void UpdateGoals(MySmallShipBot bot) { moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; up = MyMwcUtils.GetRandomVector3Normalized() * 1000; shoot = MyMwcUtils.GetRandomBool(2); }
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 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); }
internal override void Init(MySmallShipBot bot) { base.Init(bot); baseMatrix = bot.WorldMatrix; lookTarget = bot.GetPosition() + baseMatrix.Forward * 100; }
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); } }
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); } }
public void Init(MySmallShipBot bot) { m_stuckPosition = bot.GetPosition(); m_stuckTimer = 0; m_followPosition = null; m_followPath = null; PathNotFound = false; }
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); } } }
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); }
public void Init(MySmallShipBot bot, Vector3 location) { locationVisibleCheckTimer = 0; stuckPosition = bot.GetPosition(); stuckTimer = 0; PathNotFound = false; this.location = location; currentPathPosition = 0; UpdateTargetVisibility(bot); }
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; }
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; } }
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; } }
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); }
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; } } }
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); }
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 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); }
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; } }
/// <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(" "); } }
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); }
/// <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); }
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(); } }
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); }
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 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; }
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; }
private void ResetStuck(MySmallShipBot bot) { stuckPosition = bot.GetPosition(); stuckTimer = 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; } }
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; }
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); 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; } }
/// <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; }
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; } } } } }
void UpdateGoals(MySmallShipBot bot) { lookTarget = bot.GetPosition() + baseMatrix.Forward * 50 + baseMatrix.Right * MyMwcUtils.GetRandomFloat(-50, 50) + baseMatrix.Up * MyMwcUtils.GetRandomFloat(-50, 50); }
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); }
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; } } } } }