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!

Stackable items losing properties when unstacked

siran

Sorceror
I created coins using the itemID for Gold. Then I added the CraftResource property so coins can be made from any type of ingot. Everything works to create gold, silver, copper, dullcopper, iron coins and so on. However, if I have a stack of say, valorite coins and decide to split the stack, the part of the stack I moved will still have valorite as the resource, but the original stack will revert to iron. The hue won't change, but the resource will and so the resource description as well.

Is this controlled by the client? I can't seem to find the code that is causing this.
 

siran

Sorceror
post the script you made for that.
Code:
using System;
using Server.Targeting;
using Server.Engines.Craft;
 
namespace Server.Items
{
    public class Coin : Item, ICommodity
    {
        private CraftResource m_Resource;
        [CommandProperty (AccessLevel.GameMaster)]
        public CraftResource Resource
        {
            get {return m_Resource;}
            set {m_Resource = value;}
        }
        int ICommodity.DescriptionNumber {get {return LabelNumber;}}
        bool ICommodity.IsDeedable {get {return true;}}
        [Constructable]
        public Coin () : this (1)
        {
        }
        [Constructable]
        public Coin (int amount) : this (amount, CraftResource.MetalCopper)
        {
        }
        [Constructable]
        public Coin (CraftResource resource) : this (1, resource)
        {
        }
        [Constructable]
        public Coin (int amount, CraftResource resource) : base (0xef0)
        {
            Stackable = true;
            Amount = amount;
            Weight = 0.02 * CraftResources.GetWeightModifier (resource);
            SalvageValue = CraftResources.GetValueModifier (resource);
            Hue = CraftResources.GetHue (resource);
            m_Resource = resource;
            Alignment = Alignment.Earth;
        }
        #region Methods
        public override void OnDoubleClick (Mobile from)
        {
            if (!Movable)
                return;
            if (from.InRange (this.GetWorldLocation (), 2))
            {
                from.SendMessage ("Select the forge on which to smelt the coins.");
                from.Target = new InternalTarget (this);
            }
            else
            {
                from.SendMessage ("That is too far away.");
            }
        }
       
