using System; using Server.Mobiles; namespace Server.Items { public abstract class BaseTrap : Item { public virtual bool PassivelyTriggered{ get{ return false; } } public virtual TimeSpan PassiveTriggerDelay{ get{ return TimeSpan.Zero; } } public virtual int PassiveTriggerRange{ get{ return -1; } } public virtual TimeSpan ResetDelay{ get{ return TimeSpan.Zero; } } private DateTime m_WhenDisarmed; private DateTime m_WhenSkilled; private DateTime m_NextPassiveTrigger, m_NextActiveTrigger; public virtual void OnTrigger( Mobile from ) { if ( !TriggerCheck( from ) ) return; if ( DisarmCheck( from ) ) return; } public bool TriggerCheck( Mobile from ) { if ( !from.Alive || from is BaseCreature || m_WhenDisarmed > DateTime.Now ) return false; bool skillUp = false; if ( Utility.RandomBool() ) { if ( from != LastTriggeredBy || ( from == LastTriggeredBy && m_WhenSkilled < DateTime.Now ) ) skillUp = true; if ( BaseWeapon.CheckDodge( from, skillUp ) ) return false; } return true; } public bool DisarmCheck( Mobile from ) { if ( m_WhenDisarmed > DateTime.Now ) return true; if ( from is PlayerMobile ) { bool disarmed = false; double skill = from.Skills[SkillName.RemoveTrap].Base; if ( from.Skills[SkillName.RemoveTrap].Value > Utility.RandomMinMax(1,101) ) disarmed = true; if ( from != LastTriggeredBy || ( from == LastTriggeredBy && m_WhenSkilled < DateTime.Now ) ) { // If they cannot pass this skill check, allow them to keep gaining skill // Not only pass the kill check, but also gain skill // Otherwise, record them so they can't keep gaining over and over on the same trap if ( from.CheckSkill( SkillName.RemoveTrap, 0, 120 ) ) { if ( skill != from.Skills[SkillName.RemoveTrap].Base ) { LastTriggeredBy = from; m_WhenSkilled = (DateTime.Now).AddMinutes(30.0); } } } if ( disarmed ) { if ( this is MushroomTrap ) { from.SendMessage( "You squish the mushroom so its harmless!" ); from.PlaySound( 0x050 ); } else if ( this is FireColumnTrap && this.ItemID == 0x028F ) { from.SendMessage( "You plug the hole so no further flames will erupt!" ); from.PlaySound( 0x057 ); } else { from.SendMessage( "You disabled a trap!" ); from.PlaySound( 0x241 ); } m_WhenDisarmed = (DateTime.Now).AddMinutes((double)(Utility.RandomMinMax(30,60))); return true; } } return false; } public override bool HandlesOnMovement{ get{ return true; } } // Tell the core that we implement OnMovement public virtual int GetEffectHue() { int hue = this.Hue & 0x3FFF; if ( hue < 2 ) return 0; return hue - 1; } public bool CheckRange( Point3D loc, Point3D oldLoc, int range ) { return CheckRange( loc, range ) && !CheckRange( oldLoc, range ); } public bool CheckRange( Point3D loc, int range ) { return ( (this.Z + 8) >= loc.Z && (loc.Z + 16) > this.Z ) && Utility.InRange( GetWorldLocation(), loc, range ); } public override void OnMovement( Mobile m, Point3D oldLocation ) { if ( m_WhenDisarmed > DateTime.Now ) return; base.OnMovement( m, oldLocation ); if ( m.Location == oldLocation || m is BaseCreature ) return; if ( CheckRange( m.Location, oldLocation, 0 ) && DateTime.Now >= m_NextActiveTrigger ) { m_NextActiveTrigger = m_NextPassiveTrigger = DateTime.Now + ResetDelay; OnTrigger( m ); } else if ( PassivelyTriggered && CheckRange( m.Location, oldLocation, PassiveTriggerRange ) && DateTime.Now >= m_NextPassiveTrigger ) { m_NextPassiveTrigger = DateTime.Now + PassiveTriggerDelay; OnTrigger( m ); } } public BaseTrap( int itemID ) : base( itemID ) { Movable = false; } public Mobile LastTriggeredBy; [CommandProperty( AccessLevel.GameMaster )] public Mobile Last_TriggeredBy { get{ return LastTriggeredBy; } set{ LastTriggeredBy = value; } } [CommandProperty( AccessLevel.GameMaster )] public DateTime WhenDisarmed { get { return m_WhenDisarmed; } set { m_WhenDisarmed = value; } } [CommandProperty( AccessLevel.GameMaster )] public DateTime WhenSkilled { get { return m_WhenSkilled; } set { m_WhenSkilled = value; } } public BaseTrap( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 0 ); // version writer.Write( (Mobile)LastTriggeredBy); writer.Write( m_WhenDisarmed ); writer.Write( m_WhenSkilled ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); LastTriggeredBy = reader.ReadMobile(); m_WhenDisarmed = reader.ReadDateTime(); m_WhenSkilled = reader.ReadDateTime(); } } }