// 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;
        }