RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

How to make Large BODs give all the Smalls to fill it

flitwick

Sorceror
How to make Large BODs give all the Smalls to fill it

Different take on BODs

I usually play on small shards where trading BODs is very hard, if not impossible. It always seemed odd for an NPC to give you an order that you would likely never be able to fill without creating dozens of accounts and hundreds of characters. This is the answer! Any time you get a Large BOD from the smith, you automatically get all the small BODs to fill it. This has NOT been tested in a production environment. If you are going to use this on a production shard, you will probably want to ensure you don't have any automated BOD grabber accounts on your shard. This is designed for the players who like crafting and filling BODs enough to do it manually. This is just the smithy files, but the others should be pretty easy using this as a base.

This code does 2 major things:
1: It scales Large BOD quality based on skill.
2: dumps all the small bods in the player's backpack alongside the large bod when it's accepted.

In order to keep it as simple as possible, I used the small bod creation as a guide. That means your large quality should be equal to your small quality at any given skill. I did add in a little boost for skill levels over 70.1. At 120 skill, all bods are 20/exceptional.

Here are the mods:

First, the additional code needed in LargeSmithBod.cs
Code:
public static LargeSmithBOD CreateRandomFor( Mobile m )
		{
			LargeBulkEntry[] entries;
			bool useMaterials = true;
			LargeBOD m_Owner = null;
			
			int rand = Utility.Random( 8 );

			switch ( rand )
			{
				default:
				case  0: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeRing ); 	 break;
				case  1: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargePlate );	 break;
				case  2: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeChain );	 break;
				case  3: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeAxes );	 break;
				case  4: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeFencing );	 break;
				case  5: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeMaces );	 break;
				case  6: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargePolearms );	 break;
				case  7: entries = LargeBulkEntry.ConvertEntries( m_Owner, LargeBulkEntry.LargeSwords );	 break;
			}
			
			if( rand > 2 && rand < 8 )
				useMaterials = false;

			
			double theirSkill = m.Skills[SkillName.Blacksmith].Base;
			int amountMax;
			if ( theirSkill >= 120.0 )
				amountMax = Utility.RandomList( 20, 20, 20, 20 );
			else if ( theirSkill >= 100.1 )
				amountMax = Utility.RandomList( 15, 20, 20, 20 );
			else if ( theirSkill >= 70.1 )
				amountMax = Utility.RandomList( 10, 15, 20, 20 );
			else if ( theirSkill >= 50.1 )
				amountMax = Utility.RandomList( 10, 15, 15, 20 );
			else
				amountMax = Utility.RandomList( 10, 10, 15, 20 );



			BulkMaterialType material = BulkMaterialType.None;

			if ( useMaterials && theirSkill >= 70.1 )
			{
				for ( int i = 0; i < 20; ++i )
				{
					BulkMaterialType check = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
					double skillReq = 0.0;

					switch ( check )
					{
						case BulkMaterialType.DullCopper: skillReq = 65.0; break;
						case BulkMaterialType.ShadowIron: skillReq = 70.0; break;
						case BulkMaterialType.Copper: skillReq = 75.0; break;
						case BulkMaterialType.Bronze: skillReq = 80.0; break;
						case BulkMaterialType.Gold: skillReq = 85.0; break;
						case BulkMaterialType.Agapite: skillReq = 90.0; break;
						case BulkMaterialType.Verite: skillReq = 95.0; break;
						case BulkMaterialType.Valorite: skillReq = 100.0; break;
						case BulkMaterialType.Spined: skillReq = 65.0; break;
						case BulkMaterialType.Horned: skillReq = 80.0; break;
						case BulkMaterialType.Barbed: skillReq = 99.0; break;
					}
					if ( theirSkill >= skillReq )
					{
						material = check;
						break;
					}
				}
			}

			double excChance = 0.0;

			if ( theirSkill >= 70.1 )
				excChance = (theirSkill + 80.0) / 200.0;
			bool reqExceptional = ( excChance > Utility.RandomDouble() );

			return new LargeSmithBOD( amountMax, reqExceptional, material, entries );
			
		}

