コード例 #1
0
 void UpdateGoals(MySmallShipBot bot)
 {
     moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     up         = MyMwcUtils.GetRandomVector3Normalized() * 1000;
     shoot      = MyMwcUtils.GetRandomBool(2);
 }
コード例 #2
0
        private void FollowToRoutePosition(MySmallShipBot bot)
        {
            // Fly to visible position, if too close look for new visible position
            if (Vector3.DistanceSquared(m_followPosition.Value, bot.GetPosition()) < 5 * 5)
            {
                m_followPosition = null;
            }
            else
            {
                bot.Move(m_followPosition.Value, m_followPosition.Value, bot.WorldMatrix.Up, false, 1, 2);

                if (m_stuckTimer > STUCK_TIME)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                    {
                        m_followPosition = null;
                    }
                    else
                    {
                        m_followPosition = m_stuckPosition + MyMwcUtils.GetRandomVector3Normalized() * 1000;
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #3
0
 void UpdateGoals(MySmallShipBot bot)
 {
     moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     up = MyMwcUtils.GetRandomVector3Normalized() * 1000;
     shoot = MyMwcUtils.GetRandomBool(2);
 }
コード例 #4
0
        private void FollowToRoutePosition(MySmallShipBot bot)
        {
            // Fly to visible position, if too close look for new visible position
            if (Vector3.DistanceSquared(m_followPosition.Value, bot.GetPosition()) < 5 * 5)
            {
                m_followPosition = null;
            }
            else
            {
                bot.Move(m_followPosition.Value, m_followPosition.Value, bot.WorldMatrix.Up, false, 1, 2);

                if (m_stuckTimer > STUCK_TIME)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                    {
                        m_followPosition = null;
                    }
                    else
                    {
                        m_followPosition = m_stuckPosition + MyMwcUtils.GetRandomVector3Normalized() * 1000;
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #5
0
        internal bool TrySwitchExploreSearch(MySmallShipBot bot)
        {
            Vector3 flyTo = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 100);

            if (bot.TryTestPosition(flyTo, bot.GetPosition()))
            {
                m_state = CuriousState.EXPLORE_SEARCHING;
                return(true);
            }
            return(false);
        }
コード例 #6
0
        internal override void Init(MySmallShipBot bot)
        {
            base.Init(bot);

            baseMatrix = bot.WorldMatrix;
            lookTarget = bot.GetPosition() + baseMatrix.Forward * 100;
        }
コード例 #7
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            MyEntity    enemy = bot.GetEnemy();
            MyDrillBase drill = bot.Weapons.GetMountedDrill();

            if (enemy != null && drill != null)
            {
                Vector3 botToEnemy = enemy.GetPosition() - bot.GetPosition();
                float   distance   = botToEnemy.Length();
                if (distance <= (bot.DrillDistance + bot.WorldVolume.Radius + enemy.WorldVolume.Radius))
                {
                    if (drill.CurrentState == MyDrillStateEnum.InsideShip)
                    {
                        drill.Eject();
                    }
                    else
                    {
                        drill.Shot(null);
                    }
                }
                else
                {
                    // pull drill back
                    if (drill.CurrentState == MyDrillStateEnum.Activated)
                    {
                        drill.Eject();
                    }
                }

                bot.Move(enemy.GetPosition(), enemy.GetPosition(), enemy.WorldMatrix.Up, distance < 100);
            }
        }
コード例 #8
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            MyEntity enemy = bot.GetEnemy();
            MyDrillBase drill = bot.Weapons.GetMountedDrill();

            if (enemy != null && drill != null)
            {
                Vector3 botToEnemy = enemy.GetPosition() - bot.GetPosition();
                float distance = botToEnemy.Length();
                if (distance <= (bot.DrillDistance + bot.WorldVolume.Radius + enemy.WorldVolume.Radius))
                {
                    if (drill.CurrentState == MyDrillStateEnum.InsideShip)
                    {
                        drill.Eject();
                    }
                    else
                    {
                        drill.Shot(null);
                    }
                }
                else
                {
                    // pull drill back
                    if (drill.CurrentState == MyDrillStateEnum.Activated)
                    {
                        drill.Eject();
                    }
                }

                bot.Move(enemy.GetPosition(), enemy.GetPosition(), enemy.WorldMatrix.Up, distance < 100);
            }
        }
コード例 #9
0
 public static void DebugDraw()
 {
     foreach (var pair in CurrentBotsAttackingPlayer)
     {
         MySmallShipBot bot = pair.Value;
         MyDebugDraw.DrawSphereWireframe(bot.GetPosition(), bot.WorldVolume.Radius, new Vector3(1, 0, 0), 1);
     }
 }
コード例 #10
0
 public void Init(MySmallShipBot bot)
 {
     m_stuckPosition  = bot.GetPosition();
     m_stuckTimer     = 0;
     m_followPosition = null;
     m_followPath     = null;
     PathNotFound     = false;
 }
コード例 #11
0
 public void Init(MySmallShipBot bot)
 {
     m_stuckPosition = bot.GetPosition();
     m_stuckTimer = 0;
     m_followPosition = null;
     m_followPath = null;
     PathNotFound = false;
 }
コード例 #12
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            MyEntity enemy = bot.GetClosestEnemy();
            if (enemy != null)
            {
                Vector3 enemyToBot = bot.GetPosition() - enemy.GetPosition();
                float distance = enemyToBot.Length();
                if (distance <= bot.RunAwayDistance)
                {
                    Vector3 enemyToBotDirection = enemyToBot / distance;
                    Vector3 escapeTarget = bot.GetPosition() + enemyToBotDirection * 1000;
                    bot.Move(escapeTarget, escapeTarget, bot.WorldMatrix.Up, false);
                }
            }
        }
コード例 #13
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            MyEntity enemy = bot.GetClosestEnemy();

            if (enemy != null)
            {
                Vector3 enemyToBot = bot.GetPosition() - enemy.GetPosition();
                float   distance   = enemyToBot.Length();
                if (distance <= bot.RunAwayDistance)
                {
                    Vector3 enemyToBotDirection = enemyToBot / distance;
                    Vector3 escapeTarget        = bot.GetPosition() + enemyToBotDirection * 1000;
                    bot.Move(escapeTarget, escapeTarget, bot.WorldMatrix.Up, false);
                }
            }
        }
コード例 #14
0
 public override bool IsSuccess()
 {
     if (m_botToTalk != null && Vector3.DistanceSquared(m_botToTalk.GetPosition(), MySession.PlayerShip.GetPosition()) <= m_distanceToTalk * m_distanceToTalk)
     {
         StopFollow();
         return(true);
     }
     return(false);
 }
コード例 #15
0
        public void Init(MySmallShipBot bot, Vector3 location)
        {
            locationVisibleCheckTimer = 0;
            stuckPosition             = bot.GetPosition();
            stuckTimer          = 0;
            PathNotFound        = false;
            this.location       = location;
            currentPathPosition = 0;

            UpdateTargetVisibility(bot);
        }
コード例 #16
0
        public void Init(MySmallShipBot bot, Vector3 location)
        {
            locationVisibleCheckTimer = 0;
            stuckPosition = bot.GetPosition();
            stuckTimer = 0;
            PathNotFound = false;
            this.location = location;
            currentPathPosition = 0;

            UpdateTargetVisibility(bot);
        }
コード例 #17
0
 public void Start(MySmallShipBot bot)
 {
     m_bot = bot;
     m_botFaction = bot.Faction;
     m_seeDistance = bot.SeeDistance;
     m_botWorldMatrix = bot.WorldMatrix;
     m_position = bot.GetPosition();
     m_closestEnemy_OnClose = closestEnemy_OnClose;
     m_closestVisual_OnClose = closestVisual_OnClose;
     m_bot.OnClose += m_bot_OnClose;
 }
コード例 #18
0
 public void Start(MySmallShipBot bot)
 {
     m_bot                   = bot;
     m_botFaction            = bot.Faction;
     m_seeDistance           = bot.SeeDistance;
     m_botWorldMatrix        = bot.WorldMatrix;
     m_position              = bot.GetPosition();
     m_closestEnemy_OnClose  = closestEnemy_OnClose;
     m_closestVisual_OnClose = closestVisual_OnClose;
     m_bot.OnClose          += m_bot_OnClose;
 }
コード例 #19
0
        private void UpdateVisibility(MySmallShipBot bot, Vector3 targetPosition)
        {
            if (m_visibilityCheckTimer <= 0)
            {
                if (bot.GetPosition() == targetPosition)
                {
                    m_targetVisible = true;
                }
                else
                {
                    MyLine line   = new MyLine(bot.GetPosition(), targetPosition, true);
                    var    result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
                    m_targetVisible = !result.HasValue;
                }

                m_visibilityCheckTimer = 0.5f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
コード例 #20
0
 private void UpdateTargetVisibility(MySmallShipBot bot)
 {
     if (locationVisibleCheckTimer <= 0)
     {
         MyLine line   = new MyLine(bot.GetPosition(), location, true);
         var    result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
         locationVisible           = !result.HasValue;
         locationVisibleCheckTimer = 0.25f;
     }
     else
     {
         locationVisibleCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
     }
 }
コード例 #21
0
        bool TrySwitchToAttackSearch(MySmallShipBot bot)
        {
            Vector3 newFlyToTarget = m_target.WorldVolume.Center
                                     + m_target.WorldMatrix.Forward * (MyMwcUtils.GetRandomFloat(ATTACK_DISTANCE_MIN, ATTACK_DISTANCE_MAX) + m_target.WorldVolume.Radius)
                                     + m_target.WorldMatrix.Up * MyMwcUtils.GetRandomFloat(-50, 50)
                                     + m_target.WorldMatrix.Left * MyMwcUtils.GetRandomFloat(-50, 50);

            if (bot.TryTestPosition(newFlyToTarget, bot.GetPosition()))
            {
                m_state = StateEnum.ATACKING_SEARCHING;
                return(true);
            }
            return(false);
        }
コード例 #22
0
        private void FollowPath(MySmallShipBot bot)
        {
            if (currentPathPosition >= followPath.Count)
            {
                followPath = null;  // reached the goal or got stuck
            }
            else if (Vector3.DistanceSquared(followPath[currentPathPosition], bot.GetPosition()) < PATH_NEAR_DISTANCE_SQR)
            {
                currentPathPosition++;  // next waypoint reached
            }
            else
            {
                bot.Move(followPath[currentPathPosition], followPath[currentPathPosition], bot.WorldMatrix.Up, false, 1, 2);

                if (stuckTimer > 3)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), stuckPosition) > STUCK_DISTANCE)
                    {
                        currentPathPosition++;  // try skipping ahead to the next waypoint instead of getting stuck right away
                        ResetStuck(bot);
                    }
                    else
                    {
                        //followPath[currentPathPosition] += MyMwcUtils.GetRandomVector3Normalized() * 1000;  // jitter the sub-goal
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #23
0
        public override bool IsSuccess()
        {
            if (m_success)
            {
                return(true);
            }

            if (m_botToTalk != null && Vector3.DistanceSquared(m_botToTalk.GetPosition(), MySession.PlayerShip.GetPosition()) <= m_distanceToTalk * m_distanceToTalk)
            {
                MyScriptWrapper.Follow(MySession.PlayerShip, m_botToTalk);
                m_botToTalk.LookTarget = MySession.PlayerShip;
                return(true);
            }
            return(false);
        }
コード例 #24
0
        private void FollowPath(MySmallShipBot bot)
        {
            if (m_currentPathPosition >= m_followPath.Count)
            {
                m_followPath = null;  // reached the goal or got stuck
            }
            else if (Vector3.DistanceSquared(m_followPath[m_currentPathPosition], bot.GetPosition()) < PATH_NEAR_DISTANCE_SQR)
            {
                m_currentPathPosition++;  // next waypoint reached
            }
            else
            {
                bot.Move(m_followPath[m_currentPathPosition], m_followPath[m_currentPathPosition], bot.WorldMatrix.Up, false, 1, 2);

                if (m_stuckTimer > STUCK_TIME)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                    {
                        m_currentPathPosition++;  // try skipping ahead to the next waypoint instead of getting stuck right away
                        ResetStuck(bot);
                    }
                    else
                    {
                        m_followPath[m_currentPathPosition] += MyMwcUtils.GetRandomVector3Normalized() * 1000;  // jitter the sub-goal
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #25
0
        private Vector3 GetTargetPositionByDamageRatio(MySmallShipBot bot)
        {
            Vector3 targetPos = m_target.GetPosition();

            if (MySession.PlayerShip != null && MyFactions.GetFactionsRelation(bot, MySession.PlayerShip) == MyFactionRelationEnum.Enemy)
            {
                Vector3 botPos         = bot.GetPosition();
                Vector3 botToTarget    = targetPos - botPos;
                Vector3 dir            = Vector3.Normalize(botToTarget);
                float   degrees        = (float)Math.Pow(120, bot.GetDamageRatio() * 1.5 - 1.2) * 4f;
                float   deviatingAngle = MathHelper.ToRadians(degrees);
                dir       = MyUtilRandomVector3ByDeviatingVector.GetRandom(dir, deviatingAngle);
                targetPos = botPos + botToTarget.Length() * dir * 3;
            }
            return(targetPos);
        }
コード例 #26
0
        private void UpdateTargetVisibility(MySmallShipBot bot)
        {
            if (m_target != null && m_visibilityCheckTimer <= 0)
            {
                Debug.Assert(!m_target.Closed);

                MyLine line   = new MyLine(bot.GetPosition(), m_target.GetPosition(), true);
                var    result = MyEntities.GetIntersectionWithLine(ref line, bot, m_target, true, ignoreChilds: true);
                m_targetVisible        = !result.HasValue;
                m_visibilityCheckTimer = 0.25f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
コード例 #27
0
        /// <summary>
        /// For debugging, add text to the debug screen which details the state of this bot.
        /// TODO: Move this to MyGuiScreenDebugBot. That class is specific to bot so this stuff could/should go there.
        /// </summary>
        /// <param name="bot">Computer-controlled ship.</param>
        /// <param name="player">The bot's target.</param>
        public static void AddToFrameDebugText(MySmallShipBot bot, MySmallShip player)
        {
            // Get a reference to the debug screen.
            MyGuiScreenDebugBot debugScreen = MyGuiManager.GetScreenDebugBot();

            if (debugScreen != null)
            {
                // Here's the bot info we're adding to the debug screen text.
                debugScreen.AddToFrameDebugText("MyPhysObjectBot");

                // Hello.
                debugScreen.AddToFrameDebugText("   Message: Hello!");

                // Position.
                debugScreen.AddToFrameDebugText("   Player.Position: " + MyUtils.GetFormatedVector3(player.GetPosition(), 0));

                // Offest between bot and player.
                Vector3 playerPos   = player.GetPosition();
                Vector3 botPos      = bot.GetPosition();
                Vector3 botToPlayer = botPos - playerPos;
                debugScreen.AddToFrameDebugText("   BotToPlayer: " + botToPlayer.ToString());

                // Offest between player and bot.
                Vector3 playerToBot = playerPos - botPos;
                debugScreen.AddToFrameDebugText("   PlayerToBot: " + playerToBot.ToString());

                // Bot forward
                Vector3 forward = bot.WorldMatrix.Forward;
                debugScreen.AddToFrameDebugText("   Bot.WorldMatrix.Forward: " + MyUtils.GetFormatedVector3(forward, 0));

                // m_playersRelativePosition
                //debugScreen.AddToFrameDebugText("   Bot.m_playersRelativePosition: " + MyUtils.GetFormatedVector3(bot.Behavior.TargetsRelativePosition, 0));

                // Aimed at player?
                //debugScreen.AddToFrameDebugText("   Bot.IsAimedAtPlayer: " + bot.IsBotPrettyMuchAimedAtPlayer());

                // Distance to player.
                //debugScreen.AddToFrameDebugText("   Bot.DistanceToPlayer: " + ((int)(bot.DistanceTo(bot.Decision.Target))).ToString());

                // Rotation indicator.
                //debugScreen.AddToFrameDebugText("   Bot.RotationIndicator: " + MyUtils.GetFormatedVector2(bot.RotationIndicator, 1));

                // Blank line.
                debugScreen.AddToFrameDebugText(" ");
            }
        }
コード例 #28
0
        internal override void Init(MySmallShipBot bot)
        {
            base.Init(bot);

            m_isInvalid = false;
            m_target    = SourceDesire.GetEnemy();
            if (m_target != null)
            {
                Debug.Assert(m_target != bot);
            }
            findSmallship = new MyFindSmallshipHelper();

            m_visibilityCheckTimer = 0;       // force visibility test
            m_closingTimer         = 0;
            m_forcedClosingTimer   = 0;
            m_hologramTargetTimer  = 0;

            SwitchToClosing();

            PlanNextMissile();

            m_timeToAlarmCheck = 2;

            m_playerAttackDecisionTimer = 0;

            MyScriptWrapper.OnEntityAttackedByBot(bot, m_target);

            m_canShootWithAutocanon = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Primary);
            m_canShootWithShotGun   = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Secondary);
            m_canShootWithSniper    = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Third);
            m_canShootMissile       = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Fourth);
            m_canShootCannon        = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Fifth);

            m_canShootFlash    = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.FlashBombFront) && MyFakes.BOT_USE_FLASH_BOMBS;
            m_canShootSmoke    = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.SmokeBombFront) && MyFakes.BOT_USE_SMOKE_BOMBS;
            m_canShootHologram = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.HologramFront) && MyFakes.BOT_USE_HOLOGRAMS;

            m_weaponChangeTimer = 0;
            m_currentWeapon     = SelectWeapon((bot.GetPosition() - m_target.GetPosition()).Length());

            m_smokeBombTimer = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
            m_flashBombTimer = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
            m_hologramTimer  = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
        }
