Hi,

I'm struggling with adding charges to a custom dye tub. The remaining uses get spent when I double-click the tub instead of when targeting a valid item.
It was the only way I managed to do it, but I'm not satisfied with the result.

C#:
using System;
using Server.Targeting;

namespace Server.Items
{
    public class SpecialGreenDyeTub : DyeTub
    {
        private int m_UsesRemaining;
        [CommandProperty(AccessLevel.GameMaster)]
        public int UsesRemaining { get { return m_UsesRemaining; } set { m_UsesRemaining = value; InvalidateProperties(); } }

        [Constructable]
        public SpecialGreenDyeTub()
        {
            Weight = 1.0;
            m_UsesRemaining = 10;
            ItemID = 0x0F00;
        }

        public SpecialGreenDyeTub(Serial serial)
            : base(serial)
        {
        }

        public override CustomHuePicker CustomHuePicker
        {
            get
            {
                return CustomHuePicker.SpecialGreen;
            }
        }
        public override int LabelNumber
        {
            get
            {
                return 1041285;
            }
        }// Special Dye Tub

        public virtual bool ShowUsesRemaining
        {
            get
            {
                return true;
            }
            set
            {
            }
        }

        public override void OnDoubleClick(Mobile from)
        {
            base.OnDoubleClick(from);

            if (UsesRemaining > 1)
            {
                --UsesRemaining;
            }
            else
            {
                if (from != null)
                    from.SendLocalizedMessage(1116800); // no uses left msg

                Delete();
            }
        }


        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);
            list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~
        }


        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
            writer.Write(m_UsesRemaining);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
            switch (version)
            {
                case 1:
                    m_UsesRemaining = reader.ReadInt();
                    break;
                case 0:
                    break;
            }
        }
    }
}

Maybe someone can take a look and help?
Thanks
 
Well, you're only getting the target because you're calling the base doubleclick.

You'll need to modify the base dyetub to detect if it's your special tub and then remove uses, or copy over the targeting code from your base and modify it.

Also remember: It's not the dye tub that runs out of juice, when dying in the real world, it's the pigments.
 
Yeah, in theory I know what to do, I am just not able to do it.
I tried copying the targeting code and modyfying it, but got nowhere.
 
You could add a bit in the base dyetub, where it's doing the targeting, and have it check itself to see if it's your special tub. Then cast it so the code knows about the uses remaining, then remove them.

Something like:

C#:
if (this is SpecialGreenDyeTub){
    SpecialGreenDyeTub tub = (SpecialGreenDyeTub)this;
    tub.UsesRemaining--;
    if (tub.UsesRemaining < 1){
        tub.Delete();
        from.SendMessage("Your Special Green Dye Tub has run out of charges!");
    }
}

Super rough, but it might get you started.

Also, this is a root edit to basedyetub, something that's probably not so smart considering it's trying to solve a problem on this little side tub. Kind of like using a jackhammer to kill an ant.
 
Hi again,
Modyfying base dyetub did not work. However, I copied the targeting code to the special dye tub in order to put it there and again... I got nowhere.

I added:

C#:
                    if (this.m_Tub.UsesRemaining <= 0)
                    {
                        from.SendLocalizedMessage(1042544); // This item is out of charges.
                        return;
                    }
                                        
                    this.m_Tub.UsesRemaining -= 1;