Second, the code needed in SmallSmithBOD.cs

Code:
[Constructable]
		public SmallSmithBOD( BulkMaterialType material, int amountMax, bool reqExceptional, LargeBulkEntry entry )
		{

			
			
				int hue = 0x44E;

				this.Hue = hue;
				this.AmountMax = amountMax;
				this.Type = entry.Details.Type;
				this.Number = entry.Details.Number;
				this.Graphic = entry.Details.Graphic;
				this.RequireExceptional = reqExceptional;
				this.Material = material;

		}

next, the code change (additional code in RED) in LargeBODAcceptGump.cs: NOTE! you'll notice that it's possible to get the large, but not have enough room in your pack for the smalls.
Code:
if ( m_From.PlaceInBackpack( m_Deed ) )

   				[COLOR="Red"]{
					for (int i = 0; i < m_Deed.Entries.Length; ++i )
						{
							m_From.PlaceInBackpack ( new SmallSmithBOD( m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i] ) );

						}[/COLOR]					
					m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
				[COLOR="Red"]}[/COLOR]

Finally, the code change (in RED) needed in Blacksmith.cs and Weaponsmith.cs

Code:
if ( theirSkill >= 70.1 && ((theirSkill) / 120.0) > Utility.RandomDouble() )
					[COLOR="Red"]return LargeSmithBOD.CreateRandomFor( from );[/COLOR]			
				return SmallSmithBOD.CreateRandomFor( from );

And finally, a little bonus: This little sub, added to LargeSmithBOD.cs lets admins create large BODs of any type they like in-game with the command "[add largesmithbod metal amount exceptional number" where number is the integer that matches the switch list below.

i.e.
[add largesmithbod valorite 20 exceptional 1

will add a large plate valorite 20 exceptional bod. Much easier than creating a random one and editing the props.

Code:
[Constructable]
		public LargeSmithBOD ( BulkMaterialType material, int amountMax, bool reqExceptional, int bodtype )
		{
			LargeBulkEntry[] entries;
			switch ( bodtype )
			{
				default:
				case  0: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeRing ); 	 break;
				case  1: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePlate );	 break;
				case  2: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeChain );	 break;
				case  3: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeAxes );	 break;
				case  4: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeFencing );	 break;
				case  5: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeMaces );	 break;
				case  6: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePolearms );	 break;
				case  7: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeSwords );	 break;
			}
			
			
			int hue = 0x44E;
			this.Hue = hue;
			this.AmountMax = amountMax;
			this.Entries = entries;
			this.RequireExceptional = reqExceptional;
			this.Material = material;
		}

This is my very first code submission, and I welcome any questions, comments, or advice!


Thanks,
Flitwick
 

Gaea26

Sorceror
Has this been tested in a production environment? If so, for what version of Runuo? Will this mod also work for tailor/taming BOD's? (obviously with changes to what is made and resources)
My players really want a better way to get BOD's since we are small and waiting 3 hours to get something that cant hope to fill ...well...sucks:)
 

flitwick

Sorceror
I've been using it on my small shard for quite some time. We only have about 10 players, so it's not as 'extensively' tested as if it was on a full scale shard, but it works perfectly for us. I'm currently running this on 2.1.
 

Alyssa Dark

Sorceror
This looks like something our players would like as well, have received complaints about never being able to complete a Large and getting crappy ones, lol, for their skill level.

We're using [owltrbod as well as the crafting npcs for bods, has anyone successfully used this mod along with that command? Or would this command need it's own changes to match the mods for it to work in the same manner? Or just removed completely?

Thank you
 
As to the question will it work for tailoring, not as is. When implemented you will run into the issue of how to sort weither its a tailoring bod or smith bod in LargeBODAcceptGump around line 84. I would love any ideas to resolve this issue.

