From 2120f4fb5b6aa05e3a70aec925302819c7d0be72 Mon Sep 17 00:00:00 2001 From: xavier Date: Sat, 12 Jan 2013 23:56:40 +0000 Subject: [PATCH] Fixes to bola: thrower+target dismount time is equal, Core.ML is 10s, 4 sec delay from throw to hit victim, dismount info moved to playermobile rather than mount, to prevent exploit. --- Scripts/Items/Misc/Bola.cs | 139 ++++++++++++-------- Scripts/Items/Weapons/Abilities/Dismount.cs | 27 ++-- Scripts/Mobiles/Animals/Mounts/BaseMount.cs | 139 ++++---------------- Scripts/Mobiles/Animals/Mounts/Ethereals.cs | 2 +- Scripts/Mobiles/PlayerMobile.cs | 77 +++++++++++ 5 files changed, 208 insertions(+), 176 deletions(-) diff --git a/Scripts/Items/Misc/Bola.cs b/Scripts/Items/Misc/Bola.cs index dc54901fb..f1a817855 100644 --- a/Scripts/Items/Misc/Bola.cs +++ b/Scripts/Items/Misc/Bola.cs @@ -1,50 +1,53 @@ -using System; -using System.Collections; using Server; using Server.Mobiles; using Server.Network; using Server.Targeting; +using System; namespace Server.Items { public class Bola : Item { [Constructable] - public Bola() : this( 1 ) + public Bola() + : this( 1 ) { } [Constructable] - public Bola( int amount ) : base( 0x26AC ) + public Bola( int amount ) + : base( 0x26AC ) { Weight = 4.0; Stackable = true; Amount = amount; } + public static TimeSpan BolaRecoveryTime { get { return TimeSpan.FromSeconds( Core.ML ? 10 : 3 ); } } + public override void OnDoubleClick( Mobile from ) { - if ( !IsChildOf( from.Backpack ) ) + if( !IsChildOf( from.Backpack ) ) { from.SendLocalizedMessage( 1040019 ); // The bola must be in your pack to use it. } - else if ( !from.CanBeginAction( typeof( Bola ) ) ) + else if( !from.CanBeginAction( typeof( Bola ) ) ) { from.SendLocalizedMessage( 1049624 ); // You have to wait a few moments before you can use another bola! } - else if ( from.Target is BolaTarget ) + else if( from.Target is BolaTarget ) { from.SendLocalizedMessage( 1049631 ); // This bola is already being used. } - else if ( !Core.AOS && (from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null) ) + else if( !Core.AOS && ( from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null ) ) { from.SendLocalizedMessage( 1040015 ); // Your hands must be free to use this } - else if ( from.Mounted ) + else if( from.Mounted ) { from.SendLocalizedMessage( 1040016 ); // You cannot use this while riding a mount } - else if ( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) ) + else if( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) ) { from.SendLocalizedMessage( 1070902 ); // You can't use this while in an animal form! } @@ -52,14 +55,15 @@ namespace Server.Items { EtherealMount.StopMounting( from ); - if ( Core.AOS ) { + if( Core.AOS ) + { Item one = from.FindItemOnLayer( Layer.OneHanded ); Item two = from.FindItemOnLayer( Layer.TwoHanded ); - if ( one != null ) + if( one != null ) from.AddToBackpack( one ); - if ( two != null ) + if( two != null ) from.AddToBackpack( two ); } @@ -69,105 +73,126 @@ namespace Server.Items } } - private static void ReleaseBolaLock( object state ) - { - ((Mobile)state).EndAction( typeof( Bola ) ); - } - private static void FinishThrow( object state ) { - object[] states = (object[])state; + object[] states = ( object[] )state; - Mobile from = (Mobile)states[0]; - Mobile to = (Mobile)states[1]; + Mobile from = ( Mobile )states[ 0 ]; + Mobile to = ( Mobile )states[ 1 ]; - if ( Core.AOS ) + Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( ReleaseBolaLock ), from ); + + if( Core.AOS ) new Bola().MoveToWorld( to.Location, to.Map ); to.Damage( 1, from ); - if ( to is ChaosDragoon || to is ChaosDragoonElite ) + if( to is ChaosDragoon || to is ChaosDragoonElite ) + { from.SendLocalizedMessage( 1042047 ); // You fail to knock the rider from its mount. + } + else + { + if( from.InRange( to.Location, 8 ) && ( to.Map == from.Map ) && ( to.Map != Map.Internal ) ) + { + IMount mt = to.Mount; - IMount mt = to.Mount; - if ( mt != null && !( to is ChaosDragoon || to is ChaosDragoonElite ) ) - mt.Rider = null; + if( mt != null ) + { + mt.Rider = null; + } - to.SendLocalizedMessage( 1040023 ); // You have been knocked off of your mount! + from.Direction = from.GetDirectionTo( to ); + from.Animate( 11, 5, 1, true, false, 0 ); - BaseMount.SetMountPrevention( to, BlockMountType.Dazed, TimeSpan.FromSeconds( 3.0 ) ); + from.MovingEffect( to, 0x26AC, 10, 0, false, false ); - Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( ReleaseBolaLock ), from ); + from.DoHarmful( to ); + + to.SendLocalizedMessage( 1040023 ); // You have been knocked off of your mount! + + if( to is PlayerMobile ) + { + ( to as PlayerMobile ).AddMountBlock( BlockMountType.Dazed, BolaRecoveryTime ); + } + if( from is PlayerMobile ) + { + ( from as PlayerMobile ).AddMountBlock( BlockMountType.BolaRecovery, BolaRecoveryTime ); // TODO validate durations + } + } + else + { + from.SendLocalizedMessage( 1042060 ); //You cannot see that target! + } + } + } + + private static void ReleaseBolaLock( object state ) + { + ( ( Mobile )state ).EndAction( typeof( Bola ) ); } private class BolaTarget : Target { private Bola m_Bola; - public BolaTarget( Bola bola ) : base( 8, false, TargetFlags.Harmful ) + public BolaTarget( Bola bola ) + : base( 8, false, TargetFlags.Harmful ) { m_Bola = bola; } protected override void OnTarget( Mobile from, object obj ) { - if ( m_Bola.Deleted ) + if( m_Bola.Deleted ) return; - if ( obj is Mobile ) + if( obj is Mobile ) { - Mobile to = (Mobile)obj; + Mobile to = ( Mobile )obj; - if ( !m_Bola.IsChildOf( from.Backpack ) ) + if( !m_Bola.IsChildOf( from.Backpack ) ) { from.SendLocalizedMessage( 1040019 ); // The bola must be in your pack to use it. } - else if ( !Core.AOS && (from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null) ) + else if( !Core.AOS && ( from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null ) ) { from.SendLocalizedMessage( 1040015 ); // Your hands must be free to use this } - else if ( from.Mounted ) + else if( from.Mounted ) { from.SendLocalizedMessage( 1040016 ); // You cannot use this while riding a mount } - else if ( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) ) + else if( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) ) { from.SendLocalizedMessage( 1070902 ); // You can't use this while in an animal form! } - else if ( !to.Mounted ) + else if( !to.Mounted ) { from.SendLocalizedMessage( 1049628 ); // You have no reason to throw a bola at that. } - else if ( !from.CanBeHarmful( to ) ) + else if( !from.CanBeHarmful( to ) ) { } - else if ( from.BeginAction( typeof( Bola ) ) ) + else if( from.BeginAction( typeof( Bola ) ) ) { EtherealMount.StopMounting( from ); - if ( Core.AOS ) { + if( Core.AOS ) + { Item one = from.FindItemOnLayer( Layer.OneHanded ); Item two = from.FindItemOnLayer( Layer.TwoHanded ); - if ( one != null ) + if( one != null ) from.AddToBackpack( one ); - if ( two != null ) + if( two != null ) from.AddToBackpack( two ); } - from.DoHarmful( to ); - - if ( Core.AOS ) - BaseMount.SetMountPrevention( from, BlockMountType.BolaRecovery, TimeSpan.FromSeconds( 3.0 ) ); - m_Bola.Consume(); - from.Direction = from.GetDirectionTo( to ); - from.Animate( 11, 5, 1, true, false, 0 ); - from.MovingEffect( to, 0x26AC, 10, 0, false, false ); - - Timer.DelayCall( TimeSpan.FromSeconds( 0.5 ), new TimerStateCallback( FinishThrow ), new object[]{ from, to } ); + Timer.DelayCall( TimeSpan.FromSeconds( Core.ML ? 4 : .5 ), new TimerStateCallback( FinishThrow ), new object[] { from, to } ); } else { @@ -181,7 +206,8 @@ namespace Server.Items } } - public Bola( Serial serial ) : base( serial ) + public Bola( Serial serial ) + : base( serial ) { } @@ -189,7 +215,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 0 ); + writer.Write( ( int )0 ); } public override void Deserialize( GenericReader reader ) @@ -199,4 +225,5 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} + diff --git a/Scripts/Items/Weapons/Abilities/Dismount.cs b/Scripts/Items/Weapons/Abilities/Dismount.cs index e20a47d95..064677381 100644 --- a/Scripts/Items/Weapons/Abilities/Dismount.cs +++ b/Scripts/Items/Weapons/Abilities/Dismount.cs @@ -31,8 +31,7 @@ namespace Server.Items return true; } - public static readonly TimeSpan DefenderRemountDelay = TimeSpan.FromSeconds( 10.0 ); // TODO: Taken from bola script, needs to be verified - public static readonly TimeSpan AttackerRemountDelay = TimeSpan.FromSeconds( 3.0 ); + public static readonly TimeSpan RemountDelay = TimeSpan.FromSeconds( 10.0 ); public override void OnHit( Mobile attacker, Mobile defender, int damage ) { @@ -73,16 +72,26 @@ namespace Server.Items defender.PlaySound( 0x140 ); defender.FixedParticles( 0x3728, 10, 15, 9955, EffectLayer.Waist ); - mount.Rider = null; - - BaseMount.SetMountPrevention( defender, BlockMountType.Dazed, DefenderRemountDelay ); - if( Core.ML && attacker is BaseCreature && ((BaseCreature)attacker).ControlMaster != null ) + if( defender is PlayerMobile ) { - BaseMount.SetMountPrevention( ((BaseCreature)attacker).ControlMaster, BlockMountType.DismountRecovery, AttackerRemountDelay ); + ( defender as PlayerMobile ).AddMountBlock( BlockMountType.Dazed, RemountDelay ); } - else + + if( attacker is PlayerMobile ) { - BaseMount.SetMountPrevention( attacker, BlockMountType.DismountRecovery, AttackerRemountDelay ); + ( attacker as PlayerMobile ).AddMountBlock( BlockMountType.DismountRecovery, RemountDelay ); + } + + else if( Core.ML && attacker is BaseCreature ) + { + BaseCreature bc = attacker as BaseCreature; + + if( bc.ControlMaster is PlayerMobile ) + { + PlayerMobile pm = bc.ControlMaster as PlayerMobile; + + pm.AddMountBlock( BlockMountType.DismountRecovery, RemountDelay ); + } } if ( !attacker.Mounted ) diff --git a/Scripts/Mobiles/Animals/Mounts/BaseMount.cs b/Scripts/Mobiles/Animals/Mounts/BaseMount.cs index 31fc54abc..b0ab98764 100644 --- a/Scripts/Mobiles/Animals/Mounts/BaseMount.cs +++ b/Scripts/Mobiles/Animals/Mounts/BaseMount.cs @@ -32,22 +32,6 @@ namespace Server.Mobiles m_InternalItem = new MountItem( this, itemID ); } - public BaseMount( Serial serial ) : base( serial ) - { - } - - public override void Serialize( GenericWriter writer ) - { - base.Serialize( writer ); - - writer.Write( (int) 1 ); // version - - writer.Write( m_NextMountAbility ); - - writer.Write( m_Rider ); - writer.Write( m_InternalItem ); - } - [Hue, CommandProperty( AccessLevel.GameMaster )] public override int Hue { @@ -88,6 +72,23 @@ namespace Server.Mobiles base.OnDelete(); } + public BaseMount( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( ( int )1 ); // version + + writer.Write( m_NextMountAbility ); + + writer.Write( m_Rider ); + writer.Write( m_InternalItem ); + } + public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); @@ -134,7 +135,7 @@ namespace Server.Mobiles return; } - if ( !CheckMountAllowed( from, true ) ) + if ( !CheckMountAllowed( from ) ) return; if ( from.Mounted ) @@ -262,97 +263,22 @@ namespace Server.Mobiles } } - private class BlockEntry + // 1040024 You are still too dazed from being knocked off your mount to ride! + // 1062910 You cannot mount while recovering from a bola throw. + // 1070859 You cannot mount while recovering from a dismount special maneuver. + + public static bool CheckMountAllowed( Mobile mob ) { - public BlockMountType m_Type; - public DateTime m_Expiration; + bool result = true; - public bool IsExpired{ get{ return ( DateTime.Now >= m_Expiration ); } } - - public BlockEntry( BlockMountType type, DateTime expiration ) + if( ( mob is PlayerMobile ) && ( mob as PlayerMobile ).BlockReason != BlockMountType.None ) { - m_Type = type; - m_Expiration = expiration; - } - } + mob.SendLocalizedMessage( ( int )( mob as PlayerMobile ).BlockReason ); - private static Hashtable m_Table = new Hashtable(); - - public static void SetMountPrevention( Mobile mob, BlockMountType type, TimeSpan duration ) - { - if ( mob == null ) - return; - - DateTime expiration = DateTime.Now + duration; - - BlockEntry entry = m_Table[mob] as BlockEntry; - - if ( entry != null ) - { - entry.m_Type = type; - entry.m_Expiration = expiration; - } - else - { - m_Table[mob] = entry = new BlockEntry( type, expiration ); - } - } - - public static void ClearMountPrevention( Mobile mob ) - { - if ( mob != null ) - m_Table.Remove( mob ); - } - - public static BlockMountType GetMountPrevention( Mobile mob ) - { - if ( mob == null ) - return BlockMountType.None; - - BlockEntry entry = m_Table[mob] as BlockEntry; - - if ( entry == null ) - return BlockMountType.None; - - if ( entry.IsExpired ) - { - m_Table.Remove( mob ); - return BlockMountType.None; + result = false; } - return entry.m_Type; - } - - public static bool CheckMountAllowed( Mobile mob, bool message ) - { - BlockMountType type = GetMountPrevention( mob ); - - if ( type == BlockMountType.None ) - return true; - - if ( message ) - { - switch ( type ) - { - case BlockMountType.Dazed: - { - mob.SendLocalizedMessage( 1040024 ); // You are still too dazed from being knocked off your mount to ride! - break; - } - case BlockMountType.BolaRecovery: - { - mob.SendLocalizedMessage( 1062910 ); // You cannot mount while recovering from a bola throw. - break; - } - case BlockMountType.DismountRecovery: - { - mob.SendLocalizedMessage( 1070859 ); // You cannot mount while recovering from a dismount special maneuver. - break; - } - } - } - - return false; + return result; } public virtual void OnRiderDamaged( int amount, Mobile from, bool willKill ) @@ -451,12 +377,5 @@ namespace Server.Mobiles } } } +} - public enum BlockMountType - { - None = -1, - Dazed, - BolaRecovery, - DismountRecovery - } -} \ No newline at end of file diff --git a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs index 6d0bc1eaa..52d6ffdd3 100644 --- a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs @@ -133,7 +133,7 @@ namespace Server.Mobiles // CheckIsUsableBy sends the message return false; } - else if( !BaseMount.CheckMountAllowed( from, true ) ) + else if( !BaseMount.CheckMountAllowed( from ) ) { // CheckMountAllowed sends the message return false; diff --git a/Scripts/Mobiles/PlayerMobile.cs b/Scripts/Mobiles/PlayerMobile.cs index 75594b28e..da59a47e4 100644 --- a/Scripts/Mobiles/PlayerMobile.cs +++ b/Scripts/Mobiles/PlayerMobile.cs @@ -71,6 +71,15 @@ namespace Server.Mobiles Red, Black } + + public enum BlockMountType + { + None = -1, + Dazed = 1040024, + BolaRecovery = 1062910, + DismountRecovery = 1070859 + } + #endregion public partial class PlayerMobile : Mobile, IHonorTarget @@ -657,6 +666,74 @@ namespace Server.Mobiles } } + private List m_Blocks; + + public BlockMountType BlockReason { get { return ( CheckList() ) ? m_Blocks[ 0 ].type : BlockMountType.None; } } + + private class MountBlock + { + public BlockMountType type; + public Timer m_Timer; + + public MountBlock( TimeSpan duration, BlockMountType Type, List list ) + { + type = Type; + + m_Timer = Timer.DelayCall( duration, new TimerStateCallback>( RemoveBlock ), list ); + } + + private void RemoveBlock( List list ) + { + if( list != null ) + { + list.Remove( this ); + } + } + } + + public void AddMountBlock( BlockMountType type, TimeSpan duration ) + { + CheckList(); + + m_Blocks.Add( new MountBlock( duration, type, m_Blocks ) ); + + IMount mount = this.Mount; + + if( mount != null ) + { + mount.Rider = null; + } + } + + private bool CheckList() + { + if( m_Blocks == null ) + { + m_Blocks = new List(); + } + else if( m_Blocks.Count > 0 ) + { + List toRemove = new List(); + + int count = m_Blocks.Count; + + for( int i = 0; i < count; i++ ) + { + if( !m_Blocks[ i ].m_Timer.Running ) + { + toRemove.Add( m_Blocks[ i ] ); + } + } + + foreach( MountBlock block in toRemove ) + { + m_Blocks.Remove( block ); + } + } + + return m_Blocks.Count > 0; + } + public override void OnSkillInvalidated( Skill skill ) { if ( Core.AOS && skill.SkillName == SkillName.MagicResist )