Hi,

We have a add feature in this file but we can't remove a item from the despawn list after it have been spawned without making a own modifications inside this file. This is important if we spawn a item in a camp that we wish let the player keep it after the camp have despawn.

Existing Add function looks like this today:
Code:
public virtual void AddItem( Item item, int xOffset, int yOffset, int zOffset )
        {
            m_Items.Add( item );

            int zavg = Map.GetAverageZ(X + xOffset, Y + yOffset);
            item.MoveToWorld( new Point3D( X + xOffset, Y + yOffset, zavg + zOffset ), Map );
        }

And I would suggest to add a new "RemoveItem" in ServUO.
Code:
public virtual void RemoveItem( Item item )
        {
            m_Items.Remove( item ) ;
        }

-Grim
 
In item.cs it will be delete, I need to remove it from BaseCamp Item list.

Then a camp despawn it uses this function and kill all items listed in m_Items.

Code:
		public override void OnAfterDelete()
		{
			base.OnAfterDelete();

			for ( int i = 0; i < m_Items.Count; ++i )
				m_Items[i].Delete();

			for ( int i = 0; i < m_Mobiles.Count; ++i )
			{
				BaseCreature bc = (BaseCreature)m_Mobiles[i];

				if ( bc.IsPrisoner == false )
					m_Mobiles[i].Delete();
				else if ( m_Mobiles[i].CantWalk == true )
					m_Mobiles[i].Delete();
			}

			m_Items.Clear();
			m_Mobiles.Clear();
		}
 
Last edited:
What I'm asking for is to add this 4 lines into BaseCamp.cs

Code:
public virtual void RemoveItem( Item item )
        {
            m_Items.Remove( item ) ;
        }
 
Item already has RemoveItem(Item item). You can name it RemoveComponent or something, instead. I'm not sure what the purpose of removing the item is, unless you have some custom stuff going on. In That case, there is no need to modify a file in ServUO repo that doesn't match EA functionality.
 
This is the issue I got and I can work around it by duplicate camp
spawn code if needed but I thought it would be a core issue.

Or are there another solution to keep a item after a despawn that I have missed?

To view this content we will need your consent to set third party cookies.
For more detailed information, see our cookies page.

-Grim
 
Im assuming you are inheriting your class from BaseCamp and wanting that function added to BaseCamp but it seems to me it would be easier to override the OnAfterDelete in your custom class and then remove the item from the list prior to the items being counted and deleted.

It should be trivial to find the item by type and remove from the list.
 
RemoveComponent from camp would be fine sins DeleteItem already exists.
Code:
public virtual void RemoveComponent( Item item )
{
	m_Items.Remove( item ) ;
}
[doublepost=1506126133][/doublepost]
Im assuming you are inheriting your class from BaseCamp and wanting that function added to BaseCamp but it seems to me it would be easier to override the OnAfterDelete in your custom class and then remove the item from the list prior to the items being counted and deleted.

It should be trivial to find the item by type and remove from the list.

How did you planned to reach a private variable inside a inherited class?
[doublepost=1506126240][/doublepost]This is my code sins we been moved to script support, :)

Code:
using System;
using Server.Items;
using Server.Mobiles;

namespace Server.Multis
{
    public class TestCamp : BaseCamp
    {
        private int kSerial;
        private DateTime kLastMoved;

        [Constructable]
        public TestCamp() : base(0x10EE) // dummy garbage at center
        {
        }

        public override void AddComponents()
        {
            Visible = false;
            DecayDelay = TimeSpan.FromSeconds(20.0);

            AddItem(new Static(963), 3, 0, 0);
            AddItem(new Static(960), 4, 0, 0);
            AddItem(new Static(965), 5, 0, 0);
            AddItem(new Static(957), 6, 0, 0);
            AddItem(new Static(964), 0, 1, 0);
            AddItem(new Static(3108), 4, 1, 0);
            AddItem(new Static(961), 0, 2, 0);
            AddItem(new Static(964), 7, 2, 0);
            AddItem(new Static(961), 0, 3, 0);
            AddItem(new Static(4012), 3, 3, 0);
            AddItem(new Static(2541), 3, 3, 0);
            AddItem(new Static(961), 7, 3, 0);
            AddItem(new Static(961), 0, 4, 0);
            AddItem(new Static(964), 0, 4, 10);
            AddItem(new Static(966), 7, 4, 0);
            AddItem(new Static(994), 0, 5, 0);
            AddItem(new Static(3093), 1, 5, 0);
            AddItem(new Static(961), 0, 6, 0);
            AddItem(new Static(966), 0, 6, 10);
            AddItem(new Static(3094), 2, 6, 0);
            AddItem(new Static(966), 0, 7, 0);
            AddItem(new Static(957), 2, 7, 0);
        }

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

