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);
            }
        }
        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;
                }
            }
        }
        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);
            }
        }
        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;
                }
            }
        }
        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);
                }
            }
        }
Beispiel #6
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);
                }
            }
        }
Beispiel #7
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

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

            bot.Move(moveTarget, lookTarget, up, false);
            if (shoot)
            {
                // just some default distance so that bot shoots (legacy shoot method)
                bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.Primary);
            }
        }
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

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

            bot.Move(moveTarget, lookTarget, up, false);
            if (shoot)
            {
                // just some default distance so that bot shoots (legacy shoot method)
                bot.Shoot(MyMwcObjectBuilder_FireKeyEnum.Primary);
            }
        }
        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);
        }
        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;
                }
            }
        }
        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;
                }
            }
        }
        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 (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);
                }
            }
        }
        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;
            }
        }
        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);
                }
            }
        }
Beispiel #16
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;
            }
        }
        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;
            }
        }
 private void FlyToLocation(MySmallShipBot bot)
 {
     bot.Move(location, location, GetUpPlane(bot), false, 1, 2);
 }
 private void FlyToLocation(MySmallShipBot bot)
 {
     bot.Move(location, location, GetUpPlane(bot), false, 1, 2);
 }
Beispiel #20
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;
                        }
                    }
                }
            }
        }
        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;
            }
        }