using System; using System.Collections; using Server.Network; using Server.Items; using Server.Mobiles; using Server.Targeting; namespace Server.Spells.Ninjitsu { public class KiAttack : NinjaMove { public KiAttack() { } public override int BaseMana{ get{ return 25; } } public override double RequiredSkill{ get{ return 80.0; } } public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063099 ); } } // Your Ki Attack must be complete within 2 seconds for the damage bonus! public override void OnUse( Mobile from ) { if ( !Validate( from ) ) return; KiAttackInfo info = new KiAttackInfo( from ); info.m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( EndKiAttack ), info ); m_Table[from] = info; } public override bool Validate( Mobile from ) { if ( from.Hidden && from.AllowedStealthSteps > 0 ) { from.SendLocalizedMessage( 1063127 ); // You cannot use this ability while in stealth mode. return false; } if( Core.ML ) { BaseRanged ranged = from.Weapon as BaseRanged; if( ranged != null ) { from.SendLocalizedMessage( 1075858 ); // You can only use this with melee attacks. return false; } } return base.Validate( from ); } public override double GetDamageScalar( Mobile attacker, Mobile defender ) { if ( attacker.Hidden ) return 1.0; /* * Pub40 changed pvp damage max to 55% */ return 1.0 + GetBonus(attacker) / ( (Core.ML && attacker.Player && defender.Player) ? 40 : 10 ); } public override void OnHit( Mobile attacker, Mobile defender, int damage ) { if ( !Validate( attacker ) || !CheckMana( attacker, true ) ) return; if ( GetBonus( attacker ) == 0.0 ) { attacker.SendLocalizedMessage( 1063101 ); // You were too close to your target to cause any additional damage. } else { attacker.FixedParticles( 0x37BE, 1, 5, 0x26BD, 0x0, 0x1, EffectLayer.Waist ); attacker.PlaySound( 0x510 ); attacker.SendLocalizedMessage( 1063100 ); // Your quick flight to your target causes extra damage as you strike! defender.FixedParticles( 0x37BE, 1, 5, 0x26BD, 0, 0x1, EffectLayer.Waist ); CheckGain( attacker ); } ClearCurrentMove( attacker ); } public override void OnClearMove( Mobile from ) { KiAttackInfo info = m_Table[from] as KiAttackInfo; if ( info != null ) { if ( info.m_Timer != null ) info.m_Timer.Stop(); m_Table.Remove( info.m_Mobile ); } } private static Hashtable m_Table = new Hashtable(); public static double GetBonus( Mobile from ) { KiAttackInfo info = m_Table[from] as KiAttackInfo; if ( info == null ) return 0.0; int xDelta = info.m_Location.X - from.X; int yDelta = info.m_Location.Y - from.Y; double bonus = Math.Sqrt( (xDelta * xDelta) + (yDelta * yDelta) ); if ( bonus > 20.0 ) bonus = 20.0; return bonus; } private class KiAttackInfo { public Mobile m_Mobile; public Point3D m_Location; public Timer m_Timer; public KiAttackInfo( Mobile m ) { m_Mobile = m; m_Location = m.Location; } } private static void EndKiAttack( object state ) { KiAttackInfo info = (KiAttackInfo)state; if ( info.m_Timer != null ) info.m_Timer.Stop(); ClearCurrentMove( info.m_Mobile ); info.m_Mobile.SendLocalizedMessage( 1063102 ); // You failed to complete your Ki Attack in time. m_Table.Remove( info.m_Mobile ); } } }