To the targeting code, which is:
C#:
        private class InternalTarget : Target
        {
            private readonly SpecialGreenDyeTub m_Tub;

            public InternalTarget(SpecialGreenDyeTub tub)
                : base(1, false, TargetFlags.None)
            {
                m_Tub = tub;
            }


            protected override void OnTarget(Mobile from, object targeted)
            {
                if (targeted is Item)

                {
                    Item item = (Item)targeted;

                    if (item is IDyable && m_Tub.AllowDyables)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                            from.SendLocalizedMessage(500446); // That is too far away.
                        else if (item.Parent is Mobile)
                            from.SendLocalizedMessage(500861); // Can't Dye clothing that is being worn.
                        else if (((IDyable)item).Dye(from, m_Tub))
                            from.PlaySound(0x23E);
                    }
                    else if ((FurnitureAttribute.Check(item) || (item is PotionKeg)) && m_Tub.AllowFurniture)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                        {
                            from.SendLocalizedMessage(500446); // That is too far away.
                        }
                        else
                        {
                            bool okay = (item.IsChildOf(from.Backpack));

                            if (!okay)
                            {
                                if (item.Parent == null)
                                {
                                    BaseHouse house = BaseHouse.FindHouseAt(item);

                                    if (house == null || (!house.IsLockedDown(item) && !house.IsSecure(item)))
                                        from.SendLocalizedMessage(501022); // Furniture must be locked down to paint it.
                                    else if (!house.IsCoOwner(from))
                                        from.SendLocalizedMessage(501023); // You must be the owner to use this item.
                                    else
                                        okay = true;
                                }
                                else
                                {
                                    from.SendLocalizedMessage(1048135); // The furniture must be in your backpack to be painted.
                                }
                            }

                            if (okay)
                            {
                                item.Hue = m_Tub.DyedHue;
                                from.PlaySound(0x23E);
                            }
                        }
                    }
                    else if ((item is Runebook || item is RecallRune) && m_Tub.AllowRunebooks)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                        {
                            from.SendLocalizedMessage(500446); // That is too far away.
                        }
                        else if (!item.Movable)
                        {
                            from.SendLocalizedMessage(1049776); // You cannot dye runes or runebooks that are locked down.
                        }
                        else
                        {
                            item.Hue = m_Tub.DyedHue;
                            from.PlaySound(0x23E);
                        }
                    }
                    else if (item is MonsterStatuette && m_Tub.AllowStatuettes)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                        {
                            from.SendLocalizedMessage(500446); // That is too far away.
                        }
                        else if (!item.Movable)
                        {
                            from.SendLocalizedMessage(1049779); // You cannot dye statuettes that are locked down.
                        }
                        else
                        {
                            item.Hue = m_Tub.DyedHue;
                            from.PlaySound(0x23E);
                        }
                    }
                    else if ((item is BaseArmor && (((BaseArmor)item).MaterialType == ArmorMaterialType.Leather || ((BaseArmor)item).MaterialType == ArmorMaterialType.Studded) || item is ElvenBoots || item is WoodlandBelt) && m_Tub.AllowLeather)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                        {
                            from.SendLocalizedMessage(500446); // That is too far away.
                        }
                        else if (!item.Movable)
                        {
                            from.SendLocalizedMessage(1042419); // You may not dye leather items which are locked down.
                        }
                        else if (item.Parent is Mobile)
                        {
                            from.SendLocalizedMessage(500861); // Can't Dye clothing that is being worn.
                        }
                        else
                        {
                            item.Hue = m_Tub.DyedHue;
                            from.PlaySound(0x23E);
                        }
                    }
                    else if ((item is BaseArmor && (((BaseArmor)item).MaterialType == ArmorMaterialType.Chainmail || ((BaseArmor)item).MaterialType == ArmorMaterialType.Ringmail || ((BaseArmor)item).MaterialType == ArmorMaterialType.Plate)) && m_Tub.AllowMetal)
                    {
                        if (!from.InRange(m_Tub.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                        {
                            from.SendLocalizedMessage(500446); // That is too far away.
                        }
                        else if (!item.Movable)
                        {
                            from.SendLocalizedMessage(1042419); // You may not dye leather items which are locked down.
                        }
                        else if (item.Parent is Mobile)
                        {
                            from.SendLocalizedMessage(500861); // Can't Dye clothing that is being worn.
                        }
                        else
                        {
                            item.Hue = m_Tub.DyedHue;
                            from.PlaySound(0x23E);
                        }
                    }
                    else
                    {
                        from.SendLocalizedMessage(m_Tub.FailMessage);
                    }
                }
                else
                {
                    from.SendLocalizedMessage(m_Tub.FailMessage);
                }
            }
        }

and it didn't work. The item does not lose charges when I use it. I checked an original ServUO item with charges and it's written the same way.
What am I doing wrong?

Thanks!
 
I got it to work by:

C#:
            protected override void OnTarget(Mobile from, object targeted)
            {
                if (targeted is Item)
                {
                    Item item = (Item)targeted;

                    if (this.m_Tub.UsesRemaining <= 0)
                    {
                        from.SendLocalizedMessage(1042544); // This item is out of charges.
                        m_Tub.Delete();
                        return;
                    }

                    this.m_Tub.UsesRemaining -= 1;
                    this.m_Tub.InvalidateProperties();

                    if (item is IDyable && m_Tub.AllowDyables)

I must've missed a line before or maybe I was putting it in the wrong place.
Thanks for your input, @Anon the Felon. Without your indications I'd probably still be going nowhere. :)
 
Back