[RunUO_2.x] Need Help Fixing Crash With A Script

gametec

Diamond Donator
Feb 5, 2014
370
78
28
Shard Name
Untitled
This Is The Crash Log I Am Getting:
Server Crash Report
===================

RunUO Version 2.7, Build 0.23586
Operating System: Microsoft Windows NT 6.2.9200.0
.NET Framework: 4.0.30319.42000
Time: 7/21/2020 3:59:22 AM
Mobiles: 241
Items: 1319
Exception:
System.InvalidCastException: Unable to cast object of type 'Server.Items.Backpack' to type 'Server.Mobile'.
   at Server.Staff.Items.RobeOfEntitlement.OnRemoved(IEntity parent)
   at Server.Item.RemoveItem(Item item) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Item.cs:line 3480
   at Server.Item.MoveToWorld(Point3D location, Map map) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Item.cs:line 1346
   at Server.Item.Internalize() in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Item.cs:line 1898
   at Server.Mobile.Lift(Item item, Int32 amount, Boolean& rejected, LRReason& reject) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Mobile.cs:line 4372
   at Server.Network.PacketHandlers.LiftReq(NetState state, PacketReader pvSrc) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Network\PacketHandlers.cs:line 1007
   at Server.Network.MessagePump.HandleReceive(NetState ns) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Network\MessagePump.cs:line 260
   at Server.Network.MessagePump.Slice() in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Network\MessagePump.cs:line 127
   at Server.Core.Main(String[] args) in C:\Users\aasrs\uoAvocation\Server [Testing]\RunUO\v2.7\Server\Main.cs:line 537

Clients:
- Count: 1
+ --------: (account = ----) (mobile = 0xEA '-----')


This Is The Method Causing The Issue:
public override void OnRemoved(IEntity parent)
        {
            this.Name = "A Hooded Shroud";
            this.Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455)

            if (parent is Mobile)
            {
                ((Mobile)parent).NameMod = null;
                ((Mobile)parent).Title = null;
            }

            if (parent is Mobile && ((Mobile)parent).Kills >= 5)
            {
                ((Mobile)parent).Criminal = true;
            }

            if (parent is Mobile && ((Mobile)parent).GuildTitle != null)
            {
                ((Mobile)parent).DisplayGuildTitle = true;
            }

            base.OnRemoved(parent);
        }
Post automatically merged:

The issue is with lines 3 and 4...

I need to have these two statements happen when the robe is removed and returned to the backpack, however the server crashes when you remove the robe from the backpack. So everything works fine up until I place the robe in the backpack and then try to retrieve it with these two lines as they are above.

If I remove those lines, then everything works as intended, but my goal is to return the robe to its original color and name when you remove it and from what I can tell it can only be done in the OnRemoved method

This Is The Original Script In Its Entirety:
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Items;
using Server.Mobiles;

#region Script: Dev Notations

/// Date Last Updated: 07/19/2020
/// Script Edit(s) By: gametec
/// Server Foundation: RunUO_v2.7

/// Description:
/// A hooded robe that can allow staff to walk around icognito and appear official-like
/// All staff equipment doubles up as blank recall runes for staff to mark and save locations on

#endregion

namespace Server.Staff.Items
{
    [FlipableAttribute(0x2683, 0x2684)]
    public class RobeOfEntitlement : BaseOuterTorso
    {
        //private PlayerMobile from;

        [Constructable]
        public RobeOfEntitlement() : base(0x2683)
        {
            Name = "A Hooded Shroud";
            Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455)
            Weight = 5.0;

            LootType = LootType.Blessed;
            base.Layer = Layer.OuterTorso;                     
        }

        #region Staff Robe Special Properties

        public override void OnDoubleClick(Mobile from)
        {
            if (from != null && from.Alive && Parent != from)
            {
                from.SendMessage("You must be wearing the robe to use it!");
            }
            else
            {
                if (ItemID == 0x2683 || ItemID == 0x2684)
                {
                    ItemID = 0x1F03;
                    Name = "A Hooded Shroud";

                    from.SendMessage("You lower the hood.");
                    from.PlaySound(0x57);
        
                    from.Title = null;
                    from.NameMod = null;

                    from.RemoveItem(this);
                    from.EquipItem(this);
                }
                else if (ItemID == 0x1F03 || ItemID == 0x1F04)
                {
                    ItemID = 0x2683;
                    Name = "A Hooded Shroud";

                    from.SendMessage("You raise the hood.");
                    from.PlaySound(0x57);

                    from.RemoveItem(this);
                    from.EquipItem(this);
                }
            }

            if (from.AccessLevel != AccessLevel.Player)
            {
                this.facetCoordinates = from.Location;
                this.currentFacet = from.Map;
                return;
            }
        }

        public override bool OnEquip(Mobile from)
        {
            if (from != null && from.Alive && from.AccessLevel == AccessLevel.Counselor && from.AccessLevel != AccessLevel.GameMaster && from.AccessLevel != AccessLevel.Seer && from.AccessLevel != AccessLevel.Administrator && from.AccessLevel != AccessLevel.Developer && from.AccessLevel != AccessLevel.Owner && ItemID == 0x2683)
            {
                from.NameMod = "Counselor";
                from.Title = "[Staff Initiate]";
                from.DisplayGuildTitle = false;
        
                this.Name = "Shroud of Entitlement";
                this.Hue = 2122; // Counselor Color: Blue | (2122, 0x084A)
            }

            return base.OnEquip(from);
        }