コード例 #29
0
        /// <summary>
        /// Returns if bot can see target. If bot's fov is enabled and target is smallship which has radar jammer, then bot can see only targets in front of him
        /// </summary>
        /// <param name="target">Target</param>
        private bool CanSeeTarget(MySmallShipBot me, MyEntity target)
        {
            bool canSeeTarget = true;

            if (MyFakes.ENABLE_BOTS_FOV_WHEN_RADAR_JAMMER)
            {
                MySmallShip smallShipTarget = target as MySmallShip;
                if (smallShipTarget != null && !smallShipTarget.IsHologram && smallShipTarget.HasRadarJammerActive())
                {
                    float distanceSqr    = (me.GetPosition() - target.GetPosition()).LengthSquared();
                    float rangeOfViewSqr = smallShipTarget.IsHiddenFromBots() ? MyAIConstants.BOT_FOV_RANGE_HIDDEN : MyAIConstants.BOT_FOV_RANGE;
                    float targetRange    = Vector3.Dot(m_botWorldMatrix.Forward, target.GetPosition() - me.GetPosition());

                    canSeeTarget =
                        targetRange <= rangeOfViewSqr &&
                        Vector3.Dot(m_botWorldMatrix.Forward, Vector3.Normalize(target.GetPosition() - m_position)) >= MyAIConstants.BOT_FOV_COS;
                }
            }
            return(canSeeTarget);
        }
