void ShootSniper(MySmallShipBot bot, bool targetVisible, float distance, float angleToTarget)
        {
            switch (m_fireState)
            {
            case FireStateEnum.WAIT:
                m_fireTimer = 0;
                if (angleToTarget < HIT_CONE && targetVisible && distance <= FIRING_RANGE_MAX)
                {
                    m_fireState = FireStateEnum.HIT;
                }
                break;

            case FireStateEnum.HIT:
                m_fireTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                bot.Shoot(m_currentWeapon);
                if (m_fireTimer > 0.5f)
                {
                    m_fireState = FireStateEnum.COOLDOWN;
                    m_fireTimer = 0;
                }
                break;

            case FireStateEnum.COOLDOWN:
                m_fireTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                if (m_fireTimer > 0.5f)
                {
                    m_fireTimer = 0;
                    m_fireState = FireStateEnum.WAIT;
                }
                break;
            }
        }
 void SwitchToClosingInFormation()
 {
     m_fireState = FireStateEnum.WAIT;
     m_state     = StateEnum.CLOSING_IN_FORMATION;
 }
        void HandleShooting(MySmallShipBot bot, float distance, float angleToTarget, bool targetVisible)
        {
            if (bot.InitTime > 0)
            {
                return;
            }

            if (!MyBotCoordinator.IsAllowedToAttack(bot, m_target))
            {
                return;
            }

            m_smokeBombTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_flashBombTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_hologramTimer  -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

            // Change weapon - 2sec CD
            if (m_weaponChangeTimer < 2)
            {
                m_weaponChangeTimer = 0;

                var oldWeapon = m_currentWeapon;
                m_currentWeapon = SelectWeapon(distance);

                if (m_currentWeapon != oldWeapon)
                {
                    m_fireState = FireStateEnum.WAIT;
                }
            }

            // Handle weapon shooting
            switch (m_currentWeapon)
            {
            case MyMwcObjectBuilder_FireKeyEnum.Primary:
                ShootAutocannon(bot, targetVisible, distance, angleToTarget);
                break;

            case MyMwcObjectBuilder_FireKeyEnum.Secondary:
                ShootShotgun(bot, targetVisible, distance, angleToTarget);
                break;

            case MyMwcObjectBuilder_FireKeyEnum.Third:
                ShootSniper(bot, targetVisible, distance, angleToTarget);
                break;
            }

            if (MyFakes.ENABLE_BOT_MISSILES_AND_CANNON)
            {
                if (m_canShootFlash &&
                    m_flashBombTimer <= 0 &&
                    targetVisible &&
                    distance > 125 && distance < 250 &&
                    angleToTarget < SHOOT_CONE)
                {
                    m_flashBombTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.FlashBombFront);
                }

                if (m_canShootSmoke &&
                    m_smokeBombTimer <= 0 &&
                    targetVisible &&
                    distance > 150 && distance < 300 &&
                    angleToTarget < SHOOT_CONE)
                {
                    m_smokeBombTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.SmokeBombFront);
                }

                if (m_canShootHologram &&
                    m_hologramTimer <= 0 &&
                    distance > 100 && distance < 500)
                {
                    m_hologramTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.HologramFront);
                }

                // Handle missile and cannon shooting
                if (m_canShootMissile || m_canShootCannon)
                {
                    MyMwcObjectBuilder_FireKeyEnum firekey;
                    if (m_canShootMissile)
                    {
                        firekey = MyMwcObjectBuilder_FireKeyEnum.Fourth;
                    }
                    else
                    {
                        firekey = MyMwcObjectBuilder_FireKeyEnum.Fifth;
                    }

                    int missileFireTime = MyMinerGame.TotalGamePlayTimeInMilliseconds - m_planedMissileTime;
                    if (missileFireTime > 0)
                    {
                        if (missileFireTime > 1500)
                        {
                            // if bot can't shoot in 1.5 sec, wait for next time window
                            PlanNextMissile();
                        }
                        else if (targetVisible &&
                                 distance >= MyFakes.BOT_MISSILE_FIRING_RANGE_MIN &&
                                 distance <= FIRING_RANGE_MAX &&
                                 angleToTarget < SHOOT_CONE)
                        {
                            // Successful shot
                            bot.Shoot(firekey);
                            PlanNextMissile();
                        }
                    }
                }
            }
        }
 void SwitchToClosing()
 {
     m_fireState    = FireStateEnum.WAIT;
     m_state        = StateEnum.CLOSING;
     m_closingTimer = 0;
 }
 void ShootSniper(MySmallShipBot bot, bool targetVisible, float distance, float angleToTarget)
 {
     switch (m_fireState)
     {
         case FireStateEnum.WAIT:
             m_fireTimer = 0;
             if (angleToTarget < HIT_CONE && targetVisible && distance <= FIRING_RANGE_MAX)
             {
                 m_fireState = FireStateEnum.HIT;
             }
             break;
         case FireStateEnum.HIT:
             m_fireTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
             bot.Shoot(m_currentWeapon);
             if (m_fireTimer > 0.5f)
             {
                 m_fireState = FireStateEnum.COOLDOWN;
                 m_fireTimer = 0;
             }
             break;
         case FireStateEnum.COOLDOWN:
             m_fireTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
             if (m_fireTimer > 0.5f)
             {
                 m_fireTimer = 0;
                 m_fireState = FireStateEnum.WAIT;
             }
             break;
     }
 }
        void HandleShooting(MySmallShipBot bot, float distance, float angleToTarget, bool targetVisible)
        {
            if (bot.InitTime > 0)
                return;

            if (!MyBotCoordinator.IsAllowedToAttack(bot, m_target))
            {      
                return;
            }

            m_smokeBombTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_flashBombTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_hologramTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

            // Change weapon - 2sec CD
            if (m_weaponChangeTimer < 2)
            {
                m_weaponChangeTimer = 0;

                var oldWeapon = m_currentWeapon;
                m_currentWeapon = SelectWeapon(distance);
                
                if (m_currentWeapon != oldWeapon)
                {
                    m_fireState = FireStateEnum.WAIT;
                }
            }

            // Handle weapon shooting
            switch (m_currentWeapon)
            {
                case MyMwcObjectBuilder_FireKeyEnum.Primary:
                    ShootAutocannon(bot, targetVisible, distance, angleToTarget);
                    break;
                case MyMwcObjectBuilder_FireKeyEnum.Secondary:
                    ShootShotgun(bot, targetVisible, distance, angleToTarget);
                    break;
                case MyMwcObjectBuilder_FireKeyEnum.Third:
                    ShootSniper(bot, targetVisible, distance, angleToTarget);
                    break;
            }

            if (MyFakes.ENABLE_BOT_MISSILES_AND_CANNON)
            {
                if (m_canShootFlash &&
                    m_flashBombTimer <= 0 &&
                    targetVisible &&
                    distance > 125 && distance < 250 &&
                    angleToTarget < SHOOT_CONE)
                {
                    m_flashBombTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.FlashBombFront);
                }

                if (m_canShootSmoke &&
                    m_smokeBombTimer <= 0 &&
                    targetVisible &&
                    distance > 150 && distance < 300 &&
                    angleToTarget < SHOOT_CONE)
                {
                    m_smokeBombTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.SmokeBombFront);
                }

                if (m_canShootHologram &&
                    m_hologramTimer <= 0 &&
                    distance > 100 && distance < 500)
                {
                    m_hologramTimer = MyMwcUtils.GetRandomFloat(30, 60);
                    bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.HologramFront);
                }

                // Handle missile and cannon shooting
                if (m_canShootMissile || m_canShootCannon)
                {
                    MyMwcObjectBuilder_FireKeyEnum firekey;
                    if (m_canShootMissile)
                    {
                        firekey = MyMwcObjectBuilder_FireKeyEnum.Fourth;
                    }
                    else
                    {
                        firekey = MyMwcObjectBuilder_FireKeyEnum.Fifth;
                    }

                    int missileFireTime = MyMinerGame.TotalGamePlayTimeInMilliseconds - m_planedMissileTime;
                    if (missileFireTime > 0)
                    {

                        if (missileFireTime > 1500)
                        {
                            // if bot can't shoot in 1.5 sec, wait for next time window
                            PlanNextMissile();
                        }
                        else if (targetVisible &&
                            distance >= MyFakes.BOT_MISSILE_FIRING_RANGE_MIN &&
                            distance <= FIRING_RANGE_MAX &&
                            angleToTarget < SHOOT_CONE)
                        {
                            // Successful shot
                            bot.Shoot(firekey);
                            PlanNextMissile();
                        }
                    }
                }
            }
        }
 void SwitchToClosingInFormation()
 {
     m_fireState = FireStateEnum.WAIT;
     m_state = StateEnum.CLOSING_IN_FORMATION;
 }
 void SwitchToClosing()
 {
     m_fireState = FireStateEnum.WAIT;
     m_state = StateEnum.CLOSING;
     m_closingTimer = 0;
 }