Code:
public override void OnResponse( NetState sender, RelayInfo info )
        {
            if ( info.ButtonID == 1 ) // Ok
            {
                if ( m_From.PlaceInBackpack( m_Deed ) )
                {
                    for (int i = 0; i < m_Deed.Entries.Length; ++i )
                    {
                        m_From.PlaceInBackpack ( new SmallSmithBOD( m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i] ) );
                    }

                    m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
                }
                else
                {
                    m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
                    m_Deed.Delete();
                }
            }
            else
            {
                m_Deed.Delete();
            }
        }
 
Here is my solution to the sorting
Code:
public override void OnResponse( NetState sender, RelayInfo info )
        {
            if ( info.ButtonID == 1 ) // Ok
            {
                if ( m_From.PlaceInBackpack( m_Deed ) )
                {
                    for (int i = 0; i < m_Deed.Entries.Length; ++i )
                    {
                        if (m_DeedType == BODType.Smith)
                            m_From.PlaceInBackpack ( new SmallSmithBOD( m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i] ) );

                        else
                            m_From.PlaceInBackpack(new SmallTailorBOD(m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i]));
                    }

                    m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
                }
                else
                {
                    m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
                    m_Deed.Delete();
                }
            }
            else
            {
                m_Deed.Delete();
            }
        }

The bug I have now is finding where to set the hue for tailoring. I thought it would be pretty simple, for some reason it eludes me.
 
Ok I am lost, here is the code for both tailor and smith large auto fill, it works but I can not get the tailor smallBODs to hue correctly, could someone point out where I have missed something obvious?

LargeBODAcceptGump.cs
Code:
public override void OnResponse( NetState sender, RelayInfo info )
        {
            if ( info.ButtonID == 1 ) // Ok
            {
                if ( m_From.PlaceInBackpack( m_Deed ) )
                {
                    for (int i = 0; i < m_Deed.Entries.Length; ++i )
                    {
                        if (m_DeedType == BODType.Tailor)
                            m_From.PlaceInBackpack(new SmallTailorBOD(m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i]));

                        else if (m_DeedType == BODType.Smith)
                            m_From.PlaceInBackpack(new SmallSmithBOD(m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i]));
                    }

                    m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
                }
                else
                {
                    m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
                    m_Deed.Delete();
                }
            }
            else
            {
                m_Deed.Delete();
            }
        }

SmallTailorBOD.cs
Code:
[Constructable]
        public SmallTailorBOD(BulkMaterialType material, int amountMax, bool reqExceptional, LargeBulkEntry entry)
        {
            int hue = 0x483;

            this.Hue = hue;
            this.AmountMax = amountMax;
            this.Type = entry.Details.Type;
            this.Number = entry.Details.Number;
            this.Graphic = entry.Details.Graphic;
            this.RequireExceptional = reqExceptional;
            this.Material = material;

        }