        public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
        {
            if (item.ItemID == 2541)
            {
                item.Movable = true;
                kSerial = item.Serial;
                kLastMoved = item.LastMoved;
            }
            else if (item != null)
                item.Movable = false;

            base.AddItem(item, xOffset, yOffset, zOffset);
        }

        public override void OnAfterDelete()
        {
            if (kLastMoved != World.FindItem(kSerial).LastMoved)
                RemoveItemFromCamp(World.FindItem(kSerial));

            base.OnAfterDelete();
        }

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

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }
}
 
Last edited:
How did you planned to reach a private variable inside a inherited class?

I can't decide if that is meant to be a smart-ass comment, so I'm going to give you the benefit of the doubt and ignore it.

Of course you wouldn't access a private variable inside an inherited class. You would create your own variable for the instance of your class and not call the base class.

This code works fine for what you want and doesn't require any modification to the base class. It requires more code of course, but still uses some functionality from the base class while accomplishing what you want.

Code:
using System;
using System.Collections.Generic;
using CustomsFramework;
using Server.Items;
using Server.Mobiles;

namespace Server.Multis
{
   public class TestCamp : BaseCamp
   {
     private DateTime kLastMoved;
     private List<Item> m_Items;
     private List<Mobile> m_Mobiles;

     [Constructable]
     public TestCamp() : base(0x10EE) // dummy garbage at center
     {
       m_Items = new List<Item>();
     }

     public override void AddComponents()
     {
       Visible = false;
       DecayDelay = TimeSpan.FromSeconds(20.0);

       AddItem(new Static(963), 3, 0, 0);
       AddItem(new Static(960), 4, 0, 0);
       AddItem(new Static(965), 5, 0, 0);
       AddItem(new Static(957), 6, 0, 0);
       AddItem(new Static(964), 0, 1, 0);
       AddItem(new Static(3108), 4, 1, 0);
       AddItem(new Static(961), 0, 2, 0);
       AddItem(new Static(964), 7, 2, 0);
       AddItem(new Static(961), 0, 3, 0);
       AddItem(new Static(4012), 3, 3, 0);
       AddItem(new Static(2541), 3, 3, 0);
       AddItem(new Static(961), 7, 3, 0);
       AddItem(new Static(961), 0, 4, 0);
       AddItem(new Static(964), 0, 4, 10);
       AddItem(new Static(966), 7, 4, 0);
       AddItem(new Static(994), 0, 5, 0);
       AddItem(new Static(3093), 1, 5, 0);
       AddItem(new Static(961), 0, 6, 0);
       AddItem(new Static(966), 0, 6, 10);
       AddItem(new Static(3094), 2, 6, 0);
       AddItem(new Static(966), 0, 7, 0);
       AddItem(new Static(957), 2, 7, 0);
     }

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

     public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
     {
       if (item.ItemID == 2541)
       {
         item.Movable = true;
         kLastMoved = item.LastMoved;
       }
       else if (item != null)
         item.Movable = false;

       m_Items.Add(item);

       int zavg = Map.GetAverageZ(X + xOffset, Y + yOffset);
       item.MoveToWorld(new Point3D(X + xOffset, Y + yOffset, zavg + zOffset), Map);

     }

     public override void OnAfterDelete()
     {
       foreach (BaseModule module in World.GetModules(this))
       {
         module.Delete();
       }

       Timer.DelayCall(EventSink.InvokeItemDeleted, new ItemDeletedEventArgs(this));

       for (int i = 0; i < m_Items.Count; ++i)
       {
         if (m_Items[i].ItemID == 2541 && kLastMoved != m_Items[i].LastMoved)
         {
           m_Items.RemoveAt(i);
           i--;
         }
         else
           m_Items[i].Delete();
       }

       m_Items.Clear();
     }

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

       writer.Write((int)0); // version
     }

     public override void Deserialize(GenericReader reader)
     {
       base.Deserialize(reader);
       int version = reader.ReadInt();
     }
   }
}
 
It was not meant to be a smart-ass comment. I never thought of override base class and move the code one step down.
I tried to hard to keep everything in the base class, I didn't know how to access the information in another way.

Thank you for a solution that works, you saved me a lot of time here.
 
No worries, sometimes its hard to tell someone's attitude on the forums!

Anyway, I happen to agree that a virtual RemoveItem function would be an excellent thing to add to the base class. I can certainly see how it would be useful.
 
Back