コード例 #30
0
        public override void Update()
        {
            if (m_dummy == null)
            {
                return;
            }

            base.Update();

            if (m_invalid)
            {
                return;
            }

            if ((MySession.PlayerShip.GetPosition() - m_target.GetPosition()).Length() < FailDistanceTooShort)
            {
                MyScriptWrapper.PlayDialogue(ShortDialog);
                m_target.SpeedModifier = 2.00f;
                m_dummy = null;
            }

            if ((MySession.PlayerShip.GetPosition() - m_target.GetPosition()).Length() < FailDistanceTooShort + WarningDelta)
            {
                MyScriptWrapper.AddNotification(m_notificationWarningSlowDown);
                m_notificationWarningSlowDown.Appear();
            }
            else
            {
                m_notificationWarningSlowDown.Disappear();
            }


            if ((MySession.PlayerShip.GetPosition() - m_target.GetPosition()).Length() > FailDistanceTooFar)
            {
                MyScriptWrapper.PlayDialogue(FarDialog);
                m_dummy = null;
            }

            if ((MySession.PlayerShip.GetPosition() - m_target.GetPosition()).Length() > FailDistanceTooFar - WarningDelta)
            {
                m_notificationWarningHurry.Appear();
                MyScriptWrapper.AddNotification(m_notificationWarningHurry);
            }
            else
            {
                m_notificationWarningHurry.Disappear();
            }
        }
コード例 #31
0
        public static void AddAttacker(MySmallShipBot attacker, MyEntity target)
        {
            if (MySession.IsPlayerShip(target))
            {
                foreach (var pair in CurrentBotsAttackingPlayer)
                {
                    if (pair.Value == attacker)
                    {
                        return;
                    }
                }

                float attackerDistance = Vector3.Distance(MyCamera.Position, attacker.GetPosition());

                if (CurrentBotsAttackingPlayer.Count == MaxBotsAttackingPlayer)
                {
                    if (CurrentBotsAttackingPlayer[CurrentBotsAttackingPlayer.Count - 1].Key <= attackerDistance)
                    {
                        return;
                    }

                    for (int i = 0; i < CurrentBotsAttackingPlayer.Count; i++)
                    {
                        var pair = CurrentBotsAttackingPlayer[i];

                        if (attackerDistance < pair.Key)
                        {
                            CurrentBotsAttackingPlayer.RemoveAt(i);
                            break;
                        }
                    }
                }

                CurrentBotsAttackingPlayer.Add(new KeyValuePair <float, MySmallShipBot>(attackerDistance, attacker));
                CurrentBotsAttackingPlayer.Sort(Compare);
            }

            System.Diagnostics.Debug.Assert(CurrentBotsAttackingPlayer.Count <= MaxBotsAttackingPlayer);
        }
