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);
                }
            }
        }
Пример #2
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;
                        }
                    }
                }
            }
        }
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (m_target != null && !m_target.IsDead())
            {
                MySmallShip         smallShipTarget   = m_target as MySmallShip;
                MyPrefabLargeWeapon largeWeaponTarget = m_target as MyPrefabLargeWeapon;

                if (largeWeaponTarget != null && !largeWeaponTarget.IsWorking())
                {
                    m_isInvalid = true;
                    return;
                }

                if (m_timeToAlarmCheck >= 0)
                {
                    m_timeToAlarmCheck -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    // When transition from curious behavior try raise alarm (if this doesn't work pass some flag curious behavior)
                    if (m_timeToAlarmCheck < 0 && smallShipTarget != null && smallShipTarget.HasRadarJammerActive())
                    {
                        bot.LaunchAlarm(smallShipTarget);
                    }
                }

                UpdateVisibility(bot);

                if (m_targetVisible)
                {
                    AttackTarget(bot, m_targetVisible);
                    findSmallship.Init(bot);

                    // Attack player to prevent his passivity when we have invicible wingmans
                    m_playerAttackDecisionTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    if (smallShipTarget != null && smallShipTarget.Leader == MySession.PlayerShip && m_playerAttackDecisionTimer <= 0)
                    {
                        m_playerAttackDecisionTimer = 2.5f;
                        if (MyMwcUtils.GetRandomFloat(0, 1.0f) < 0.7f)
                        {
                            m_target = smallShipTarget.Leader;
                        }
                    }
                }
                else
                {
                    m_state = StateEnum.CLOSING;

                    findSmallship.Update(bot, m_target);

                    if (findSmallship.PathNotFound)
                    {
                        bot.IsSleeping = true;
                        m_isInvalid    = true;
                    }
                    else if (!findSmallship.GotPosition())
                    {
                        AttackTarget(bot, false);
                    }
                }
            }
        }