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); } } }
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); } } } }