コード例 #32
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (ShouldFallAsleep(bot))
            {
                bot.IsSleeping = true;
                return;
            }

            if (timeToGoalChange <= 0)
            {
                UpdateGoals(bot);
                timeToGoalChange = MyMwcUtils.GetRandomFloat(CHANGE_TIME_MIN, CHANGE_TIME_MAX);
            }
            else
            {
                timeToGoalChange -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }

            bot.Move(bot.GetPosition(), lookTarget, baseMatrix.Up, false, slowRotation: true);
        }
コード例 #33
0
 private Vector3 GetTargetPositionByDamageRatio(MySmallShipBot bot)         
 {
     Vector3 targetPos = m_target.GetPosition();
     if (MySession.PlayerShip != null && MyFactions.GetFactionsRelation(bot, MySession.PlayerShip) == MyFactionRelationEnum.Enemy)
     {
         Vector3 botPos = bot.GetPosition();
         Vector3 botToTarget = targetPos - botPos;
         Vector3 dir = Vector3.Normalize(botToTarget);                
         float degrees = (float)Math.Pow(120, bot.GetDamageRatio() * 1.5 - 1.2) * 4f;
         float deviatingAngle = MathHelper.ToRadians(degrees);
         dir = MyUtilRandomVector3ByDeviatingVector.GetRandom(dir, deviatingAngle);
         targetPos = botPos + botToTarget.Length() * dir * 3;                
     }
     return targetPos;
 }
コード例 #34
0
 bool TrySwitchToAttackSearch(MySmallShipBot bot)
 {
     Vector3 newFlyToTarget = m_target.WorldVolume.Center
         + m_target.WorldMatrix.Forward * (MyMwcUtils.GetRandomFloat(ATTACK_DISTANCE_MIN, ATTACK_DISTANCE_MAX) + m_target.WorldVolume.Radius)
         + m_target.WorldMatrix.Up * MyMwcUtils.GetRandomFloat(-50, 50)
         + m_target.WorldMatrix.Left * MyMwcUtils.GetRandomFloat(-50, 50);
     if (bot.TryTestPosition(newFlyToTarget, bot.GetPosition()))
     {
         m_state = StateEnum.ATACKING_SEARCHING;
         return true;
     }
     return false;
 }
コード例 #35
0
 private void ResetStuck(MySmallShipBot bot)
 {
     stuckPosition = bot.GetPosition();
     stuckTimer    = 0;
 }
コード例 #36
0
 private void ResetStuck(MySmallShipBot bot)
 {
     stuckPosition = bot.GetPosition();
     stuckTimer = 0;
 }
コード例 #37
0
        private void AttackTarget(MySmallShipBot bot, bool targetVisible)
        {
            Vector3 botToTarget = m_target.WorldVolume.Center - bot.GetPosition();
            float distance = botToTarget.Length() - m_target.WorldVolume.Radius;
            Vector3 botToTargetDirection = botToTarget / distance;
            float angleToTarget = (float)Math.Acos(MathHelper.Clamp(Vector3.Dot(bot.WorldMatrix.Forward, botToTargetDirection), -1, 1));

            switch (m_state)
            {
                case StateEnum.CLOSING:
                    if (distance > MANEUVERING_RANGE || m_forcedClosingTimer > 0)
                    {
                        bot.Move(GetTargetPositionByDamageRatio(bot), m_target.GetPosition(), GetUpPlane(), true);                        
                        m_closingTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                        m_forcedClosingTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                        if (distance < FIRING_RANGE_MAX)
                        {
                            HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                        }

                        if (m_closingTimer >= CLOSING_FORMATION_TIME)
                        {
                            SwitchToClosingInFormation();
                        }
                    }
                    else
                    {
                        SwitchToAttack(bot);
                    }

                    break;
                case StateEnum.CLOSING_IN_FORMATION:
                    if (distance > MANEUVERING_RANGE || m_forcedClosingTimer > 0)
                    {
                        Vector3 formationTarget = MyAttackFormations.Instance.GetFormationPosition(bot, m_target);
                        m_closingTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                        m_forcedClosingTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                        
                        if (distance < FIRING_RANGE_MAX)
                        {
                            bot.Move(formationTarget, m_target.GetPosition(), GetUpPlane(), true);
                            HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                        }
                        else
	                    {
                            bot.Move(formationTarget, formationTarget, GetUpPlane(), true);
	                    }
                    }
                    else
                    {
                        MyAttackFormations.Instance.RemoveEntity(bot);
                        SwitchToAttack(bot);
                    }

                    if (distance < FIRING_RANGE_MAX)
                    {
                        HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                    }
                    break;
                case StateEnum.FLYING_AROUND:
                    float flyToDistance = Vector3.Distance(bot.GetPosition(), m_flyToTarget);

                    if (m_strafe)
                    {
                        float rspeed = (1.0f - Math.Abs(MathHelper.Clamp(angleToTarget / MathHelper.Pi, -1, 1))) * 900 + 100;

                        //bot.Move(m_flyToTarget, m_target.GetPosition(), GetUpPlane(), false, customDamping: 0.35f,
                        //    rotationSpeed: rspeed);
                        bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, customDamping: 0.35f,
                            rotationSpeed: rspeed);
                    }
                    else
                    {
                        float factor = MathHelper.Clamp(flyToDistance / 20, 0.15f, 0.45f);
                        //factor = factor * factor * factor;
                        bot.Move(m_flyToTarget, m_flyToTarget, GetUpPlane(), false, 1, 5, factor, slowRotation: true);
                    }

                    HandleShooting(bot, distance, angleToTarget, targetVisible);

                    if (flyToDistance < 10 || m_flyAroundTimer < 0)
                    {
                        if (distance > MANEUVERING_RANGE)
                        {
                            SwitchToClosing();
                        }
                        else
                        {
                            SwitchToAttack(bot);
                        }
                    }

                    m_flyAroundTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    break;
                case StateEnum.ATTACKING:
                    // Handle hologram target, if bot is atacking hologram for 5 seconds he will get it's a hologram
                    MySmallShip smallShip = m_target as MySmallShip;
                    if (smallShip != null && smallShip.IsHologram)
                    {
                        m_hologramTargetTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                        if (m_hologramTargetTimer > 5.0f)
                        {
                            bot.SpoilHologram(smallShip);
                        }
                    }

                    //bot.Move(bot.GetPosition(), m_target.GetPosition(), GetUpPlane(), false, rotationSpeed: 100);
                    bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, rotationSpeed: 100);                    

                    if (m_attackTimer < 0)
                    {
                        if (distance > MANEUVERING_RANGE)
                        {
                            SwitchToClosing();
                        }
                        else
                        {
                            if (!MyFakes.DISABLE_BOT_MANEUVERING)
                            {
                                TrySwitchToAttackSearch(bot);
                            }
                        }
                    }
                    m_attackTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    HandleShooting(bot, distance, angleToTarget, targetVisible);
                    break;
                case StateEnum.ATACKING_SEARCHING:
                    //bot.Move(bot.GetPosition(), m_target.GetPosition(), GetUpPlane(), false, rotationSpeed: 100);
                    bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, rotationSpeed: 100);

                    TrySwitchToFlyAround(bot);

                    HandleShooting(bot, distance, angleToTarget, targetVisible);
                    break;
            }
        }
