public BehaviorTacticalCharge(Formation formation)
     : base(formation)
 {
     this._lastTarget                = (FormationQuerySystem)null;
     this.CurrentOrder               = MovementOrder.MovementOrderCharge;
     this.CurrentFacingOrder         = FacingOrder.FacingOrderLookAtEnemy;
     this._chargeState               = BehaviorTacticalCharge.ChargeState.Undetermined;
     this.BehaviorCoherence          = 0.5f;
     this._desiredChargeStopDistance = 20f;
 }
        private BehaviorTacticalCharge.ChargeState CheckAndChangeState()
        {
            BehaviorTacticalCharge.ChargeState chargeState = this._chargeState;
            if (this.formation.QuerySystem.ClosestEnemyFormation == null)
            {
                chargeState = BehaviorTacticalCharge.ChargeState.Undetermined;
            }
            else
            {
                switch (this._chargeState)
                {
                case BehaviorTacticalCharge.ChargeState.Undetermined:
                    if (this.formation.QuerySystem.ClosestEnemyFormation != null && (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) / (double)this.formation.QuerySystem.MovementSpeedMaximum <= 5.0))
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Charging:
                    if (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation)
                    {
                        if (!this.formation.QuerySystem.IsInfantryFormation || !this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation)
                        {
                            chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                            break;
                        }
                        Vec2   vec2            = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition;
                        double num1            = (double)vec2.Normalize();
                        Vec2   currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity;
                        double num2            = (double)currentVelocity.Normalize();
                        if (num1 / num2 <= 6.0 && (double)vec2.DotProduct(currentVelocity) > 0.5)
                        {
                            this._chargeState = BehaviorTacticalCharge.ChargeState.Bracing;
                            break;
                        }
                        break;
                    }
                    if ((double)this._initialChargeDirection.DotProduct(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition) <= 0.0)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.ChargingPast;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.ChargingPast:
                    if (this._chargingPastTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) >= (double)this._desiredChargeStopDistance)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Reforming;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Reforming:
                    if (this._reformTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) <= 30.0)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Bracing:
                    bool flag = false;
                    if (this.formation.QuerySystem.IsInfantryFormation && this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation)
                    {
                        Vec2   vec2            = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition;
                        double num1            = (double)vec2.Normalize();
                        Vec2   currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity;
                        double num2            = (double)currentVelocity.Normalize();
                        if (num1 / num2 <= 8.0 && (double)vec2.DotProduct(currentVelocity) > 0.330000013113022)
                        {
                            flag = true;
                        }
                    }
                    if (!flag)
                    {
                        this._bracePosition = Vec2.Invalid;
                        this._chargeState   = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;
                }
            }
            return(chargeState);
        }
        protected override void CalculateCurrentOrder()
        {
            if (this.formation.QuerySystem.ClosestEnemyFormation == null)
            {
                this.CurrentOrder = MovementOrder.MovementOrderCharge;
            }
            else
            {
                BehaviorTacticalCharge.ChargeState chargeState = this.CheckAndChangeState();
                if (chargeState != this._chargeState)
                {
                    this._chargeState = chargeState;
                    switch (this._chargeState)
                    {
                    case BehaviorTacticalCharge.ChargeState.Undetermined:
                        this.CurrentOrder = MovementOrder.MovementOrderCharge;
                        break;

                    case BehaviorTacticalCharge.ChargeState.Charging:
                        this._lastTarget = this.formation.QuerySystem.ClosestEnemyFormation;
                        if (this.formation.QuerySystem.IsCavalryFormation || this.formation.QuerySystem.IsRangedCavalryFormation)
                        {
                            this._initialChargeDirection    = this._lastTarget.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition;
                            this._desiredChargeStopDistance = MBMath.ClampFloat(this._initialChargeDirection.Normalize(), 20f, 50f);
                            break;
                        }
                        break;

                    case BehaviorTacticalCharge.ChargeState.ChargingPast:
                        this._chargingPastTimer = new Timer(MBCommon.GetTime(MBCommon.TimeType.Mission), 5f);
                        break;

                    case BehaviorTacticalCharge.ChargeState.Reforming:
                        this._reformTimer = new Timer(MBCommon.GetTime(MBCommon.TimeType.Mission), 2f);
                        break;

                    case BehaviorTacticalCharge.ChargeState.Bracing:
                        this._bracePosition = this.formation.QuerySystem.AveragePosition + (this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized() * 5f;
                        break;
                    }
                }
                switch (this._chargeState)
                {
                case BehaviorTacticalCharge.ChargeState.Undetermined:
                    if (this.formation.QuerySystem.ClosestEnemyFormation != null && (this.formation.QuerySystem.IsCavalryFormation || this.formation.QuerySystem.IsRangedCavalryFormation))
                    {
                        this.CurrentOrder = MovementOrder.MovementOrderMove(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition);
                    }
                    else
                    {
                        this.CurrentOrder = MovementOrder.MovementOrderCharge;
                    }
                    this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtEnemy;
                    break;

                case BehaviorTacticalCharge.ChargeState.Charging:
                    if (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation)
                    {
                        this.CurrentOrder       = MovementOrder.MovementOrderMove(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition);
                        this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtEnemy;
                        break;
                    }
                    Vec2          direction1      = (this._lastTarget.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized();
                    WorldPosition medianPosition1 = this._lastTarget.MedianPosition;
                    Vec2          vec2            = medianPosition1.AsVec2 + direction1 * this._desiredChargeStopDistance;
                    medianPosition1.SetVec2(vec2);
                    this.CurrentOrder       = MovementOrder.MovementOrderMove(medianPosition1);
                    this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction1);
                    break;

                case BehaviorTacticalCharge.ChargeState.ChargingPast:
                    Vec2          averagePosition = this.formation.QuerySystem.AveragePosition;
                    WorldPosition medianPosition2 = this._lastTarget.MedianPosition;
                    Vec2          asVec2          = medianPosition2.AsVec2;
                    Vec2          direction2      = averagePosition - asVec2;
                    if ((double)direction2.Normalize() <= 20.0)
                    {
                        Vec2 initialChargeDirection = this._initialChargeDirection;
                    }
                    this._lastReformDestination = this._lastTarget.MedianPosition;
                    medianPosition2             = this._lastTarget.MedianPosition;
                    this._lastReformDestination.SetVec2(medianPosition2.AsVec2 + direction2 * this._desiredChargeStopDistance);
                    this.CurrentOrder       = MovementOrder.MovementOrderMove(this._lastReformDestination);
                    this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction2);
                    break;

                case BehaviorTacticalCharge.ChargeState.Reforming:
                    this.CurrentOrder       = MovementOrder.MovementOrderMove(this._lastReformDestination);
                    this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtEnemy;
                    break;

                case BehaviorTacticalCharge.ChargeState.Bracing:
                    WorldPosition medianPosition3 = this.formation.QuerySystem.MedianPosition;
                    medianPosition3.SetVec2(this._bracePosition);
                    this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition3);
                    break;
                }
            }
        }