public void StopAllActions( bool resetAnim )
        {
            if ( m_RotationTimer != null )
            {
                m_RotationTimer.Stop();
                m_RotationTimer = null;
            }
            CancelAim( resetAnim );
            CancelCharge();
            CancelDefensiveFormation( resetAnim );
            if ( m_DefenseTimer != null )
            {
                if ( resetAnim )
                    m_DefenseTimer.Interrupt();
                else
                    m_DefenseTimer.Stop();
                m_DefenseTimer = null;
            }

            if ( m_AttackTimer != null )
            {
                if ( resetAnim )
                    m_AttackTimer.Interrupt();
                else
                    m_AttackTimer.Stop();
                m_AttackTimer = null;
            }

            if ( resetAnim && m_AnimationTimer != null )
                m_AnimationTimer.RefreshAnimation();
        }
        // 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 FinishAttack( double damageBonus, bool cannotParry, bool spinning, bool opportunity )
        {
            bool flashy = false;
            AttackType type;
            bool AOE = AttachedTo != null && AttachedTo is BaseCreature && ( (BaseCreature)AttachedTo ).AOEAttack;

            if ( !spinning && !AOE )
            {
                if ( m_AttackTimer == null )
                    return;	// we weren't swinging anything
                else
                {
                    type = m_AttackTimer.Type;
                    flashy = m_AttackTimer.Flashy;
                    m_AttackTimer.Stop();
                }
            }
            else
                type = AttackType.Swing;

            m_LastMeleeAttackType = type;

            Mobile attacker = AttachedTo as Mobile;
            Mobile opponent = m_Opponent;
            bool throwing = (m_OffHand || type == AttackType.Throw);

            BaseWeapon weapon = attacker.Weapon as BaseWeapon;

            if( attacker != null && attacker is IKhaerosMobile )
            {
                SkillName skill = SkillName.Tactics;

                if( throwing )
                    skill = SkillName.Throwing;

                ( (IKhaerosMobile)attacker ).CombatManeuver.CanUseManeuverCheck( attacker, skill );
            }

            double percentageDamage = 0.0;
            double bestDamage = 0.0;

            percentageDamage = GetDirectionDamage( type );
            if ( type == AttackType.ShieldBash )
                percentageDamage = 1.0;
            bestDamage = GetBestDirectionDamage();

            if ( !m_Charging && !spinning && !m_DefensiveFormation && !opportunity )
                SpellHelper.Turn( attacker, m_Opponent );
            if ( ( spinning || m_Charging || m_DefensiveFormation ) && ((IKhaerosMobile)attacker).OffensiveFeat != FeatList.None )
                ((IKhaerosMobile)attacker).DisableManeuver(); // no maneuvers while we're doing these things

            List<Mobile> defenders = new List<Mobile>();
            if ( spinning )
            {
                damageBonus *= ((double)((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.CircularAttack))*0.5;
                int myRange = ((BaseWeapon)attacker.Weapon).MaxRange;
                if ( attacker is BaseCreature && ((BaseCreature)attacker).RangeFight > myRange )
                    myRange = ((BaseCreature)attacker).RangeFight;
                foreach( Mobile m in attacker.GetMobilesInRange( myRange ) )
                {
                    if ( !((IKhaerosMobile)attacker).IsAllyOf( m ) )
                        defenders.Add( m );
                }
            }
            else
            {
                defenders.Add( opponent );
                /*if ( opportunity )
                {
                    double damageIgnoreFactor = 0.0;
                    if ( opponent is PlayerMobile ) // reduce damage a bit
                    {
                        PlayerMobile opponentPM = opponent as PlayerMobile;
                        damageIgnoreFactor += opponentPM.HeavyPieces * 0.0625;
                        damageIgnoreFactor += opponentPM.MediumPieces * 0.03125;
                    }
                    damageBonus *= (1.0 - damageIgnoreFactor);
                }*/
            }

            foreach ( Mobile defender in defenders )
            {
                double attackerDCI, defenderDCI, attackerHCI, defenderHCI;
                attackerDCI = defenderDCI = attackerHCI = defenderHCI = 0.0;
                bool defenderDCIRoll, attackerDCIRoll, attackerHCIRoll, defenderHCIRoll;
                defenderDCIRoll = attackerDCIRoll = attackerHCIRoll = defenderHCIRoll = false;
                CombatSystemAttachment csa = null;
                AttackType newAttack = AttackType.Invalid;
                if ( defender != null )
                {
                    csa = GetCSA( defender );
                    attackerDCI = GetDCI(); // this is used "offensively", but only for unarmed fighting
                    defenderHCI = csa.GetHCI(); // this is used "defensively" but only against unarmed fighting
                    if ( defenderHCI < 0 && attackerDCI < 0 ) // both are negative, we won't favor either of them
                    {
                        double temp = defenderHCI - attackerDCI;
                        attackerDCI -= defenderHCI;
                        defenderHCI = temp;
                    }
                    else if ( defenderHCI < 0 ) // attackerDCI is >=0
                        attackerDCI -= defenderHCI; // it's negative, so our opponent is adding their negative HCI to our DCI
                    else // attackerDCI < 0 and defenderHCI >= 0
                        defenderHCI -= attackerDCI;

                    attackerDCIRoll = ( Utility.RandomDouble() < attackerDCI );
                    defenderHCIRoll = ( Utility.RandomDouble() < defenderHCI );

                    if ( attackerDCIRoll && defenderHCIRoll )
                        attackerDCIRoll = defenderHCIRoll = false; // cancel them out

                    defenderDCI = csa.GetDCI();
                    attackerHCI = GetHCI();
                    if ( attackerHCI < 0 && defenderDCI < 0 ) // both are negative, we won't favor either of them
                    {
                        double temp = attackerHCI - defenderDCI;
                        defenderDCI -= attackerHCI;
                        attackerHCI = temp;
                    }
                    else if ( attackerHCI < 0 ) // defenderDCI is >=0
                        defenderDCI -= attackerHCI; // it's negative, so we're adding our negative HCI to our opponent's DCI
                    else // defenderDCI < 0 and attackerHCI >= 0
                        attackerHCI -= defenderDCI;
                    defenderDCIRoll = ( Utility.RandomDouble() < defenderDCI );
                    attackerHCIRoll = ( Utility.RandomDouble() < attackerHCI );
                    if ( defenderDCIRoll && attackerHCIRoll ) // cancel them out
                        defenderDCIRoll = attackerHCIRoll = false;

                    if ( m_Charging || spinning || type == AttackType.ShieldBash || m_DefensiveFormation || type == AttackType.Throw )
                    {
                        attackerHCIRoll = false; // there's only one possible direction when doing these attacks
                        attackerDCIRoll = false;
                    }
                    if ( type == AttackType.ShieldBash || type == AttackType.Throw )
                    {
                        defenderDCIRoll = false; // this cannot be parried anyway
                        defenderHCIRoll = false; // they can't change direction to avoid interruption
                    }
                    if ( csa.Charging || csa.RotationTimer != null || csa.DefensiveFormation ||
                    (csa.AttackTimer != null && (csa.AttackTimer.Type == AttackType.Throw || csa.AttackTimer.Type == AttackType.ShieldBash) ) )
                    {
                        defenderHCIRoll = false; // they cannot change direction
                        attackerDCIRoll = false; // we can't interrupt that, no matter the direction
                    }

                    newAttack = AttackType.Invalid;

                    if ( attackerHCIRoll )
                    {
                        foreach ( AttackType atktype in GetPossibleAttacks() )
                        {
                            if ( atktype == type )
                                continue; // skip same attack
                            else if ( newAttack == AttackType.Invalid )
                                newAttack = atktype;
                            else if ( GetDirectionDamage( atktype ) > GetDirectionDamage( newAttack ) )
                                newAttack = atktype;
                        }

                        if ( newAttack == AttackType.Invalid )
                            attackerHCIRoll = false;
                    }
                }
                int myRange = ((BaseWeapon)attacker.Weapon).MaxRange;
                if ( attacker is BaseCreature && ((BaseCreature)attacker).RangeFight > myRange )
                    myRange = ((BaseCreature)attacker).RangeFight;
                if ( defender != null && attacker.InRange( defender.Location, myRange ) && defender.Alive && type != AttackType.Throw &&
                    attacker.CanSee( defender ) && attacker.InLOS( defender ))
                { // melee
                    bool parried = false;
                    if ( csa.DefenseTimer != null && !cannotParry ) // defending
                    {
                        DefenseType deftype = csa.DefenseTimer.Type;
                        BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
                        BaseWeapon twohander = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseWeapon;
                        BaseWeapon onehander = defender.FindItemOnLayer( Layer.OneHanded ) as BaseWeapon;
                        bool weaponCannotBlock = weapon.CannotBlock;

                        if( attacker is PlayerMobile && ( (PlayerMobile)attacker ).Claws != null )
                            weaponCannotBlock = false;

                        BaseWeapon opponentWeapon = defender.Weapon as BaseWeapon;
                        bool opponentWeaponCannotBlock = opponentWeapon.CannotBlock;

                        if( defender is PlayerMobile && ( (PlayerMobile)defender ).Claws != null )
                            opponentWeaponCannotBlock = false;

                        if ( ( !opponentWeaponCannotBlock || defender.Body.Type != BodyType.Human ) || weaponCannotBlock || shield != null )
                        {
                            if ( ( type == AttackType.Swing && deftype == DefenseType.ParrySwing ) ||	// this handles parries
                            ( type == AttackType.Thrust && deftype == DefenseType.ParryThrust ) ||
                            ( type == AttackType.Overhead && deftype == DefenseType.ParryOverhead ) || defenderDCIRoll )
                            {
                                if ( attackerHCIRoll )
                                {
                                    type = newAttack;
                                    percentageDamage = GetDirectionDamage( type );
                                }
                                else
                                {
                                    if ( shield != null )
                                    {
                                        int dmg = (int)weapon.GetScaledDamage( attacker, defender, damageBonus );
                                        shield.OnHit( weapon, dmg );
                                        PlayBlockSound( attacker, defender, attacker.Weapon as BaseWeapon, shield );
                                    }
                                    else if ( twohander != null )
                                    {
                                        twohander.DegradeWeapon(); // this should degrade more.
                                        PlayBlockSound( attacker, defender, attacker.Weapon as BaseWeapon, twohander );
                                    }
                                    else
                                    {
                                        if ( onehander != null )  // could be fists
                                            onehander.DegradeWeapon(); // this should degrade more.

                                        PlayBlockSound( attacker, defender, attacker.Weapon as BaseWeapon, defender.Weapon as BaseWeapon );
                                    }

                                    parried = true;
                                    if ( !spinning )
                                    {
                                        weapon.InitializeManeuver( attacker, null, false );
                                        weapon.EndManeuver( attacker );
                                    }
                                    csa.DefenseTimer.Parries++;
                                    PlayerMobile pmatk = attacker as PlayerMobile;
                                    int blut = weapon.AosElementDamages.Blunt;
                                    if( attacker.Weapon is Fists && attacker is IKhaerosMobile && ((IKhaerosMobile)attacker).TechniqueLevel > 0 )
                                    {
                                        int slax = 0;
                                        int pirc = 0;
                                        blut = 100;
                                        if( ((IKhaerosMobile)attacker).Technique == "slashing" )
                                            slax = ((IKhaerosMobile)attacker).TechniqueLevel;
                                        else if( ((IKhaerosMobile)attacker).Technique == "piercing" )
                                            pirc = ((IKhaerosMobile)attacker).TechniqueLevel;

                                        blut -= ((IKhaerosMobile)attacker).TechniqueLevel;

                                        if( attacker is PlayerMobile && ( (PlayerMobile)attacker ).Claws != null )
                                            blut = 0;
                                    }

                                    if ( Utility.RandomDouble() < (((double)(blut))/200.0) )
                                        weapon.OnSplash( attacker, defender, damageBonus*percentageDamage ); // 20% dmg done in OnHit
                                    if ( pmatk != null && pmatk.HasSpecializedWeaponSkill() )
                                    {
                                        CombatSystemAttachment.FightingStyleOnParry( attacker );
                                        /*PlayerMobile pmdef = defender as PlayerMobile;
                                        if ( pmdef != null && pmdef.HasSpecializedWeaponSkill() )
                                        {
                                            CombatSystemAttachment.FightingStyleOnHit( defender );
                                        }*/
                                    }
                                    PlayerMobile pmdef = defender as PlayerMobile;
                                    if ( pmdef != null && pmdef.HasSpecializedWeaponSkill() )
                                    {
                                        // This is a positive bonus for the defender, but it's not a hit, it's a parry (confusing :\)
                                        CombatSystemAttachment.FightingStyleOnHit( defender );
                                    }

                                    if ( ((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.Buildup) > 0 )
                                        CombatSystemAttachment.BuildupOnParry( attacker );
                                    if ( !spinning )
                                    {
                                        TimeSpan extraPenalty = TimeSpan.Zero;
                                        IKhaerosMobile km = defender as IKhaerosMobile;

                                        if ( km != null )
                                        {
                                            BaseWeapon greatweapon = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseWeapon;
                                            if( greatweapon != null && !(greatweapon is BaseRanged) )
                                            {
                                                if ( km.Feats.GetFeatLevel(FeatList.GreatweaponFighting) == 1 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.125 );
                                                else if ( km.Feats.GetFeatLevel(FeatList.GreatweaponFighting) == 2 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.25 );
                                                else if ( km.Feats.GetFeatLevel(FeatList.GreatweaponFighting) == 3 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.5 );
                                            }

                                            if ( shield != null )
                                            {
                                                if ( km.Feats.GetFeatLevel(FeatList.ShieldMastery) == 1 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.125 );
                                                else if ( km.Feats.GetFeatLevel(FeatList.ShieldMastery) == 2 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.25 );
                                                else if ( km.Feats.GetFeatLevel(FeatList.ShieldMastery) == 3 )
                                                    extraPenalty += TimeSpan.FromSeconds( 0.5 );
                                            }
                                        }
                                        if (opportunity)
                                            m_NextAttackAction += extraPenalty;
                                        else
                                            m_NextAttackAction = DateTime.Now + ComputeNextSwingTime() + extraPenalty; // extra penalty since we were parried
                                    }
                                    if ( m_Charging ) // we're charging and the guy parried, this is the mounted momentum feat
                                    {
                                        if ( ((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.MountedMomentum) > 0 && !defender.Mounted )
                                        {
                                            double distance = CalculateChargeDistance( defender.Location ); // this was csa.CalcCh...? Why?
                                            if ( distance - (19-(((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.MountedMomentum)*3)) >= 0 )
                                            { // sufficient distance for feat to activate
                                                if( !csa.PerformingSequence )
                                                    csa.DoTrip( 1 ); // 2 seconds
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if ( !parried )
                    {
                        if( ((IKhaerosMobile)defender).CanDodge &&  ( !defender.Mounted || Utility.RandomMinMax(1,100) < BaseWeapon.GetRacialMountAbility(defender, typeof(ForestStrider)) ) && !csa.PerformingSequence )
                        {
                            if( ((IKhaerosMobile)defender).Dodged() )
                            {
                                parried = true;
                                if ( !spinning )
                                {
                                    weapon.InitializeManeuver( attacker, null, false );
                                    weapon.EndManeuver( attacker );
                                    ((IKhaerosMobile)attacker).DisableManeuver();
                                    if ( !opportunity )
                                    {
                                        if ( type == AttackType.ShieldBash )
                                            m_NextAttackAction = DateTime.Now + TimeSpan.FromSeconds( 1.0 );
                                        else
                                            m_NextAttackAction = DateTime.Now + ComputeNextSwingTime();
                                    }
                                }
                                /*if ( csa.RotationTimer == null ) // no more delay for dodging
                                {
                                    //csa.NextAction = DateTime.Now + TimeSpan.FromSeconds( 0.5 );
                                    csa.CombatInterrupt( false );
                                }*/ // Dodge no longer interrupts

                                attacker.PlaySound( 1307 );
                                defender.Say( "*dodges*" );

                                /*if ( csa.RotationTimer == null )
                                {
                                    switch ( (int)type )
                                    {
                                        case (int)AttackType.Swing:
                                        {
                                            if ( defender.Body.Type == BodyType.Human )
                                                csa.Animate( 21, 1, 1, false, false, 4 );
                                            break;
                                        }

                                        case (int)AttackType.Thrust:
                                        {
                                            if ( defender.Body.Type == BodyType.Human )
                                                csa.Animate( 30, 7, 1, true, false, 0 );
                                            break;
                                        }

                                        case (int)AttackType.Overhead:
                                        {
                                            goto case (int)AttackType.Thrust; // same anim
                                        }
                                    }
                                    csa.UpdateACBrainExternal();
                                }*/
                            }
                        }
                        if ( !parried )
                        {
                            bool noInterruption = defender is BaseCreature && ( (BaseCreature)defender ).CantBeInterrupted;
                            bool cantInterrupt = attacker is BaseCreature && ( (BaseCreature)attacker ).CantInterrupt;
                            bool success = true;
                            if ( m_Charging || m_DefensiveFormation )
                            {
                                double skill = (attacker.Skills[weapon.Skill].Base)/100.0;
                                if ( Utility.RandomDouble() > skill )
                                    success = false;
                            }
                            if ( success ) // this can only miss when charging with below 100.0 skill
                            {
                                if ( type == AttackType.ShieldBash )
                                    attacker.PlaySound( 0x3AC );
                                else
                                    PlayHitSound( attacker, defender );

                                if ( weapon is Fists && !defender.Mounted && csa.AttackTimer != null )
                                {
                                    if ( csa.AttackTimer.Type == type || attackerDCIRoll || csa.AttackTimer.Type == AttackType.Throw )
                                    { // throw always gets interrupted
                                        // this is also an interrupt, as it is an external animation
                                        if ( attackerDCIRoll ) // this and the defenderHCIRoll cannot happen both, we made sure of that
                                        {
                                            type = csa.AttackTimer.Type;
                                            percentageDamage = GetDirectionDamage( type );
                                        }
                                        bool changedDirection = false;
                                        if ( defenderHCIRoll ) // they might change direction
                                        {
                                            AttackType newType = AttackType.Invalid;
                                            foreach ( AttackType atktype in csa.GetPossibleAttacks() )
                                            {
                                                if ( atktype == csa.AttackTimer.Type )
                                                    continue; // skip same attack
                                                else if ( newType == AttackType.Invalid )
                                                    newType = atktype;
                                                else if ( csa.GetDirectionDamage( atktype ) > csa.GetDirectionDamage( newType ) )
                                                    newType = atktype;
                                            }

                                            if ( newType != AttackType.Invalid )
                                            {
                                                csa.AttackTimer.Type = newType;
                                                changedDirection = true;
                                            }
                                        }
                                        if ( !csa.PerformingSequence && csa.RotationTimer == null && !changedDirection )
                                        {
                                            if ( !opportunity && !noInterruption && !cantInterrupt ) // opportunity attacks do not interrupt
                                            {
                                                weapon.PlayHurtAnimation( defender );
                                                if ( defender.Mounted ) // there's no hurt animation for it
                                                    ResetAnimation( defender );
                                                csa.CombatInterrupt( true );
                                            }
                                            if ( ((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.Disarm) > 0 && attacker is PlayerMobile )
                                            {
                                                if ( ((PlayerMobile)attacker).CanUseMartialPower )
                                                { // Disarm class will check for fists, not movable, etc.. we don't have to
                                                    if ( Utility.RandomDouble() <= ((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.Disarm)*0.01 )
                                                        Server.Misc.Disarm.Effect( attacker, defender );
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    if ( !csa.PerformingSequence && csa.RotationTimer == null )
                                    {
                                        if( !opportunity && !noInterruption && !cantInterrupt )
                                        { // AoO does not interrupt
                                            weapon.PlayHurtAnimation( defender );
                                            if ( defender.Mounted ) // there's no hurt animation for it
                                                ResetAnimation( defender );
                                            csa.CombatInterrupt( true );
                                        }
                                    }
                                }

                                if ( csa.CruiseControl && csa.ACBrain != null && csa.ACBrain.Enabled )
                                    csa.ACBrain.RegisterFrequency( type, defender );
                                weapon.OnBeforeSwing( attacker, defender );
                                weapon.OnSwing( attacker, defender, damageBonus*percentageDamage, false );

                                PlayerMobile pmatk = attacker as PlayerMobile;
                                if ( type != AttackType.ShieldBash )
                                {
                                    if ( pmatk != null )
                                    {
                                        if ( pmatk.HasSpecializedWeaponSkill() )
                                            CombatSystemAttachment.FightingStyleOnHit( attacker );
                                    }

                                    if ( attacker.Weapon is Fists && ((IKhaerosMobile)attacker).CanUseMartialStance )
                                    {
                                        if ( ((IKhaerosMobile)attacker).Feats.GetFeatLevel(FeatList.Buildup) > 0 )
                                            CombatSystemAttachment.BuildupOnHit( attacker );
                                    }
                                }
                            }
                            else
                                attacker.SendMessage( "Your charge attack misses!" );

                            if ( !spinning )
                            {
                                if ( !opportunity )
                                {
                                    if ( type == AttackType.ShieldBash )
                                        m_NextAttackAction = DateTime.Now + TimeSpan.FromSeconds( 1.0 );
                                    else
                                        m_NextAttackAction = DateTime.Now + ComputeNextSwingTime();
                                }
                            }
                        }
                    }

                    if( attacker is BaseCreature )
                    {
                        bool melee = !( attacker.Weapon is BaseRanged ) && type != AttackType.Throw;
                        ( (BaseCreature)attacker ).OnGaveAttack( melee, parried, defender );
                    }

                    if( defender is BaseCreature )
                    {
                        bool melee = !( attacker.Weapon is BaseRanged ) && type != AttackType.Throw;
                        ( (BaseCreature)defender ).OnReceivedAttack( melee, parried, attacker );
                    }
                }
                else if ( type == AttackType.Throw && defender != null && defender.Alive ) // throw attacks, this can't be spinning so who cares
                {
                    if( weapon is AzhuranBoomerang && !m_OffHand ) // this isn't really "thrown" mechanically
                    {
                        if ( defender.InRange( attacker, myRange ) && attacker.CanSee( defender ) && attacker.InLOS( defender ) )
                        {
                            attacker.PlaySound( 1329 );
                            weapon.OnSwing( attacker, defender, weapon.RangedPercentage, false );
                            if ( !opportunity )
                                m_NextAttackAction = DateTime.Now + ComputeNextSwingTime();
                        }
                    }
                    else // actually mechanically thrown weapon
                    {
                        IKhaerosMobile km = attacker as IKhaerosMobile;
                        if ( defender.InRange( attacker, 3 + km.Feats.GetFeatLevel(FeatList.ThrowingMastery) ) && !defender.Deleted && defender.Map == attacker.Map &&
                            attacker.CanSee( defender ) && attacker.InLOS( defender ))
                        {
                            bool snatched = false;
                            bool deflected = false;

                            if( defender is PlayerMobile )
                            {
                                if( ( (PlayerMobile)defender ).Snatched() )
                                    snatched = true;

                                if( ( (PlayerMobile)defender ).DeflectedProjectile() )
                                    deflected = true;
                            }

                            if( m_OffHand )
                                weapon = ((PlayerMobile)attacker).OffHandWeapon;

                            double damagebonus = 1.0;

                            if( weapon.Throwable )
                            {
                                switch( km.Feats.GetFeatLevel(FeatList.Finesse) )
                                {
                                    case 0: break;
                                    case 1: damagebonus = 1.1; break;
                                    case 2: damagebonus = 1.2; break;
                                    case 3: damagebonus = 1.3; break;
                                }
                            }

                            /*if ( km.Feats.GetFeatLevel(FeatList.Finesse) > 0 && Utility.RandomDouble() <= (0.6*(km.Feats.GetFeatLevel(FeatList.Finesse))/(weapon.Weight*weapon.Weight) ) )
                                damagebonus += 1.0;*/
                            /*if (km.Feats.GetFeatLevel(FeatList.Finesse) > 0)
                                damagebonus += (0.2 * km.Feats.GetFeatLevel(FeatList.Finesse));*/

                            km.OffensiveFeat = FeatList.ThrowingMastery;
                            Point3D loc = defender.Location;
                            Map map = defender.Map;
                            //attacker.MovingEffect( defender, weapon.ItemID, 9, 1, false, false );
                            SendCombatAlerts( attacker, defender, weapon.ItemID, 5, 0, false, false, weapon.Hue, 1, 9501, 1, 0, EffectLayer.Waist, 0x100 );
                            if( snatched )
                            {
                                attacker.PlaySound( 1329 );
                                defender.Emote( "*snatches the weapon thrown at {0} by {1}*", defender.Female == true ? "her" : "him", attacker.Name );
                            }

                            else if( deflected )
                            {
                                attacker.PlaySound( 1329 );
                                defender.Emote( "*uses {0} shield to deflect the weapon thrown at {1} by {2}*", defender.Female == true ? "her" : "him", defender.Female == true ? "her" : "him", attacker.Name );
                            }

                            else
                            {
                                attacker.PlaySound( 1329 );

                                // 50% damage penalty from off-hand throwing
                                if( m_OffHand )
                                    damagebonus *= 0.5;

                                weapon.OnSwing( attacker, defender, damagebonus, true ); // bestDamage will be multiplied with in BaseWeapon due to "cleave"
                            }

                            if ( !snatched )
                                weapon.MoveToWorld( loc, map );
                            else
                                defender.AddToBackpack( weapon ); // N***a stole my ______!

                            // auto-equipping
                            if( ( weapon is Dagger || weapon is TyreanThrowingAxe ) && !m_OffHand && attacker is PlayerMobile && ( (PlayerMobile)attacker ).Feats.GetFeatLevel( FeatList.ThrowingMastery ) > 2 )
                            {
                                PlayerMobile m = attacker as PlayerMobile;

                                if( m.CraftContainer != null && !m.CraftContainer.Deleted && m.Backpack != null && !m.Backpack.Deleted && m.CraftContainer.IsChildOf(m.Backpack) )
                                {
                                    foreach( Item item in m.CraftContainer.Items )
                                    {
                                        if( item is BaseWeapon && weapon.NameType == ((BaseWeapon)item).NameType )
                                        {
                                            m.EquipItem( item );
                                            break;
                                        }
                                    }
                                }
                            }
                            if ( !opportunity )
                                m_NextAttackAction = DateTime.Now + ComputeNextSwingTime();
                        }
                    }
                }
                else // miss due to range
                {
                    if ( !spinning )
                    {
                        weapon.InitializeManeuver( attacker, null, false );
                        weapon.EndManeuver( attacker );
                    }
                    PlayMissSound( attacker, defender );
                }
            }

            if ( spinning )
            {
                m_RotationTimer = null;
                if ( !opportunity )
                m_NextAttackAction = DateTime.Now + ComputeNextSwingTime();
            }

            m_AttackTimer = null;
            if ( !flashy ) // otherwise another attack is coming right after
            {
                UpdateACBrainExternal();
                UpdateQueueDelay();
            }

            if (attacker != null && !attacker.Deleted && attacker.Weapon != null && attacker.Weapon is BaseWeapon && !(attacker.Weapon as BaseWeapon).Deleted)
            {
                    if ((attacker.Weapon as BaseWeapon).MaxHitPoints < 1)
                    {
                        attacker.SendMessage("Your weapon has fallen apart!");
                        attacker.SendSound(0x3E8, attacker.Location);
                        (attacker.Weapon as BaseWeapon).Delete();
                    }
            }
        }
        public void OnAfterOpponentMoved( Mobile opponent )
        {
            Mobile mob = AttachedTo as Mobile;

            if ( opponent == null || mob.Combatant != opponent || !opponent.Alive )
                return;
            CombatSystemAttachment opponentCSA = GetCSA( opponent );
            if ( m_Aiming || m_DefensiveFormation )
            {
                int myRange = ((BaseWeapon)mob.Weapon).MaxRange;
                if ( mob is BaseCreature && ((BaseCreature)mob).RangeFight > myRange )
                    myRange = ((BaseCreature)mob).RangeFight;
                if ( opponent.InRange( mob, myRange ) && m_DefensiveFormation )
                {
                    if ( opponentCSA.Charging ) // he charged straight into us
                    {
                        m_AttackTimer = new AttackTimer( mob, AttackType.Thrust, TimeSpan.Zero );
                        FinishAttack( opponentCSA.CalculateChargeBonus( mob.Location ), true ); // steal his damage bonus
                        CancelDefensiveFormation( true );
                    }
                    else if ( ((int)opponent.Direction) > 7 ) // running
                    {
                        m_AttackTimer = new AttackTimer( mob, AttackType.Thrust, TimeSpan.Zero );
                        FinishAttack( 1.0, true );
                        CancelDefensiveFormation( true );
                    }
                }

                if ( mob.Direction != mob.GetDirectionTo( mob.Combatant ) && mob.CanSee(mob.Combatant) )
                {
                    mob.Direction = mob.GetDirectionTo( mob.Combatant );
                    if ( m_AnimationTimer != null )
                        m_AnimationTimer.RefreshAnimation();
                }
            }
            else if ( !m_PerformingSequence && DateTime.Now >= (mob.LastMoveTime + TimeSpan.FromSeconds(0.75)) &&
                        mob.InRange( mob.Combatant, 3 ) )
            {
                if ( mob.Direction != mob.GetDirectionTo( mob.Combatant ) && mob.CanSee(mob.Combatant) )
                {
                    mob.Direction = mob.GetDirectionTo( mob.Combatant );
                }
            }

            UpdateACBrainExternal();
        }
        // melee attacks and throwing only
        public bool BeginAttack( AttackType attacktype, AttackFlags flags, bool playerInitiated )
        {
            if ( attacktype == AttackType.Invalid )
                return false;

            bool flashyFollowup = ( (flags&AttackFlags.FlashyFollowup) != AttackFlags.None );
            bool disregardDelay = ( (flags&AttackFlags.DisregardDelay) != AttackFlags.None );
            bool feint = false;
            bool flashy = false;
            Mobile attacker = AttachedTo as Mobile;
            IKhaerosMobile km = attacker as IKhaerosMobile;
            BaseWeapon weapon = attacker.Weapon as BaseWeapon;
            BaseShield shield = attacker.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;

            if( attacker is PlayerMobile )
            {
                PlayerMobile m = attacker as PlayerMobile;

                if( !m.EnableOffHand )
                    m.OffHandWeapon = null;
                else
                {
                    m.EnableOffHand = false;

                    if( !Commands.OffHandThrow.EnableOffHand( m ) )
                        return false;
                }
            }

            m_OffHand = ( attacker is PlayerMobile && ( (PlayerMobile)attacker ).OffHandThrowing ) && attacktype == AttackType.Throw;

            if ( !CanBeginCombatAction( ) || !CanBeginAttack( flags ) )
                return false;

            if ( attacktype == AttackType.Throw )
            {
                if( m_OffHand )
                    weapon = ((PlayerMobile)attacker).OffHandWeapon;

                if ( !CanThrow() )
                    return false;
                if ( weapon is AzhuranBoomerang ) // requires still time
                {
                    if ( !((BaseRanged)weapon).IsStill( attacker ) )
                    {
                        if ( playerInitiated )
                        {
                            m_ErrorMessage = "";
                            DisplayQueueResultMessage( QueueRanged() );
                        }

                        return false;
                    }
                }
            }
            else if ( !CanBeginMeleeAttack() )
                return false;
            else if ( attacktype == AttackType.ShieldBash && shield == null )
            {
                m_ErrorMessage = "A shield is needed in order to perform a shield bash!";
                return false;
            }

            if ( attacker.Mounted )
            {
                if ( attacktype == AttackType.Swing || attacktype == AttackType.Circular )
                {
                    m_ErrorMessage = "Cannot perform swing attacks while mounted.";
                    return false;
                }
                else if ( attacktype == AttackType.Thrust && !(CanThrustOnMount()) )
                    return false;
                else if ( attacktype == AttackType.ShieldBash )
                {
                    m_ErrorMessage = "This attack cannot be performed while mounted.";
                    return false;
                }
            }

            StopAllActions( false );

            if ( attacktype == AttackType.Circular ) // it is important that all of these are part of the same if/elseif chain
            { // as some feats are actually additional attacks, but that does not mean they can be used together with maneuvers.
                PlayerMobile pm = attacker as PlayerMobile;
                if ( km.Feats.GetFeatLevel(FeatList.CircularAttack) <= 0 )
                {
                    m_ErrorMessage = "You do not have the required feat.";
                    return false;
                }
                else if ( pm == null || weapon.Layer != Layer.TwoHanded || weapon is BaseRanged )
                {
                    m_ErrorMessage = "You can only perform this attack with two-handed melee weapons.";
                    return false;
                }
                else if ( weapon.NameType != pm.WeaponSpecialization && weapon.NameType != pm.SecondSpecialization )
                {
                    m_ErrorMessage = "You can only perform this attack with a weapon you have specialized in.";
                    return false;
                }
                else if ( !BaseWeapon.CheckStam( attacker, km.Feats.GetFeatLevel(FeatList.CircularAttack), false, false ) )
                {
                    m_ErrorMessage = ""; // will be displayed by the checkstam thingy
                    return false;
                }
            }
            else if ( attacktype == AttackType.ShieldBash )
            {
                if ( km.Feats.GetFeatLevel(FeatList.ShieldBash) <= 0 )
                {
                    m_ErrorMessage = "You do not have the required feat.";
                    return false;
                }
                else if ( !BaseWeapon.CheckStam( attacker, km.Feats.GetFeatLevel(FeatList.ShieldBash), false, false ) )
                {
                    m_ErrorMessage = ""; // will be displayed by the checkstam thingy
                    return false;
                }

                km.CombatManeuver = new ShieldBash( km.Feats.GetFeatLevel(FeatList.ShieldBash) );
                km.OffensiveFeat = FeatList.ShieldBash;

            }
            else if ( km.OffensiveFeat == FeatList.Feint )
            {
                if ( BaseWeapon.CheckStam( attacker, km.Feats.GetFeatLevel(FeatList.Feint), false, false ) )
                    feint = true;

                weapon.EndManeuver( attacker );
            }
            else if ( km.OffensiveFeat == FeatList.FlashyAttack )
            {
                if ( BaseWeapon.CheckStam( attacker, km.Feats.GetFeatLevel(FeatList.FlashyAttack), false, false ) )
                    flashy = true;

                weapon.EndManeuver( attacker );
            }

            // standard delay is 1 second
            double delay = ComputeAnimationDelay();
            if ( attacktype == AttackType.ShieldBash )
                delay = 4.0 - (3.0*((attacker.Skills[SkillName.Parry].Base)/100.0));
            if ( feint )
                delay *= 2.5-(((double)km.Feats.GetFeatLevel(FeatList.Feint))*0.5); // lvl 1 -> 2x slower, lvl 2 -> 1.5x slower, lvl 3 -> same as normal

            if ( attacktype == AttackType.Throw )
            {
                if ( !(weapon is AzhuranBoomerang) ) // otherwise the duration is already calculated
                    delay = 0.5;
            }
            int animspeed = (int)(delay*2);
            IKhaerosMobile kmob = attacker as IKhaerosMobile;
            AttackTimer newTimer = null;
            if ( attacktype != AttackType.Circular )
            {
                newTimer = new AttackTimer( attacker, attacktype, TimeSpan.FromSeconds( delay ) );
                newTimer.Flashy = flashy;
                newTimer.Feint = feint;
                newTimer.FlashyFollowup = flashyFollowup;
            }

            if ( attacktype == AttackType.Throw ) // throws cannot have a rotationtimer anyway
            {
                SpellHelper.Turn( attacker, m_Opponent );
                m_AttackTimer = newTimer;
            }

            if ( attacktype != AttackType.Circular ) // not if we're spinning
            {
                m_AttackTimer = newTimer;
                if ( m_Opponent != null )
                { // checking of AoO is necessary so we don't force Turn, which causes jerky movement
                    m_NextAttackAction = DateTime.Now + ComputeNextSwingTime() + TimeSpan.FromSeconds( delay );
                    if ( !CheckForFreeAttack( m_Opponent, true ) ) // attack of opportunity
                    {
                        m_AttackTimer = null;
                        SpellHelper.Turn( attacker, m_Opponent );
                        m_AttackTimer = newTimer;
                    }
                    else // we DID get an AoO, so we're done here
                    {
                        if ( BandageContext.GetContext( attacker ) != null )
                        {
                            BandageContext.GetContext( attacker ).StopHeal();
                            if ( attacker is IKhaerosMobile )
                            {
                                if ( ((IKhaerosMobile)attacker).HealingTimer != null )
                                {
                                    ((IKhaerosMobile)attacker).HealingTimer.Stop();
                                    ((IKhaerosMobile)attacker).HealingTimer = null;
                                }
                            }
                        }
                        return true;
                    }
                }
            }
            int zMod = 0;
            if ( attacker is BaseCreature )
                zMod = ((BaseCreature)attacker).Height;
            if ( !feint )
            {
                if ( attacktype == AttackType.ShieldBash )
                    m_NextAttackAction = DateTime.Now + TimeSpan.FromSeconds( 1.0 );
                else
                    m_NextAttackAction = DateTime.Now + ComputeNextSwingTime() + TimeSpan.FromSeconds( delay );
            }

            switch ( (int)attacktype )
            {
                case (int)AttackType.ShieldBash:
                {
                    if ( attacker.Body.Type == BodyType.Human )
                        Animate( 30, 7, 1, true, false, animspeed );
                    else
                    {
                        int[] anim = BAData.GetAnimation( attacker, AttackType.ShieldBash );
                        if ( anim != null )
                            Animate( anim[0], anim[1], 1, true, false, animspeed );
                    }
                    break;
                }
                case (int)AttackType.Throw:
                {
                    if ( attacker.Body.Type == BodyType.Human )
                    {
                        if ( !attacker.Mounted )
                        {
                            if( weapon.Layer == Layer.OneHanded || m_OffHand )
                                Animate( 11, 7, 1, true, false, animspeed );
                            else
                                Animate( 12, 7, 1, true, false, animspeed );
                        }
                        else
                        {
                            if( weapon.Layer == Layer.OneHanded || m_OffHand )
                                Animate( 26, 8, 1, true, false, animspeed );
                            else
                                Animate( 29, 7, 1, true, false, animspeed );
                        }
                    }
                    else
                    {
                        int[] anim = BAData.GetAnimation( attacker, AttackType.Throw );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Thrust );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Overhead );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Swing );
                        if ( anim != null )
                            Animate( anim[0], anim[1], 1, true, false, animspeed );
                    }
                    break;
                }
                case (int)AttackType.Circular: goto case (int)AttackType.Swing;
                case (int)AttackType.Swing:
                {
                    IEntity from = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + zMod ), attacker.Map );
                    IEntity to = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + 25 + zMod*2 ), attacker.Map );
                    SendCombatAlerts( from, to, 9556, 3, 0, true, false, 3, 2, 9501, 1, 0, EffectLayer.Head, 0x100 );
                    if ( attacker.Body.Type == BodyType.Human )
                    {
                        if ( weapon is Fists )
                        {
                            if ( kmob.Stance is VenomousWay )
                                Animate( 9, 7, 1, true, false, animspeed ); // karate chop
                            else
                                Animate( 31, 7, 1, true, false, animspeed ); // regular wrestling
                        }
                        else
                        {
                            if ( weapon.Layer == Layer.TwoHanded )
                                Animate( 13, 7, 1, true, false, animspeed );
                            else
                                Animate( 9, 7, 1, true, false, animspeed );
                        }
                    }
                    else
                    {
                        int[] anim = BAData.GetAnimation( attacker, AttackType.Swing );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Thrust );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Overhead );
                        if ( anim != null )
                            Animate( anim[0], anim[1], 1, true, false, animspeed );
                    }
                    break;
                }

                case (int)AttackType.Thrust:
                {
                    IEntity from = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + zMod ), attacker.Map );
                    IEntity to = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + 25 + zMod*2 ), attacker.Map );
                    SendCombatAlerts( from, to, 9556, 3, 0, true, false, 62, 2, 9501, 1, 0, EffectLayer.Head, 0x100 );
                    if ( attacker.Body.Type == BodyType.Human )
                    {
                        if ( attacker.Mounted )
                            Animate( 28, 7, 1, false, false, animspeed );
                        else
                        {
                            if ( weapon.Layer == Layer.TwoHanded )
                                Animate( 14, 7, 1, true, false, animspeed );
                            else
                            {
                                if ( weapon is Fists && kmob.Stance is SearingBreath )
                                    Animate( 32, 5, 1, false, false, animspeed+2 ); // headbutt! Nah. People could abuse bow to do this.
                                else if ( weapon is Fists && kmob.Stance is TempestuousSea ) // this is fine, though, heartstopper punch!
                                    Animate( 16, 7, 1, true, false, animspeed );
                                else
                                    Animate( 10, 7, 1, true, false, animspeed );
                            }
                        }
                    }
                    else
                    {
                        int[] anim = BAData.GetAnimation( attacker, AttackType.Thrust );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Overhead );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Swing );
                        if ( anim != null )
                            Animate( anim[0], anim[1], 1, true, false, animspeed );
                    }
                    break;
                }

                case (int)AttackType.Overhead:
                {
                    IEntity from = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + zMod ), attacker.Map );
                    IEntity to = new Entity( Server.Serial.Zero, new Point3D( attacker.X, attacker.Y, attacker.Z + 25 + zMod*2 ), attacker.Map );
                    SendCombatAlerts( from, to, 9556, 3, 0, true, false, 37, 2, 9501, 1, 0, EffectLayer.Head, 0x100 );

                    if ( attacker.Body.Type == BodyType.Human )
                    {
                        if ( attacker.Mounted )
                        {
                            if ( weapon.Layer == Layer.TwoHanded )
                                Animate( 29, 7, 1, true, false, animspeed );
                            else
                                Animate( 26, 7, 1, true, false, animspeed );
                        }
                        else
                        {
                            if ( weapon.Layer == Layer.TwoHanded )
                                Animate( 12, 7, 1, true, false, animspeed );
                            else
                                Animate( 11, 7, 1, true, false, animspeed );
                        }
                    }
                    else
                    {
                        int[] anim = BAData.GetAnimation( attacker, AttackType.Overhead );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Thrust );
                        if ( anim == null )
                            anim = BAData.GetAnimation( attacker, AttackType.Swing );
                        if ( anim != null )
                            Animate( anim[0], anim[1], 1, true, false, animspeed );
                    }
                    break;
                }
            }
            if (attacktype == AttackType.Circular)
            {
                m_RotationTimer = new RotationTimer(attacker, TimeSpan.FromSeconds(delay));
                m_RotationTimer.Start();
            }
            else
            {
                if (m_AttackTimer == null)
                {
                    attacker.SendMessage("There was an error in the CombatSystemAttachment @ line 2226.");
                    return false;
                }
                else
                    m_AttackTimer.Start();
            }

            // this delays as if we were parried, but if we actually won't be, then the delay will shorten
            // what if we get interrupted, though? it should count as a hit on our part, no extra delay.
            if ( BandageContext.GetContext( attacker ) != null )
            {
                BandageContext.GetContext( attacker ).StopHeal();
                if ( attacker is IKhaerosMobile )
                {
                    if ( ((IKhaerosMobile)attacker).HealingTimer != null )
                    {
                        ((IKhaerosMobile)attacker).HealingTimer.Stop();
                        ((IKhaerosMobile)attacker).HealingTimer = null;
                    }
                }
            }

            if ( m_Opponent != null )
            {
                GetCSA( m_Opponent ).UpdateACBrainExternal();
            }

            return true;
        }