コード例 #38
0
        internal bool TrySwitchExploreSearch(MySmallShipBot bot)
        {
            Vector3 flyTo = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 100);

            if (bot.TryTestPosition(flyTo, bot.GetPosition()))
            {
                m_state = CuriousState.EXPLORE_SEARCHING;
                return true;
            }
            return false;
        }
コード例 #39
0
        private void UpdateTargetVisibility(MySmallShipBot bot)
        {
            if (m_target != null && m_visibilityCheckTimer <= 0)
            {
                Debug.Assert(!m_target.Closed);

                MyLine line = new MyLine(bot.GetPosition(), m_target.GetPosition(), true);
                var result = MyEntities.GetIntersectionWithLine(ref line, bot, m_target, true, ignoreChilds: true);
                m_targetVisible = !result.HasValue;
                m_visibilityCheckTimer = 0.25f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
コード例 #40
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (ShouldFallAsleep(bot))
            {
                bot.IsSleeping = true;
                return;
            }

            bool pathChange = m_lastWayPointPath != bot.WaypointPath;

            if (pathChange)
            {
                m_lastWayPointPath     = bot.WaypointPath;
                m_currentWayPointIndex = 0;
            }

            bool cycle = bot.PatrolMode == MyPatrolMode.CYCLE;

            if (bot.WaypointPath != null && !bot.SuspendPatrol && bot.WaypointPath.WayPoints.Count > 0)
            {
                UpdateVisibility(bot, bot.CurrentWaypoint.GetPosition());

                if (!m_targetVisible)
                {
                    findSmallship.Update(bot, bot.CurrentWaypoint);
                    if (findSmallship.PathNotFound)
                    {
                        bot.IsSleeping = true;
                        m_isInvalid    = true;
                    }
                }
                else
                {
                    bool blockedEdgesIdDirty = m_lastBlockedEdgesChangeId != MyWayPoint.BlockedEdgesChangeId;
                    m_path.Clear();
                    using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                    {
                        m_path.AddRange(bot.WaypointPath.CompletePath(MyWayPoint.BlockedEdgesForBots, bot.CurrentWaypoint, false, cycle, !blockedEdgesIdDirty));
                    }
                    m_lastBlockedEdgesChangeId = MyWayPoint.BlockedEdgesChangeId;

                    if (blockedEdgesIdDirty)
                    {
                        if (bot.CurrentWaypoint == null)
                        {
                            m_currentWayPointIndex = 0;
                        }
                        else
                        {
                            m_currentWayPointIndex = m_path.IndexOf(bot.CurrentWaypoint);
                        }
                    }

                    // no path found
                    if (m_currentWayPointIndex == -1)
                    {
                        return;
                    }

                    bot.CurrentWaypoint = m_path[m_currentWayPointIndex];

                    if (Vector3.DistanceSquared(bot.GetPosition(), bot.CurrentWaypoint.GetPosition()) <= WAYPOINT_NEAR_DISTANCE_SQR)
                    {
                        if (bot.CurrentWaypoint.EntityId != null && m_lastWayPoint != bot.CurrentWaypoint)
                        {
                            m_lastWayPoint = bot.CurrentWaypoint;

                            MyScriptWrapper.BotReachedWaypoint(bot, bot.CurrentWaypoint);
                        }
                        //++processedWaypoints;

                        int count = m_path.Count;
                        switch (bot.PatrolMode)
                        {
                        case MyPatrolMode.CYCLE:
                            //bot.CurrentWaypointIndex = processedWaypoints % count;
                            m_currentWayPointIndex++;
                            if (m_currentWayPointIndex >= count)
                            {
                                m_currentWayPointIndex = 0;
                            }
                            break;

                        case MyPatrolMode.PING_PONG:
                            if (count > 1)
                            {
                                //bot.CurrentWaypointIndex = processedWaypoints % (count * 2 - 2);
                                //if (bot.CurrentWaypointIndex >= count)
                                //{
                                //    bot.CurrentWaypointIndex = (count * 2 - 2) - bot.CurrentWaypointIndex;
                                //}
                                if (m_forward)
                                {
                                    if (m_currentWayPointIndex < count - 1)
                                    {
                                        m_currentWayPointIndex++;
                                    }
                                    else
                                    {
                                        m_currentWayPointIndex--;
                                        m_forward = false;
                                    }
                                }
                                else
                                {
                                    if (m_currentWayPointIndex > 0)
                                    {
                                        m_currentWayPointIndex--;
                                    }
                                    else
                                    {
                                        m_currentWayPointIndex++;
                                        m_forward = true;
                                    }
                                }
                            }
                            else
                            {
                                m_currentWayPointIndex = 0;
                            }
                            break;

                        case MyPatrolMode.ONE_WAY:
                            if (m_currentWayPointIndex < m_path.Count - 1)
                            {
                                ++m_currentWayPointIndex;
                            }
                            break;
                        }

                        bot.CurrentWaypoint = m_path[m_currentWayPointIndex];
                    }

                    bot.Move(bot.CurrentWaypoint.GetPosition(), bot.CurrentWaypoint.GetPosition(), GetUpPlane(), false);
                    findSmallship.Init(bot);
                }
            }
        }
コード例 #41
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            m_targetVisibleTime += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

            //No need to have this here, because it runs on main thread
            //lock (MyEntities.EntityCloseLock)
            {
                UpdateTargetVisibility(bot);

                if (m_targetVisible && m_target != null)
                {
                    // If target is visible long enough, attack is initiated, this also happens when target is too close or target shoots
                    MySmallShip smallShip = m_target as MySmallShip;
                    if (m_targetVisibleTime > DISCOVER_TIME || 
                        (m_target.GetPosition() - bot.GetPosition()).LengthSquared() < IDENTIFY_DISTANCE_SQR ||
                        (smallShip != null && smallShip.Weapons != null && smallShip.Weapons.IsShooting()))
                    {
                        bot.AddSeenEnemy(m_target);
                        m_state = CuriousState.FINISHED;
                        return;
                    }
                }
            }

            switch (m_state)
            {
                // First stage - goto location
                case CuriousState.GOTO:
                    m_gotoLocationHelper.Update(bot);
                    
                    if (m_gotoLocationHelper.PathNotFound || Vector3.DistanceSquared(bot.GetPosition(), m_location) < LOCATION_NEAR_DISTANCE_SQR)
                    {
                        TrySwitchExploreSearch(bot);
                    }
                    break;
                
                // Second stage - try explore area
                case CuriousState.EXPLORE:
                    m_explorationTime += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    m_exploreTargetTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    if (m_explorationTime > EXPLORATION_TIME)
                    {
                        m_state = CuriousState.FINISHED;
                    }
                    else if (m_exploreTargetTimer <= 0)
                    {
                        TrySwitchExploreSearch(bot);
                    }
                    else
                    {
                        float factor = MathHelper.Clamp((m_exploreTarget - bot.GetPosition()).Length() / 20, 0.15f, 0.45f);
                        bot.Move(m_exploreTarget, m_exploreTarget, GetUpPlane(bot), false, 1, 5, factor, slowRotation: true); 
                    }
                    
                    break;

                // Paralel searching for new explore location
                case CuriousState.EXPLORE_SEARCHING:
                    TrySwitchToExplore(bot);
                    
                    if (m_explorationTime > EXPLORATION_TIME)
                    {
                        m_state = CuriousState.FINISHED;
                    }
                    break;

                // Third stage - nothing interesting was found (IsInvalid is true)
                case CuriousState.FINISHED:
                default:
                    break;
            }
        }