        public override void OnRemoved(IEntity parent)
        {
            this.Name = "A Hooded Shroud";
            this.Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455) 

            if (parent is Mobile)
            {
                ((Mobile)parent).NameMod = null;
                ((Mobile)parent).Title = null;
            }

            if (parent is Mobile && ((Mobile)parent).Kills >= 5)
            {
                ((Mobile)parent).Criminal = true;
            }

            if (parent is Mobile && ((Mobile)parent).GuildTitle != null)
            {
                ((Mobile)parent).DisplayGuildTitle = true;
            }

            base.OnRemoved(parent);
        }

        #endregion

            #region Staff Item Can Mark Locations

        public Point3D facetCoordinates;

        [CommandProperty(AccessLevel.GameMaster)]
        public Point3D HomeLocation
        {
            get { return facetCoordinates; }
            set { facetCoordinates = value; }
        }

        public Map currentFacet;

        [CommandProperty(AccessLevel.GameMaster)]
        public Map HomeMap
        {
            get { return currentFacet; }
            set { currentFacet = value; }
        }

        private class SetHomeEntry : ContextMenuEntry
        {
            private RobeOfEntitlement m_Item;
            private Mobile m_Mobile;

            public SetHomeEntry(Mobile from, Item item) : base(2055) // uses "Mark" entry
            {
                m_Item = (RobeOfEntitlement)item;
                m_Mobile = from;
            }

            public override void OnClick()
            {
                m_Item.HomeLocation = m_Mobile.Location;
                m_Item.HomeMap = m_Mobile.Map;
                m_Mobile.SendMessage("The home location on your robe has been set to your current position.");
            }
        }

        private class GoHomeEntry : ContextMenuEntry
        {
            private RobeOfEntitlement m_Item;
            private Mobile m_Mobile;

            public GoHomeEntry(Mobile from, Item item) : base(5134) // uses "Goto Loc" entry
            {
                m_Item = (RobeOfEntitlement)item;
                m_Mobile = from;
            }

            public override void OnClick()
            {
                m_Mobile.Location = m_Item.HomeLocation;

                if (m_Item.HomeMap != null)
                    m_Mobile.Map = m_Item.HomeMap;
            }
        }

        public static void GetContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list)
        {
            list.Add(new SetHomeEntry(from, item));
            list.Add(new GoHomeEntry(from, item));
        }

        public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
        {
            base.GetContextMenuEntries(from, list);
            RobeOfEntitlement.GetContextMenuEntries(from, this, list);
        }

        #endregion

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

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

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

            writer.Write(facetCoordinates);
            writer.Write(currentFacet);
        }

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

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
                        facetCoordinates = reader.ReadPoint3D();
                        currentFacet = reader.ReadMap();

                        goto case 0;
                    }                   
                case 0:
                    {
                        
                        break;
                    }
            }
        }
    }
}
 
Last edited:

PyrO

Paladin
Jan 27, 2015
1,293
154
63
public override void OnRemoved(IEntity parent)
{
this.Name = "A Hooded Shroud";
this.Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455)

if (parent is Mobile)
{
((Mobile)parent).NameMod = null;
((Mobile)parent).Title = null;
}

if (parent is Mobile && ((Mobile)parent).Kills >= 5)
{
((Mobile)parent).Criminal = true;
}

if (parent is Mobile && ((Mobile)parent).GuildTitle != null)
{
((Mobile)parent).DisplayGuildTitle = true;
}

base.OnRemoved(parent);
}
thise code and also the full code do not have anything that would cause the issue.
There is no cast there, well only after an check if parent is Mobile.

Since the crash happens on a cast, did you maybe remove some code there?

also the equal code just for fun:
C#:
        public override void OnRemoved(IEntity parent)
        {
            Name = "A Hooded Shroud";
            Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455)

            if (parent is Mobile)
            {
                Mobile p = (Mobile)parent;
                p.NameMod = null;
                p.Title = null;
                if(p.Kills >= 5)
                {
                        p.Criminal = true;
                }
                p.DisplayGuildTitle = p.GuildTitle != null;
            }

            base.OnRemoved(parent);
        }
 

gametec

Diamond Donator
Feb 5, 2014
370
78
28
Shard Name
Untitled
I think I accidently fixed it... lol

Now I am unsure why the crashed happened :/ I made this script a long time ago and it was never thoroughly tested. So now that I am looking at it again I am testing it. Anyway thanks for the help, do you mind if I credit your name in the script?

Because I used a variation of your code to clean things up and make it nicer to look at:

C#:
if (parent is Mobile)
            {
                Mobile from = (Mobile)parent;

                from.NameMod = null;
                from.Title = null;
                from.DisplayGuildTitle = from.GuildTitle != null;

                if (from.Kills >= 5)
                {
                    from.Criminal = true;
                }
                else
                {
                    from.Criminal = false;
                }       
            }

            this.Name = "A Hooded Shroud";
            this.Hue = 1109; // Default Color: Shadow Dancer Black | (1109, 0x0455)

            base.OnRemoved(parent);
 

PyrO

Paladin
Jan 27, 2015
1,293
154
63
you dont really need to credit me for anything there :D

also from.Criminal = true; and the false as well can be put in one line as well.

from.Criminal = from.Kills >= 5;