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!

Deleting a mobile after a given time

GhostRiderGrey

Sorceror
I am looking for a way to delete a mobile after a given amount of time. In my searching of the forums I came across this, which uses the OnThink method.

Code:
private DateTime m_DeleteTime;
 
public override void OnThink()
{
    base.OnThink();
 
    if( m_DeleteTime >= DateTime.Now )
    {
        Delete();
        return; // we need to delete
    }
 
    // Do your heal function here.
    m_DeleteTime = DateTime.Now + TimeSpan.FromMinutes( 1 );
}

Would not the line if( m_DeleteTime >= DateTime.Now ) always be true because, until 1 minute had passed, the m_DeleteTime would be greater than the DateTime.Now?

Additionally, should the m_DeleteTime be serialized?

Thanks!
 

GhostRiderGrey

Sorceror
Okay, i have continued to try iterations of m_DeleteTime and DateTime.Now to no avail. Here is the complete mobile script as I presently have it. When one adds a RabidSquirrel to the shard, it is instantly deleted (rather than after a 2 minute delay). All my iterations have produced this result.

Code:
using System;
using Server;
using Server.Mobiles;
 
namespace Server.Mobiles
{
    [CorpseName( "a squirrel corpse" )]   
    public class RabidSquirrel : BaseCreature
    {
        private DateTime m_DeleteTime;
        private DateTime m_NextFire;
 
        [Constructable]
        public RabidSquirrel() : base( AIType.AI_Animal, FightMode.Closest, 10, 1, 0.2, 0.4 )
        {
            Name = "a rabid squirrel";
            Body = 0x116;
 
            SetStr( 44, 50 );
            SetDex( 35 );
            SetInt( 5 );
 
            SetHits( 150, 200 );
 
            SetDamage( 30, 40 );
 
            SetDamageType( ResistanceType.Physical, 100 );
 
            SetResistance( ResistanceType.Physical, 30, 34 );
            SetResistance( ResistanceType.Fire, 10, 14 );
            SetResistance( ResistanceType.Cold, 30, 35 );
            SetResistance( ResistanceType.Poison, 20, 25 );
            SetResistance( ResistanceType.Energy, 20, 25 );
 
            SetSkill( SkillName.MagicResist, 120.0 );
            SetSkill( SkillName.Tactics,120.0 );
            SetSkill( SkillName.Wrestling, 120.0 );
        }
 
        public override void OnThink()
        {
            base.OnThink();
 
            if (DateTime.Now >= m_DeleteTime)
            {
                Delete();
                return; // we need to delete
            }
 
            if ( this.Combatant != null && this.m_NextFire < DateTime.Now )
            {
                this.MovingParticles( this.Combatant, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
                AOS.Damage( this.Combatant, this, Utility.Random( 20, 30 ), 0, 100, 0, 0, 0 );
                this.m_NextFire = DateTime.Now + TimeSpan.FromSeconds( 30.0 );
            }
 
            m_DeleteTime = DateTime.Now + TimeSpan.FromMinutes( 2 );
        }
 
//Extra Pet damage code -- Ch'vayre
        public override void AlterMeleeDamageTo( Mobile to, ref int damage )
        {
            if ( to is BaseCreature )
            {
                BaseCreature creature = (BaseCreature)to;
                if( creature.Controlled )
                {
                    damage = damage * 4;
                }           
            }
           
            base.AlterMeleeDamageTo( to, ref damage );
        }
 
//End extra pet damage code
 
        public override Poison HitPoison{ get{ return Poison.Lethal ; } }
        public override bool Unprovokable{ get{ return true; } }
        public override bool Uncalmable{ get{ return true; } }
 
        public RabidSquirrel( Serial serial ) : base( serial )
        {
        }
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );           
            writer.Write( (int) 0 ); // version
            writer.WriteDeltaTime( m_DeleteTime );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );           
            int version = reader.ReadInt();
            m_DeleteTime = reader.ReadDeltaTime();
        }
    }
}

Any guidance would be appreciated.
 

GhostRiderGrey