コード例 #42
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            m_targetVisibleTime += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

            //No need to have this here, because it runs on main thread
            //lock (MyEntities.EntityCloseLock)
            {
                UpdateTargetVisibility(bot);

                if (m_targetVisible && m_target != null)
                {
                    // If target is visible long enough, attack is initiated, this also happens when target is too close or target shoots
                    MySmallShip smallShip = m_target as MySmallShip;
                    if (m_targetVisibleTime > DISCOVER_TIME ||
                        (m_target.GetPosition() - bot.GetPosition()).LengthSquared() < IDENTIFY_DISTANCE_SQR ||
                        (smallShip != null && smallShip.Weapons != null && smallShip.Weapons.IsShooting()))
                    {
                        bot.AddSeenEnemy(m_target);
                        m_state = CuriousState.FINISHED;
                        return;
                    }
                }
            }

            switch (m_state)
            {
            // First stage - goto location
            case CuriousState.GOTO:
                m_gotoLocationHelper.Update(bot);

                if (m_gotoLocationHelper.PathNotFound || Vector3.DistanceSquared(bot.GetPosition(), m_location) < LOCATION_NEAR_DISTANCE_SQR)
                {
                    TrySwitchExploreSearch(bot);
                }
                break;

            // Second stage - try explore area
            case CuriousState.EXPLORE:
                m_explorationTime    += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                m_exploreTargetTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                if (m_explorationTime > EXPLORATION_TIME)
                {
                    m_state = CuriousState.FINISHED;
                }
                else if (m_exploreTargetTimer <= 0)
                {
                    TrySwitchExploreSearch(bot);
                }
                else
                {
                    float factor = MathHelper.Clamp((m_exploreTarget - bot.GetPosition()).Length() / 20, 0.15f, 0.45f);
                    bot.Move(m_exploreTarget, m_exploreTarget, GetUpPlane(bot), false, 1, 5, factor, slowRotation: true);
                }

                break;

            // Paralel searching for new explore location
            case CuriousState.EXPLORE_SEARCHING:
                TrySwitchToExplore(bot);

                if (m_explorationTime > EXPLORATION_TIME)
                {
                    m_state = CuriousState.FINISHED;
                }
                break;

            // Third stage - nothing interesting was found (IsInvalid is true)
            case CuriousState.FINISHED:
            default:
                break;
            }
        }
コード例 #43
0
        /// <summary>
        /// Returns if bot can see target. If bot's fov is enabled and target is smallship which has radar jammer, then bot can see only targets in front of him
        /// </summary>
        /// <param name="target">Target</param>
        private bool CanSeeTarget(MySmallShipBot me, MyEntity target) 
        {
            bool canSeeTarget = true;
            if (MyFakes.ENABLE_BOTS_FOV_WHEN_RADAR_JAMMER)
            {
                MySmallShip smallShipTarget = target as MySmallShip;
                if (smallShipTarget != null && !smallShipTarget.IsHologram && smallShipTarget.HasRadarJammerActive()) 
                {
                    float distanceSqr = (me.GetPosition() - target.GetPosition()).LengthSquared();
                    float rangeOfViewSqr = smallShipTarget.IsHiddenFromBots() ? MyAIConstants.BOT_FOV_RANGE_HIDDEN : MyAIConstants.BOT_FOV_RANGE;
                    float targetRange = Vector3.Dot(m_botWorldMatrix.Forward, target.GetPosition() - me.GetPosition());

                    canSeeTarget =
                        targetRange <= rangeOfViewSqr &&
                        Vector3.Dot(m_botWorldMatrix.Forward, Vector3.Normalize(target.GetPosition() - m_position)) >= MyAIConstants.BOT_FOV_COS;
                }                
            }
            return canSeeTarget;
        }
コード例 #44
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (bot.Leader != null)
            {
                if (ShouldFallAsleep(bot))
                {
                    bot.IsSleeping = true;
                    return;
                }

                Vector3 leaderToBot = bot.GetPosition() - bot.Leader.GetPosition();
                Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot);
                Vector3 botToFormationPosition = formationPositionActual - bot.GetPosition();

                float leaderDistance = leaderToBot.Length();
                float formationPositionDistance = botToFormationPosition.Length();

                Vector3 flyTo;
                if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON)
                {
                    float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20;
                    flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance;
                    flyTo = MyMwcUtils.Normalize(flyTo);
                    flyTo = bot.GetPosition() + flyTo * formationPositionDistance;

                    // Update leader visibility
                    if (visibilityCheckTimer <= 0)
                    {
                        MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true);
                        leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue;

                        visibilityCheckTimer = 0.5f;
                    }
                    else
                    {
                        visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    }
                }
                else
                {
                    // Bot is on formation position
                    flyTo = bot.GetPosition() + bot.WorldMatrix.Forward;
                    leaderVisible = true;
                }
                 
                if (leaderVisible)
                {
                    bool afterburner = /*bot.Leader.IsAfterburnerOn() || */formationPositionDistance > AFTERBURNER_DISTANCE;
                    Vector3 lookTarget = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual;

                    float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f);

                    factor = factor * factor * factor;

                    bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true);

                    checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    findSmallship.Init(bot);
                }
                else
                {
                    if (leaderDistance > MIN_LEADER_DISTANCE)
                    {
                        findSmallship.Update(bot, bot.Leader);

                        if (findSmallship.PathNotFound)
                        {
							//We dont want our friends sleeping elsewhere
                          //  bot.IsSleeping = true;
                        }
                    }
                }
            }
        }
コード例 #45
0
 private void UpdateTargetVisibility(MySmallShipBot bot)
 {
     if (locationVisibleCheckTimer <= 0)
     {
         MyLine line = new MyLine(bot.GetPosition(), location, true);
         var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
         locationVisible = !result.HasValue;
         locationVisibleCheckTimer = 0.25f;
     }
     else
     {
         locationVisibleCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
     }
 }
コード例 #46
0
 void UpdateGoals(MySmallShipBot bot)
 {
     lookTarget = bot.GetPosition() + baseMatrix.Forward * 50 + baseMatrix.Right * MyMwcUtils.GetRandomFloat(-50, 50) + baseMatrix.Up * MyMwcUtils.GetRandomFloat(-50, 50);
 }