        private class InternalTarget : Target
        {
            private Coin m_Coin;
            public InternalTarget (Coin coin) : base (2, false, TargetFlags.None)
            {
                m_Coin = coin;
            }
            private bool IsForge (object obj)
            {
                if ( obj.GetType ().IsDefined (typeof (ForgeAttribute ), false))
                    return true;
                int itemID = 0;
                if (obj is Item)
                    itemID = ((Item)obj).ItemID;
                else if (obj is StaticTarget)
                    itemID = ((StaticTarget)obj).ItemID & 0x3FFF;
                return (itemID == 4017 || (itemID >= 6522 && itemID <= 6569));
            }
            protected override void OnTarget (Mobile from, object targeted)
            {
                if (m_Coin.Deleted)
                    return;
                if (!from.InRange (m_Coin.GetWorldLocation (), 2))
                {
                    from.SendMessage ("They are too far away");
                    return;
                }
                double smeltingSkill = from.Skills[SkillName.Smelting].Base;
                if (IsForge (targeted))
                {
                    double difficulty = CraftResources.GetSmeltingDifficulty (m_Coin.Resource) - 25.0;
                    int consume_per_make = Math.Max (500, 600 - (int)smeltingSkill);
                    int make_qty = 1;
                    double minSkill = difficulty - 25.0;
                    double maxSkill = difficulty + 25.0;
                    if (difficulty > 25.0 && difficulty > smeltingSkill)
                    {
                        from.SendMessage ("You have no idea how to smelt these coins!");
                        return;
                    }
                    if (m_Coin.Amount < consume_per_make)
                    {
                        from.SendMessage ("There are not enough coins to make an ingot.");
                        return;
                    }
                    int consume_qty = consume_per_make;
                    while (consume_qty + consume_per_make < m_Coin.Amount && make_qty < (int)smeltingSkill / 5)
                    {
                        consume_qty += consume_per_make;
                        make_qty += 1;
                    }
                    if (from.CheckTargetSkill (SkillName.Smelting, targeted, minSkill, maxSkill)) // Success
                    {
                        Ingot newIngot = new Ingot ();
                        newIngot.Amount = make_qty;
                        newIngot.Resource = m_Coin.Resource;
                        newIngot.Hue = CraftResources.GetHue (newIngot.Resource);
                        newIngot.Weight = 10.0 * CraftResources.GetWeightModifier (newIngot.Resource);
                        newIngot.SalvageValue = 15.0 * CraftResources.GetValueModifier (newIngot.Resource);
                        m_Coin.Consume (consume_qty);
                        if (m_Coin.Amount <= 0)
                            m_Coin.Delete ();
                        newIngot.MoveToWorld (from.Location, from.Map);
                        from.PlaySound (0x57);
                        from.SendMessage ("You re-smelt the coins into ingots.");
                    }
                    else // Failure
                    {
                        int waste = Utility.RandomMinMax (1, 10);
                       
                        if (m_Coin.Amount > waste)
                        {
                            m_Coin.Amount -= waste;
                            from.SendMessage ("You failed to re-smelt the coins and ruined some.");
                        }
                        else
                        {
                            m_Coin.Delete ();
                            from.SendMessage ("You failed to re-smelt the coins and ruined them.");
                        }
                    }
                }
            }
        }
        public override void AddNameProperty (ObjectPropertyList list)
        {
            list.Add ("{0} Coins", Amount);
        }
        public override void GetProperties (ObjectPropertyList list)
        {
            base.GetProperties (list);
            list.Add (CraftResources.GetName (m_Resource));
        }
        #endregion
        public Coin (Serial serial) : base (serial)
        {
        }
        public override void Serialize (GenericWriter writer)
        {
            base.Serialize (writer);
            writer.Write ((int)0); // version
            writer.Write ((int)m_Resource);
        }
        public override void Deserialize (GenericReader reader)
        {
            base.Deserialize (reader);
            int version = reader.ReadInt ();
            m_Resource = (CraftResource)reader.ReadInt ();
        }
    }
}
 

siran

Sorceror
The code works fine, no problems compiling or using ingame. What I did not do is make a separate class for every iteration of coin (each resource), the way ingots and other items using craft resources are handled. I can go back and do that, but I'm hoping it's not necessary.
 

pooka01

Sorceror
It is possibly due to the client, as such we can double click on blank scrolls that are just static items.
What could be done is a on drag lift, or such, aka overriding the base drag/drop methods to keep the same ressource after drop.
I'll see if i can come up with some codes.

I doubt that making a separate file for each ressource would be useful, keep what you have so far.
 

pooka01

Sorceror
Code:
  public override bool OnDragDropInto( Mobile from, Item item )
  {
  Console.WriteLine("OnDragDropInto");
  return base.OnDragDropInto();
  }
  public override bool OnDroppedInto( Mobile from, Container target, Point3D p )
  {
  Console.WriteLine("OnDroppedToWorld");
  return base.OnDroppedInto();
  }
  public override bool OnDroppedOnto( Mobile from, Item target )
  {
  Console.WriteLine("OnDroppedOnto");
  return base.OnDroppedOnto();
  }
  public override bool OnDroppedToMobile( Mobile from, Mobile target )
  {
  Console.WriteLine("OnDroppedToMobile");
  return base.OnDroppedToMobile();
  }
  public override bool OnDroppedToWorld( Mobile from, Point3D p )
  {
  Console.WriteLine("OnDroppedToWorld");
  return base.OnDroppedToWorld();
  }

Could test out with this, i'm just unsure of how to detect the amount change.
Would atleast be able to find on which method it scraps it on.
 

Soteric

Knight
You should override OnAfterDuped method and assign the properties you need. Check Scripts\Engines\Plants\Seed.cs for example.
 
Top