Sorceror
Got it figured by setting m_DeleteTime outside of the OnThink area
Code:
using System;
using Server;
using Server.Mobiles;
 
namespace Server.Mobiles
{
    [CorpseName( "a squirrel corpse" )]   
    public class RabidSquirrel : BaseCreature
    {
        private DateTime m_DeleteTime = DateTime.Now + TimeSpan.FromMinutes( 1 );
        private DateTime m_NextFire;
 
        [Constructable]
        public RabidSquirrel() : base( AIType.AI_Animal, FightMode.Closest, 10, 1, 0.2, 0.4 )
        {
            Name = "a rabid squirrel";
            Body = 0x116;
 
            SetStr( 44, 50 );
            SetDex( 35 );
            SetInt( 5 );
 
            SetHits( 150, 200 );
 
            SetDamage( 30, 40 );
 
            SetDamageType( ResistanceType.Physical, 100 );
 
            SetResistance( ResistanceType.Physical, 30, 34 );
            SetResistance( ResistanceType.Fire, 10, 14 );
            SetResistance( ResistanceType.Cold, 30, 35 );
            SetResistance( ResistanceType.Poison, 20, 25 );
            SetResistance( ResistanceType.Energy, 20, 25 );
 
            SetSkill( SkillName.MagicResist, 120.0 );
            SetSkill( SkillName.Tactics,120.0 );
            SetSkill( SkillName.Wrestling, 120.0 );
        }
 
        public override void OnThink()
        {
            base.OnThink();
 
            if (DateTime.Now >= m_DeleteTime)
            {
                Delete();
                return; // we need to delete
            }
 
            if ( this.Combatant != null && this.m_NextFire < DateTime.Now )
            {
                this.MovingParticles( this.Combatant, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
                AOS.Damage( this.Combatant, this, Utility.Random( 20, 30 ), 0, 100, 0, 0, 0 );
                this.m_NextFire = DateTime.Now + TimeSpan.FromSeconds( 30.0 );
            }
        }
 
//Extra Pet damage code -- Ch'vayre
        public override void AlterMeleeDamageTo( Mobile to, ref int damage )
        {
            if ( to is BaseCreature )
            {
                BaseCreature creature = (BaseCreature)to;
                if( creature.Controlled )
                {
                    damage = damage * 4;
                }           
            }
           
            base.AlterMeleeDamageTo( to, ref damage );
        }
 
//End extra pet damage code
 
        public override Poison HitPoison{ get{ return Poison.Lethal ; } }
        public override bool Unprovokable{ get{ return true; } }
        public override bool Uncalmable{ get{ return true; } }
 
        public RabidSquirrel( Serial serial ) : base( serial )
        {
        }
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );           
            writer.Write( (int) 0 ); // version
            writer.WriteDeltaTime( m_DeleteTime );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );           
            int version = reader.ReadInt();
            m_DeleteTime = reader.ReadDeltaTime();
        }
    }
}

And am I doing the serialization of m_DeleteTime correctly?
 

daat99

Moderator
Staff member
1. You need to initialize the delete time inside the constructor and not in the definition.
2. I'm not sure how you're supposed to serialize a DateTime object.
If you took your serialization code from another file that serializes a DateTime object than it should be ok.
 

Mortis

Knight
You could try this. Source was from Sheep.cs Witch has a DateTime object.
Code:
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            writer.Write( (int) 1 );
 
            writer.WriteDeltaTime( m_DeleteTime );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
 
            int version = reader.ReadInt();
 
            switch ( version )
            {
                case 1:
                {
                    DeleteTime = reader.ReadDeltaTime();
                    break;
                }
 

Aquatic Elf

Sorceror
If you're not too concerned with the creature being deleted at an exact or specific time, then a simplier solution would be:

Just create a timer for X minutes right when the creature is spawned. To ensure the creature is still deleted if the world goes down (since timers aren't persistent), just recreate the timer on Deserialize for X minutes.

The difference is that you're ignoring how much time the timer had remaining when the world went down, and just simply recreating the timer.
 
Top