コード例 #47
0
        internal override void Init(MySmallShipBot bot)
        {
            base.Init(bot);
            
            m_isInvalid = false;
            m_target = SourceDesire.GetEnemy();
            if (m_target != null)
            {
                Debug.Assert(m_target != bot);
            }
            findSmallship = new MyFindSmallshipHelper();

            m_visibilityCheckTimer = 0;       // force visibility test
            m_closingTimer = 0;
            m_forcedClosingTimer = 0;
            m_hologramTargetTimer = 0;

            SwitchToClosing();
            
            PlanNextMissile();

            m_timeToAlarmCheck = 2;
            
            m_playerAttackDecisionTimer = 0;

            MyScriptWrapper.OnEntityAttackedByBot(bot, m_target);

            m_canShootWithAutocanon = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Primary);
            m_canShootWithShotGun = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Secondary);
            m_canShootWithSniper = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Third);
            m_canShootMissile = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Fourth);
            m_canShootCannon = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.Fifth);

            m_canShootFlash = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.FlashBombFront) && MyFakes.BOT_USE_FLASH_BOMBS;
            m_canShootSmoke = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.SmokeBombFront) && MyFakes.BOT_USE_SMOKE_BOMBS;
            m_canShootHologram = bot.CanShootWith(MyMwcObjectBuilder_FireKeyEnum.HologramFront) && MyFakes.BOT_USE_HOLOGRAMS;

            m_weaponChangeTimer = 0;
            m_currentWeapon = SelectWeapon((bot.GetPosition() - m_target.GetPosition()).Length());

            m_smokeBombTimer = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
            m_flashBombTimer = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
            m_hologramTimer = MyMwcUtils.GetRandomFloat(0.5f, 3.0f);
        }
コード例 #48
0
        public static void AddAttacker(MySmallShipBot attacker, MyEntity target)
        {
            if (MySession.IsPlayerShip(target))
            {
                foreach (var pair in CurrentBotsAttackingPlayer)
                {
                    if (pair.Value == attacker)
                        return;
                }

                float attackerDistance = Vector3.Distance(MyCamera.Position, attacker.GetPosition());

                if (CurrentBotsAttackingPlayer.Count == MaxBotsAttackingPlayer)
                {
                    if (CurrentBotsAttackingPlayer[CurrentBotsAttackingPlayer.Count - 1].Key <= attackerDistance)
                        return;

                    for (int i = 0; i < CurrentBotsAttackingPlayer.Count; i++ )
                    {
                        var pair = CurrentBotsAttackingPlayer[i];

                        if (attackerDistance < pair.Key)
                        {
                            CurrentBotsAttackingPlayer.RemoveAt(i);
                            break;
                        }
                    }
                }

                CurrentBotsAttackingPlayer.Add(new KeyValuePair<float, MySmallShipBot>(attackerDistance, attacker));
                CurrentBotsAttackingPlayer.Sort(Compare);
            }

            System.Diagnostics.Debug.Assert(CurrentBotsAttackingPlayer.Count <= MaxBotsAttackingPlayer);
        }
コード例 #49
0
        private void UpdateVisibility(MySmallShipBot bot, Vector3 targetPosition)
        {
            if (m_visibilityCheckTimer <= 0)
            {
                if (bot.GetPosition() == targetPosition)
                {
                    m_targetVisible = true;


                }
                else
                {
                    MyLine line = new MyLine(bot.GetPosition(), targetPosition, true);
                    var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
                    m_targetVisible = !result.HasValue;
                }

                m_visibilityCheckTimer = 0.5f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
コード例 #50
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (ShouldFallAsleep(bot))
            {
                bot.IsSleeping = true;
                return;
            }

            bool pathChange = m_lastWayPointPath != bot.WaypointPath;
            if (pathChange) 
            {
                m_lastWayPointPath = bot.WaypointPath;
                m_currentWayPointIndex = 0;
            }

            bool cycle = bot.PatrolMode == MyPatrolMode.CYCLE;

            if (bot.WaypointPath != null && !bot.SuspendPatrol && bot.WaypointPath.WayPoints.Count > 0)
            {
                UpdateVisibility(bot, bot.CurrentWaypoint.GetPosition());

                if (!m_targetVisible)
                {
                    findSmallship.Update(bot, bot.CurrentWaypoint);
                    if (findSmallship.PathNotFound)
                    {
                        bot.IsSleeping = true;
                        m_isInvalid = true;
                    }
                }
                else
                {
                    bool blockedEdgesIdDirty = m_lastBlockedEdgesChangeId != MyWayPoint.BlockedEdgesChangeId;
                    m_path.Clear();
                    using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                    {
                        m_path.AddRange(bot.WaypointPath.CompletePath(MyWayPoint.BlockedEdgesForBots, bot.CurrentWaypoint, false, cycle, !blockedEdgesIdDirty));
                    }
                    m_lastBlockedEdgesChangeId = MyWayPoint.BlockedEdgesChangeId;

                    if (blockedEdgesIdDirty)
                    {
                        if (bot.CurrentWaypoint == null)
                        {
                            m_currentWayPointIndex = 0;
                        }
                        else
                        {
                            m_currentWayPointIndex = m_path.IndexOf(bot.CurrentWaypoint);
                        }
                    }

                    // no path found
                    if (m_currentWayPointIndex == -1)
                    {
                        return;
                    }

                    bot.CurrentWaypoint = m_path[m_currentWayPointIndex];

                    if (Vector3.DistanceSquared(bot.GetPosition(), bot.CurrentWaypoint.GetPosition()) <= WAYPOINT_NEAR_DISTANCE_SQR)
                    {
                        if (bot.CurrentWaypoint.EntityId != null && m_lastWayPoint != bot.CurrentWaypoint)
                        {
                            m_lastWayPoint = bot.CurrentWaypoint;

                            MyScriptWrapper.BotReachedWaypoint(bot, bot.CurrentWaypoint);
                        }
                        //++processedWaypoints;

                        int count = m_path.Count;
                        switch (bot.PatrolMode)
                        {
                            case MyPatrolMode.CYCLE:
                                //bot.CurrentWaypointIndex = processedWaypoints % count;
                                m_currentWayPointIndex++;
                                if (m_currentWayPointIndex >= count)
                                {
                                    m_currentWayPointIndex = 0;
                                }
                                break;
                            case MyPatrolMode.PING_PONG:
                                if (count > 1)
                                {
                                    //bot.CurrentWaypointIndex = processedWaypoints % (count * 2 - 2);
                                    //if (bot.CurrentWaypointIndex >= count)
                                    //{
                                    //    bot.CurrentWaypointIndex = (count * 2 - 2) - bot.CurrentWaypointIndex;
                                    //}
                                    if (m_forward)
                                    {
                                        if (m_currentWayPointIndex < count - 1)
                                        {
                                            m_currentWayPointIndex++;
                                        }
                                        else
                                        {
                                            m_currentWayPointIndex--;
                                            m_forward = false;
                                        }
                                    }
                                    else
                                    {
                                        if (m_currentWayPointIndex > 0)
                                        {
                                            m_currentWayPointIndex--;
                                        }
                                        else
                                        {
                                            m_currentWayPointIndex++;
                                            m_forward = true;
                                        }
                                    }
                                }
                                else
                                {
                                    m_currentWayPointIndex = 0;
                                }
                                break;
                            case MyPatrolMode.ONE_WAY:
                                if (m_currentWayPointIndex < m_path.Count - 1)
                                {
                                    ++m_currentWayPointIndex;
                                }
                                break;
                        }

                        bot.CurrentWaypoint = m_path[m_currentWayPointIndex];
                    }

                    bot.Move(bot.CurrentWaypoint.GetPosition(), bot.CurrentWaypoint.GetPosition(), GetUpPlane(), false);
                    findSmallship.Init(bot);
                }
            }
        }
コード例 #51
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (bot.Leader != null)
            {
                if (ShouldFallAsleep(bot))
                {
                    bot.IsSleeping = true;
                    return;
                }

                Vector3 leaderToBot             = bot.GetPosition() - bot.Leader.GetPosition();
                Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot);
                Vector3 botToFormationPosition  = formationPositionActual - bot.GetPosition();

                float leaderDistance            = leaderToBot.Length();
                float formationPositionDistance = botToFormationPosition.Length();

                Vector3 flyTo;
                if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON)
                {
                    float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20;
                    flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance;
                    flyTo = MyMwcUtils.Normalize(flyTo);
                    flyTo = bot.GetPosition() + flyTo * formationPositionDistance;

                    // Update leader visibility
                    if (visibilityCheckTimer <= 0)
                    {
                        MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true);
                        leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue;

                        visibilityCheckTimer = 0.5f;
                    }
                    else
                    {
                        visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    }
                }
                else
                {
                    // Bot is on formation position
                    flyTo         = bot.GetPosition() + bot.WorldMatrix.Forward;
                    leaderVisible = true;
                }

                if (leaderVisible)
                {
                    bool    afterburner = /*bot.Leader.IsAfterburnerOn() || */ formationPositionDistance > AFTERBURNER_DISTANCE;
                    Vector3 lookTarget  = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual;

                    float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f);

                    factor = factor * factor * factor;

                    bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true);

                    checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    findSmallship.Init(bot);
                }
                else
                {
                    if (leaderDistance > MIN_LEADER_DISTANCE)
                    {
                        findSmallship.Update(bot, bot.Leader);

                        if (findSmallship.PathNotFound)
                        {
                            //We dont want our friends sleeping elsewhere
                            //  bot.IsSleeping = true;
                        }
                    }
                }
            }
        }
コード例 #52
0
        private void AttackTarget(MySmallShipBot bot, bool targetVisible)
        {
            Vector3 botToTarget          = m_target.WorldVolume.Center - bot.GetPosition();
            float   distance             = botToTarget.Length() - m_target.WorldVolume.Radius;
            Vector3 botToTargetDirection = botToTarget / distance;
            float   angleToTarget        = (float)Math.Acos(MathHelper.Clamp(Vector3.Dot(bot.WorldMatrix.Forward, botToTargetDirection), -1, 1));

            switch (m_state)
            {
            case StateEnum.CLOSING:
                if (distance > MANEUVERING_RANGE || m_forcedClosingTimer > 0)
                {
                    bot.Move(GetTargetPositionByDamageRatio(bot), m_target.GetPosition(), GetUpPlane(), true);
                    m_closingTimer       += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    m_forcedClosingTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    if (distance < FIRING_RANGE_MAX)
                    {
                        HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                    }

                    if (m_closingTimer >= CLOSING_FORMATION_TIME)
                    {
                        SwitchToClosingInFormation();
                    }
                }
                else
                {
                    SwitchToAttack(bot);
                }

                break;

            case StateEnum.CLOSING_IN_FORMATION:
                if (distance > MANEUVERING_RANGE || m_forcedClosingTimer > 0)
                {
                    Vector3 formationTarget = MyAttackFormations.Instance.GetFormationPosition(bot, m_target);
                    m_closingTimer       += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    m_forcedClosingTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    if (distance < FIRING_RANGE_MAX)
                    {
                        bot.Move(formationTarget, m_target.GetPosition(), GetUpPlane(), true);
                        HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                    }
                    else
                    {
                        bot.Move(formationTarget, formationTarget, GetUpPlane(), true);
                    }
                }
                else
                {
                    MyAttackFormations.Instance.RemoveEntity(bot);
                    SwitchToAttack(bot);
                }

                if (distance < FIRING_RANGE_MAX)
                {
                    HandleShooting(bot, distance, angleToTarget, m_targetVisible);
                }
                break;

            case StateEnum.FLYING_AROUND:
                float flyToDistance = Vector3.Distance(bot.GetPosition(), m_flyToTarget);

                if (m_strafe)
                {
                    float rspeed = (1.0f - Math.Abs(MathHelper.Clamp(angleToTarget / MathHelper.Pi, -1, 1))) * 900 + 100;

                    //bot.Move(m_flyToTarget, m_target.GetPosition(), GetUpPlane(), false, customDamping: 0.35f,
                    //    rotationSpeed: rspeed);
                    bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, customDamping: 0.35f,
                             rotationSpeed: rspeed);
                }
                else
                {
                    float factor = MathHelper.Clamp(flyToDistance / 20, 0.15f, 0.45f);
                    //factor = factor * factor * factor;
                    bot.Move(m_flyToTarget, m_flyToTarget, GetUpPlane(), false, 1, 5, factor, slowRotation: true);
                }

                HandleShooting(bot, distance, angleToTarget, targetVisible);

                if (flyToDistance < 10 || m_flyAroundTimer < 0)
                {
                    if (distance > MANEUVERING_RANGE)
                    {
                        SwitchToClosing();
                    }
                    else
                    {
                        SwitchToAttack(bot);
                    }
                }

                m_flyAroundTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                break;

            case StateEnum.ATTACKING:
                // Handle hologram target, if bot is atacking hologram for 5 seconds he will get it's a hologram
                MySmallShip smallShip = m_target as MySmallShip;
                if (smallShip != null && smallShip.IsHologram)
                {
                    m_hologramTargetTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    if (m_hologramTargetTimer > 5.0f)
                    {
                        bot.SpoilHologram(smallShip);
                    }
                }

                //bot.Move(bot.GetPosition(), m_target.GetPosition(), GetUpPlane(), false, rotationSpeed: 100);
                bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, rotationSpeed: 100);

                if (m_attackTimer < 0)
                {
                    if (distance > MANEUVERING_RANGE)
                    {
                        SwitchToClosing();
                    }
                    else
                    {
                        if (!MyFakes.DISABLE_BOT_MANEUVERING)
                        {
                            TrySwitchToAttackSearch(bot);
                        }
                    }
                }
                m_attackTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                HandleShooting(bot, distance, angleToTarget, targetVisible);
                break;

            case StateEnum.ATACKING_SEARCHING:
                //bot.Move(bot.GetPosition(), m_target.GetPosition(), GetUpPlane(), false, rotationSpeed: 100);
                bot.Move(bot.GetPosition(), GetTargetPositionByDamageRatio(bot), GetUpPlane(), false, rotationSpeed: 100);

                TrySwitchToFlyAround(bot);

                HandleShooting(bot, distance, angleToTarget, targetVisible);
                break;
            }
        }