LargeTailorBOD.cs
Code:
public static LargeTailorBOD CreateRandomFor(Mobile m)
        {
            LargeBulkEntry[] entries;
            bool useMaterials = true;
            LargeBOD m_Owner = null;

            int rand = Utility.Random(14);

            switch (rand)
            {
                default:
                case 0: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Farmer); break;
                case 1: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.FemaleLeatherSet); break;
                case 2: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.FisherGirl); break;
                case 3: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Gypsy); break;
                case 4: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.HatSet); break;
                case 5: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Jester); break;
                case 6: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Lady); break;
                case 7: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.MaleLeatherSet); break;
                case 8: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Pirate); break;
                case 9: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.ShoeSet); break;
                case 10: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.StuddedSet); break;
                case 11: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.TownCrier); break;
                case 12: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.Wizard); break;
                case 13: entries = LargeBulkEntry.ConvertEntries(m_Owner, LargeBulkEntry.BoneSet); break;
            }

            if (rand > 3 && rand < 11)
                useMaterials = false;
 
            double theirSkill = m.Skills[SkillName.Tailoring].Base;
            int amountMax;
            if (theirSkill >= 120.0)
                amountMax = Utility.RandomList(20, 20, 20, 20);
            else if (theirSkill >= 100.1)
                amountMax = Utility.RandomList(15, 20, 20, 20);
            else if (theirSkill >= 70.1)
                amountMax = Utility.RandomList(10, 15, 20, 20);
            else if (theirSkill >= 50.1)
                amountMax = Utility.RandomList(10, 15, 15, 20);
            else
                amountMax = Utility.RandomList(10, 10, 15, 20);
  
            BulkMaterialType material = BulkMaterialType.None;

            if (useMaterials && theirSkill >= 70.1)
            {
                for (int i = 0; i < 20; ++i)
                {
                    BulkMaterialType check = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
                    double skillReq = 0.0;

                    switch (check)
                    {
                        case BulkMaterialType.Spined: skillReq = 65.0; break;
                        case BulkMaterialType.Horned: skillReq = 80.0; break;
                        case BulkMaterialType.Barbed: skillReq = 99.0; break;
                    }
                    if (theirSkill >= skillReq)
                    {
                        material = check;
                        break;
                    }
                }
            }

            double excChance = 0.0;

            if (theirSkill >= 70.1)
                excChance = (theirSkill + 80.0) / 200.0;
            bool reqExceptional = (excChance > Utility.RandomDouble());

            return new LargeTailorBOD(amountMax, reqExceptional, material, entries);

        }

Someone please point out where I made an obvious mistake.... TailorSmallBODs do not get hued propperly when they are issued with the large, if they are issued on their own they hue fine?????
 

Montmatre

Sorceror
Thanks for this excellent script modification, was really what I was after :). You have probably solved the hue colour issue, but if you haven't I found a rather strange way of fixing it.
In LargeBODAcceptGump.cs
Code:
        public override void OnResponse( NetState sender, RelayInfo info )
        {
            if ( info.ButtonID == 1 ) // Ok
            {
               
                if ( m_From.PlaceInBackpack( m_Deed ) )
                {
 
                    if (m_Deed.Hue == 0x44E)
                    {
                        for (int i = 0; i < m_Deed.Entries.Length; ++i)
                        {
                            m_From.PlaceInBackpack(new SmallSmithBOD(m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i]));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < m_Deed.Entries.Length; ++i)
                        {
                            m_From.PlaceInBackpack(new SmallTailorBOD(m_Deed.Material, m_Deed.AmountMax, m_Deed.RequireExceptional, m_Deed.Entries[i]));
                        }
 
                    }
 
 
                    m_From.SendLocalizedMessage(1045152); // The bulk order deed has been placed in your backpack.
                }
            }
            else
            {
                m_Deed.Delete();
            }
        }
A strange way but it sorted it out for me :)
 

Miracle99

Squire
Would it be possible to get someone that has this working on their shard to upload the files. Right now playing on a shard with just myself and one friend. This would be a great addition.
 

SilverDragon47

Sorceror
Has this been tested in a production environment? If so, for what version of Runuo? Will this mod also work for tailor/taming BOD's? (obviously with changes to what is made and resources)
My players really want a better way to get BOD's since we are small and waiting 3 hours to get something that cant hope to fill ...well...sucks:)
It states clearly in the initial post "This has NOT been tested in a production environment."
Maybe you should test it and let us know how well it works...
 

SilverDragon47

Sorceror
Great idea.
I played on OSI's Sonoma shard for many years and was unable to fill most large BODs for exactly this reason.
The way the core is set up, it is near impossible to obtain all the small BODs required to fill the large ones.
Looking forward to using this when the bugs are worked out.
Ambitious first script. Looking forward to seeing more from you.
Some day I hope to be able to figure out the trick myself.
 
Top