(18bb55660) Add unreachable targets on the unreachables list. Reset the list when a new combat objective begins. Don't immediately find a new hull target if the current hull is unsafe. Instead wait a sec at max. Fixes #1417.

This commit is contained in:
Joonas Rikkonen
2019-04-15 12:01:48 +03:00
parent cc0e217e82
commit 29f902f0bb
2 changed files with 17 additions and 11 deletions
@@ -44,6 +44,7 @@ namespace Barotrauma
private AIObjectiveContainItem reloadWeaponObjective; private AIObjectiveContainItem reloadWeaponObjective;
private Hull retreatTarget; private Hull retreatTarget;
private AIObjectiveGoTo retreatObjective; private AIObjectiveGoTo retreatObjective;
private AIObjectiveFindSafety findSafety;
private float coolDownTimer; private float coolDownTimer;
@@ -60,7 +61,9 @@ namespace Barotrauma
{ {
Enemy = enemy; Enemy = enemy;
coolDownTimer = CoolDown; coolDownTimer = CoolDown;
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 0; findSafety = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>();
findSafety.Priority = 0;
findSafety.unreachable.Clear();
Mode = mode; Mode = mode;
if (Enemy == null) if (Enemy == null)
{ {
@@ -175,7 +178,7 @@ namespace Barotrauma
{ {
if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted)) if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted))
{ {
retreatTarget = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().FindBestHull(new List<Hull>() { character.CurrentHull }); retreatTarget = findSafety.FindBestHull(new List<Hull>() { character.CurrentHull });
} }
if (retreatTarget != null) if (retreatTarget != null)
{ {
@@ -277,7 +280,6 @@ namespace Barotrauma
{ {
abandon = true; abandon = true;
SteeringManager.Reset(); SteeringManager.Reset();
//HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
} }
public override bool IsCompleted() public override bool IsCompleted()
@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Barotrauma.Extensions;
namespace Barotrauma namespace Barotrauma
{ {
@@ -17,10 +18,7 @@ namespace Barotrauma
const float SearchHullInterval = 3.0f; const float SearchHullInterval = 3.0f;
const float clearUnreachableInterval = 30; const float clearUnreachableInterval = 30;
private readonly List<Hull> targetHulls = new List<Hull>(20); public readonly List<Hull> unreachable = new List<Hull>();
private readonly List<float> hullWeights = new List<float>(20);
private List<Hull> unreachable = new List<Hull>();
private float currenthullSafety; private float currenthullSafety;
private float unreachableClearTimer; private float unreachableClearTimer;
@@ -67,6 +65,11 @@ namespace Barotrauma
} }
} }
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
{
searchHullTimer = Math.Min(1, searchHullTimer);
}
if (unreachableClearTimer > 0) if (unreachableClearTimer > 0)
{ {
unreachableClearTimer -= deltaTime; unreachableClearTimer -= deltaTime;
@@ -190,15 +193,17 @@ namespace Barotrauma
float dist = Math.Abs(character.WorldPosition.X - hull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - hull.WorldPosition.Y) * 2.0f; float dist = Math.Abs(character.WorldPosition.X - hull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - hull.WorldPosition.Y) * 2.0f;
float distanceFactor = MathHelper.Lerp(1, 0.9f, MathUtils.InverseLerp(0, 10000, dist)); float distanceFactor = MathHelper.Lerp(1, 0.9f, MathUtils.InverseLerp(0, 10000, dist));
hullSafety *= distanceFactor; hullSafety *= distanceFactor;
//skip the hull if the safety is already less than the best hull //skip the hull if the safety is already less than the best hull
//(no need to do the expensive pathfinding if we already know we're not going to choose this hull) //(no need to do the expensive pathfinding if we already know we're not going to choose this hull)
if (hullSafety < bestValue) { continue; } if (hullSafety < bestValue) { continue; }
// Each unsafe node reduces the hull safety value. // Each unsafe node reduces the hull safety value.
// Ignore current hull, because otherwise the would block all paths from the current hull to the target hull. // Ignore current hull, because otherwise the would block all paths from the current hull to the target hull.
var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition); var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition);
if (path.Unreachable) { continue; } if (path.Unreachable)
{
unreachable.Add(hull);
continue;
}
int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull)); int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull));
hullSafety /= 1 + unsafeNodes; hullSafety /= 1 + unsafeNodes;
// If the target is not inside a friendly submarine, considerably reduce the hull safety. // If the target is not inside a friendly submarine, considerably reduce the hull safety.
@@ -226,7 +231,6 @@ namespace Barotrauma
} }
} }
} }
// Huge preference for closer targets // Huge preference for closer targets
float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition); float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition);
float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance)); float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance));