(e0d673b0d) Test: Don't calculate the distance to the buttons when seeking path. Instead, check the distance when checking the doors. Allows the bots to access the Remora ballast through the door where the button is a bit farther from the door than usually.
This commit is contained in:
+77
-116
@@ -10,7 +10,6 @@ namespace Barotrauma
|
||||
{
|
||||
public override string DebugTag => "find safety";
|
||||
public override bool ForceRun => true;
|
||||
public override bool KeepDivingGearOn => true;
|
||||
|
||||
// TODO: expose?
|
||||
const float priorityIncrease = 25;
|
||||
@@ -18,7 +17,7 @@ namespace Barotrauma
|
||||
const float SearchHullInterval = 3.0f;
|
||||
const float clearUnreachableInterval = 30;
|
||||
|
||||
public readonly List<Hull> unreachable = new List<Hull>();
|
||||
public readonly HashSet<Hull> unreachable = new HashSet<Hull>();
|
||||
|
||||
private float currenthullSafety;
|
||||
private float unreachableClearTimer;
|
||||
@@ -27,49 +26,15 @@ namespace Barotrauma
|
||||
private AIObjectiveGoTo goToObjective;
|
||||
private AIObjectiveFindDivingGear divingGearObjective;
|
||||
|
||||
public AIObjectiveFindSafety(Character character) : base(character, "") { }
|
||||
public AIObjectiveFindSafety(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { }
|
||||
|
||||
public override bool IsCompleted() => false;
|
||||
public override bool CanBeCompleted => true;
|
||||
|
||||
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFindSafety;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
var currentHull = character.AnimController.CurrentHull;
|
||||
if (HumanAIController.NeedsDivingGear(currentHull) && divingGearObjective == null)
|
||||
{
|
||||
bool needsDivingSuit = currentHull == null || currentHull.WaterPercentage > 90;
|
||||
bool hasEquipment = needsDivingSuit ? HumanAIController.HasDivingSuit(character) : HumanAIController.HasDivingGear(character);
|
||||
if (!hasEquipment)
|
||||
{
|
||||
divingGearObjective = new AIObjectiveFindDivingGear(character, needsDivingSuit);
|
||||
}
|
||||
}
|
||||
if (divingGearObjective != null)
|
||||
{
|
||||
divingGearObjective.TryComplete(deltaTime);
|
||||
if (divingGearObjective.IsCompleted())
|
||||
{
|
||||
divingGearObjective = null;
|
||||
Priority = 0;
|
||||
}
|
||||
else if (divingGearObjective.CanBeCompleted)
|
||||
{
|
||||
// If diving gear objective is active and can be completed, wait for it to complete.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
divingGearObjective = null;
|
||||
// Reduce the timer so that we get a safe hull target faster.
|
||||
searchHullTimer = Math.Min(1, searchHullTimer);
|
||||
}
|
||||
}
|
||||
|
||||
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
|
||||
{
|
||||
searchHullTimer = Math.Min(1, searchHullTimer);
|
||||
}
|
||||
|
||||
if (unreachableClearTimer > 0)
|
||||
{
|
||||
unreachableClearTimer -= deltaTime;
|
||||
@@ -79,56 +44,86 @@ namespace Barotrauma
|
||||
unreachableClearTimer = clearUnreachableInterval;
|
||||
unreachable.Clear();
|
||||
}
|
||||
|
||||
if (searchHullTimer > 0.0f)
|
||||
{
|
||||
unreachableClearTimer = clearUnreachableInterval;
|
||||
unreachable.Clear();
|
||||
}
|
||||
if (character.CurrentHull == null)
|
||||
{
|
||||
var bestHull = FindBestHull();
|
||||
if (bestHull != null && bestHull != currentHull)
|
||||
{
|
||||
if (goToObjective != null)
|
||||
{
|
||||
if (goToObjective.Target != bestHull)
|
||||
{
|
||||
// If we need diving gear, we should already have it, if possible.
|
||||
goToObjective = new AIObjectiveGoTo(bestHull, character, getDivingGearIfNeeded: false)
|
||||
{
|
||||
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goToObjective = new AIObjectiveGoTo(bestHull, character, getDivingGearIfNeeded: false)
|
||||
{
|
||||
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
|
||||
};
|
||||
}
|
||||
}
|
||||
searchHullTimer = SearchHullInterval;
|
||||
currenthullSafety = 0;
|
||||
Priority = 100;
|
||||
return;
|
||||
}
|
||||
if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { Priority = 100; }
|
||||
currenthullSafety = HumanAIController.GetHullSafety(character.CurrentHull);
|
||||
if (currenthullSafety > HumanAIController.HULL_SAFETY_THRESHOLD)
|
||||
{
|
||||
goToObjective.TryComplete(deltaTime);
|
||||
if (!goToObjective.CanBeCompleted)
|
||||
{
|
||||
if (!unreachable.Contains(goToObjective.Target))
|
||||
{
|
||||
unreachable.Add(goToObjective.Target as Hull);
|
||||
}
|
||||
goToObjective = null;
|
||||
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
|
||||
//SteeringManager.SteeringWander();
|
||||
}
|
||||
Priority -= priorityDecrease * deltaTime;
|
||||
}
|
||||
else if (currentHull != null)
|
||||
else
|
||||
{
|
||||
float dangerFactor = (100 - currenthullSafety) / 100;
|
||||
Priority += dangerFactor * priorityIncrease * deltaTime;
|
||||
}
|
||||
Priority = MathHelper.Clamp(Priority, 0, 100);
|
||||
if (divingGearObjective != null && !divingGearObjective.IsCompleted() && divingGearObjective.CanBeCompleted)
|
||||
{
|
||||
Priority = Math.Max(Priority, Math.Min(AIObjectiveManager.OrderPriority + 20, 100));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Act(float deltaTime)
|
||||
{
|
||||
var currentHull = character.AnimController.CurrentHull;
|
||||
bool needsDivingGear = HumanAIController.NeedsDivingGear(currentHull);
|
||||
bool needsDivingSuit = needsDivingGear && (currentHull == null || currentHull.WaterPercentage > 90);
|
||||
bool needsEquipment = false;
|
||||
if (needsDivingSuit)
|
||||
{
|
||||
needsEquipment = !HumanAIController.HasDivingSuit(character);
|
||||
}
|
||||
else if (needsDivingGear)
|
||||
{
|
||||
needsEquipment = !HumanAIController.HasDivingMask(character);
|
||||
}
|
||||
if (needsEquipment)
|
||||
{
|
||||
TryAddSubObjective(ref divingGearObjective,
|
||||
() => new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager),
|
||||
onAbandon: () => searchHullTimer = Math.Min(1, searchHullTimer));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (divingGearObjective != null && divingGearObjective.IsCompleted())
|
||||
{
|
||||
// Reset the devotion.
|
||||
Priority = 0;
|
||||
divingGearObjective = null;
|
||||
}
|
||||
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
|
||||
{
|
||||
searchHullTimer = Math.Min(1, searchHullTimer);
|
||||
}
|
||||
if (searchHullTimer > 0.0f)
|
||||
{
|
||||
searchHullTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
searchHullTimer = SearchHullInterval;
|
||||
var bestHull = FindBestHull();
|
||||
if (bestHull != null && bestHull != currentHull)
|
||||
{
|
||||
if (goToObjective?.Target != bestHull)
|
||||
{
|
||||
goToObjective = null;
|
||||
}
|
||||
TryAddSubObjective(ref goToObjective, () =>
|
||||
new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
|
||||
{
|
||||
// If we need diving gear, we should already have it, if possible.
|
||||
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
|
||||
}, onAbandon: () => unreachable.Add(goToObjective.Target as Hull));
|
||||
}
|
||||
}
|
||||
if (goToObjective != null) { return; }
|
||||
if (currentHull == null) { return; }
|
||||
//goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found)
|
||||
// -> attempt to manually steer away from hazards
|
||||
Vector2 escapeVel = Vector2.Zero;
|
||||
@@ -136,17 +131,15 @@ namespace Barotrauma
|
||||
{
|
||||
Vector2 dir = character.Position - fireSource.Position;
|
||||
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(fireSource.Position, character.Position), 0.1f, 10.0f);
|
||||
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
|
||||
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
|
||||
}
|
||||
|
||||
foreach (Character enemy in Character.CharacterList)
|
||||
{
|
||||
//don't run from friendly NPCs
|
||||
if (enemy.TeamID == Character.TeamType.FriendlyNPC) { continue; }
|
||||
//friendly NPCs don't run away from anything but characters controlled by EnemyAIController (= monsters)
|
||||
if (character.TeamID == Character.TeamType.FriendlyNPC && !(enemy.AIController is EnemyAIController)) { continue; }
|
||||
|
||||
if (enemy.CurrentHull == currentHull && !enemy.IsDead && !enemy.IsUnconscious &&
|
||||
if (enemy.CurrentHull == currentHull && !enemy.IsDead && !enemy.IsUnconscious &&
|
||||
(enemy.AIController is EnemyAIController || enemy.TeamID != character.TeamID))
|
||||
{
|
||||
Vector2 dir = character.Position - enemy.Position;
|
||||
@@ -154,7 +147,6 @@ namespace Barotrauma
|
||||
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
if (escapeVel != Vector2.Zero)
|
||||
{
|
||||
//only move if we haven't reached the edge of the room
|
||||
@@ -251,36 +243,5 @@ namespace Barotrauma
|
||||
}
|
||||
return bestHull;
|
||||
}
|
||||
|
||||
public override bool IsDuplicate(AIObjective otherObjective)
|
||||
{
|
||||
return (otherObjective is AIObjectiveFindSafety);
|
||||
}
|
||||
|
||||
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
|
||||
{
|
||||
if (character.CurrentHull == null)
|
||||
{
|
||||
currenthullSafety = 0;
|
||||
Priority = 5;
|
||||
return;
|
||||
}
|
||||
if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { Priority = 100; }
|
||||
currenthullSafety = HumanAIController.GetHullSafety(character.CurrentHull);
|
||||
if (currenthullSafety > HumanAIController.HULL_SAFETY_THRESHOLD)
|
||||
{
|
||||
Priority -= priorityDecrease * deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
float dangerFactor = (100 - currenthullSafety) / 100;
|
||||
Priority += dangerFactor * priorityIncrease * deltaTime;
|
||||
}
|
||||
Priority = MathHelper.Clamp(Priority, 0, 100);
|
||||
if (divingGearObjective != null && !divingGearObjective.IsCompleted() && divingGearObjective.CanBeCompleted)
|
||||
{
|
||||
Priority = Math.Max(Priority, AIObjectiveManager.OrderPriority + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user