// I've moved or turned public void OnMoved( Point3D oldLocation ) { m_LastAnimAction = DateTime.Now; Mobile mob = AttachedTo as Mobile; if ( m_RotationTimer != null ) { if ( oldLocation == mob.Location ) return; // we can't possibly stop this awesomeness else // foul play! { m_RotationTimer.Stop(); // stop that shit m_RotationTimer = null; } } CancelQueuedAction(); if ( m_DefensiveFormationTimer != null ) { m_DefensiveFormationTimer.Stop(); m_DefensiveFormationTimer = null; } if ( m_Charging ) { if ( mob.Hidden ) mob.RevealingAction(); if ( ((int)mob.Direction) <= 7 ) // walking in charge cancels it { mob.SendMessage( "You stopped running and thus fumbled your charge." ); CancelCharge(); } } // fumble my attack and defense if ( m_AttackTimer != null ) { m_AttackTimer.Stop(); m_AttackTimer = null; } if ( m_DefenseTimer != null ) { m_DefenseTimer.Stop(); m_DefenseTimer = null; } if ( m_DefensiveFormation ) { if ( mob.Location != oldLocation ) // not just turning CancelDefensiveFormation( false ); // moved while in defensive formation else // this needs a tiny delay, otherwise the animation is sent together with the 'movement' one Timer.DelayCall( TimeSpan.FromMilliseconds( 50 ), new TimerStateCallback( AnimationRefreshCallback ), this ); } if ( m_Aiming ) { if ( mob.Location != oldLocation ) // not just turning CancelAim( false ); // moved while aiming else // this needs a tiny delay, otherwise the animation is sent together with the 'movement' one Timer.DelayCall( TimeSpan.FromMilliseconds( 50 ), new TimerStateCallback( AnimationRefreshCallback ), this ); } // check if i'm showing my back to any of my combatants, if so, check if they're swinging anything, and make it connect List<Mobile> opponents = new List<Mobile>( m_Aggressors ); // necessary due to concurrency foreach ( Mobile opponent in opponents ) { GetCSA( opponent ).CheckForFreeAttack( mob, oldLocation ); GetCSA( opponent ).OnAfterOpponentMoved( mob ); } BaseWeapon weapon = mob.Weapon as BaseWeapon; int myRange = weapon.MaxRange; if ( AttachedTo is BaseCreature && ((BaseCreature)AttachedTo).RangeFight > myRange ) myRange = ((BaseCreature)AttachedTo).RangeFight; if ( m_Charging && m_Opponent != null ) { if ( m_Opponent.InRange( mob, myRange ) ) // we are in range, but charge might not be valid { if ( ValidateCharge( mob, m_Opponent ) ) { //mob.SendMessage( "Charge Okay." ); bool weWin = true; // we're going to strike them now, but let's see if they are, too if ( ValidateCharge( m_Opponent, mob ) ) { // seems they have a valid charge BaseWeapon opponentWeapon = m_Opponent.Weapon as BaseWeapon; int theirRange = opponentWeapon.MaxRange; if ( m_Opponent is BaseCreature && ((BaseCreature)m_Opponent).RangeFight > theirRange ) theirRange = ((BaseCreature)m_Opponent).RangeFight; if ( m_Opponent.InRange( mob, theirRange ) ) { // they can charge-strike us as well! lets make it somewhat randomized double myRidingSkill = mob.Skills[SkillName.Riding].Value + ((IKhaerosMobile)mob).RideBonus; double theirRidingSkill = m_Opponent.Skills[SkillName.Riding].Value + ((IKhaerosMobile)m_Opponent).RideBonus; if ( !mob.Mounted ) myRidingSkill = 0; if ( !m_Opponent.Mounted ) theirRidingSkill = 0; double myWeaponSkill = mob.Skills[weapon.Skill].Base; double theirWeaponSkill = m_Opponent.Skills[opponentWeapon.Skill].Base; double myTacticsSkill = mob.Skills[SkillName.Tactics].Base; double theirTacticsSkill = m_Opponent.Skills[SkillName.Tactics].Base; double ourSum = myRidingSkill + myWeaponSkill + myTacticsSkill; double theirSum = theirRidingSkill + theirWeaponSkill + theirTacticsSkill; double chance = ( ourSum / theirSum ) / 2; // fifty-fifty at same skills and backgrounds if ( Utility.RandomDouble() < chance ) weWin = true; else weWin = false; } } if ( weWin ) { double chargeBonus = CalculateChargeBonus( m_Opponent.Location ); m_ChargeEndTime = DateTime.Now; SetChargeCooldown(mob); ChargeIconRefreshCallback( AttachedTo ); Timer.DelayCall( GetChargeNoRunDelay(), new TimerStateCallback( ChargeIconRefreshCallback ), AttachedTo ); AttackType chargetype = ChargeAttackType( weapon ); m_AttackTimer = new AttackTimer( mob, chargetype, TimeSpan.Zero ); FinishAttack( chargeBonus ); CancelCharge(); } else // they win :( { CombatSystemAttachment opCSA = GetCSA( m_Opponent ); double chargeBonus = opCSA.CalculateChargeBonus( mob.Location ); opCSA.ChargeEndTime = DateTime.Now; SetChargeCooldown(m_Opponent); ChargeIconRefreshCallback( m_Opponent ); Timer.DelayCall( GetChargeNoRunDelay(), new TimerStateCallback( ChargeIconRefreshCallback ), m_Opponent ); AttackType chargetype = ChargeAttackType( m_Opponent.Weapon ); opCSA.AttackTimer = new AttackTimer( m_Opponent, chargetype, TimeSpan.Zero ); opCSA.FinishAttack( chargeBonus ); opCSA.CancelCharge(); } } else // this is a showstopper { if ( m_ErrorMessage != "" ) mob.SendMessage( m_ErrorMessage ); CancelCharge(); } } else if ( m_Opponent.InRange( mob, myRange+2 ) ) { GetCSA( m_Opponent ).ChargeAlert( ChargeAttackType( weapon ) ); // alerts auto combat } } else if ( m_BullRushing ) { IKhaerosMobile km = mob as IKhaerosMobile; if ( (mob.Direction&Direction.Mask) != m_BullRushDirection ) { m_BullRushing = false; mob.SendMessage( "Bull Rush interrupted due to not rushing in a straight line." ); } else { List<Mobile> list = new List<Mobile>(); int moveXOffset = 0; int moveYOffset = 0; switch ( mob.Direction&Direction.Mask ) { case Direction.South: case Direction.North: { moveXOffset = 1; break; } case Direction.West: case Direction.East: { moveYOffset = 1; break; } case Direction.Up: case Direction.Down: { moveXOffset = 1; moveYOffset = -1; break; } case Direction.Left: case Direction.Right: { moveXOffset = 1; moveYOffset = 1; break; } } foreach ( Mobile candidate in mob.GetMobilesInRange( myRange ) ) { if ( candidate != null && mob != candidate ) if ( IsOnCollisionCourse( candidate ) ) list.Add( candidate ); } foreach ( Mobile opponent in list ) { bool randomDir = Utility.RandomBool(); if ( !BaseAI.AreAllies( mob, opponent ) ) { // only attacks non-allies mob.Combatant = opponent; m_AttackTimer = new AttackTimer( mob, AttackType.Swing, TimeSpan.Zero ); FinishAttack(); } Point3D newLoc = new Point3D(); newLoc.X = opponent.Location.X + ( randomDir ? -1 : 1 ) * moveXOffset; newLoc.Y = opponent.Location.Y + ( randomDir ? -1 : 1 ) * moveYOffset; newLoc.Z = opponent.Location.Z; if ( opponent.Map.CanSpawnMobile( newLoc ) ) opponent.SetLocation( newLoc, true ); int additionalPush = 0; if ( km.Feats.GetFeatLevel(FeatList.BullRush) >= 3 ) additionalPush = 2; else if ( km.Feats.GetFeatLevel(FeatList.BullRush) == 2 ) additionalPush = 1; // move x more times if ( additionalPush > 0 ) GetCSA( opponent ).GotBullRushed( ( randomDir ? -1 : 1 ) * moveXOffset, ( randomDir ? -1 : 1 ) * moveYOffset, 2 ); } } m_BullRushSteps++; if ( m_BullRushSteps > km.Feats.GetFeatLevel(FeatList.BullRush) * 2 ) CancelSequences(); } UpdateACBrainExternal(); }
public void CancelDefensiveFormation( bool resetAnim ) { if ( m_DefensiveFormationTimer != null ) { m_DefensiveFormationTimer.Stop(); m_DefensiveFormationTimer = null; } if ( m_DefensiveFormation ) { m_DefensiveFormation = false; StopAnimating( resetAnim ); } }
public bool EnterDefensiveFormation() { Mobile defender = AttachedTo as Mobile; if(m_DefensiveFormationTimer != null) m_DefensiveFormationTimer.Stop(); m_DefensiveFormationTimer = null; m_DefensiveFormation = true; StartAnimating( 19, 3, 1, false, false, 255 ); return true; }
public bool BeginDefensiveFormation() { Mobile defender = AttachedTo as Mobile; if ( !CanBeginDefensiveFormation() ) return false; defender.RevealingAction(); StopAllActions( false ); m_DefensiveFormation = false; m_DefensiveFormationTimer = new DefensiveFormationTimer( defender, TimeSpan.FromSeconds( 1.0 ) ); m_DefensiveFormationTimer.Start(); Animate( 19, 1, 1, true, false, 2 ); return true; }