(f0837188e) Bots now target only reported targets when the objective is not an order.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:31:48 +03:00
parent 4f825ce309
commit 5f610caadd
16 changed files with 272 additions and 353 deletions
@@ -35,6 +35,8 @@ namespace Barotrauma
public IEnumerable<AIObjective> SubObjectives => subObjectives;
public AIObjective CurrentSubObjective { get; private set; }
public event Action Completed;
protected HumanAIController HumanAIController => character.AIController as HumanAIController;
protected IndoorsSteeringManager PathSteering => HumanAIController.PathSteering;
protected SteeringManager SteeringManager => HumanAIController.SteeringManager;
@@ -94,7 +96,12 @@ namespace Barotrauma
return;
}
bool wasCompleted = IsCompleted();
Act(deltaTime);
if (!wasCompleted && IsCompleted())
{
Completed?.Invoke();
}
}
public void AddSubObjective(AIObjective objective)
@@ -31,6 +31,7 @@ namespace Barotrauma
protected override bool Filter(PowerContainer battery)
{
if (battery == null) { return false; }
var item = battery.Item;
if (item.Submarine == null) { return false; }
if (item.CurrentHull == null) { return false; }
@@ -23,11 +23,12 @@ namespace Barotrauma
protected override bool Filter(Hull target)
{
if (target == null) { return false; }
if (target.FireSources.None()) { return false; }
if (target.Submarine == null) { return false; }
if (target.Submarine.TeamID != character.TeamID) { return false; }
if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(target, true)) { return false; }
if (Character.CharacterList.Any(c => c.CurrentHull == target && !HumanAIController.IsFriendly(c))) { return false; }
//if (Character.CharacterList.Any(c => c.CurrentHull == target && !HumanAIController.IsFriendly(c))) { return false; }
return true;
}
@@ -25,14 +25,12 @@ namespace Barotrauma
protected override bool Filter(Gap gap)
{
bool ignore = gap.ConnectedWall == null || gap.ConnectedDoor != null || gap.Open <= 0 || gap.linkedTo.All(l => l == null);
if (!ignore)
{
if (gap.Submarine == null) { ignore = true; }
else if (gap.Submarine.TeamID != character.TeamID) { ignore = true; }
else if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(gap, true)) { ignore = true; }
}
return !ignore;
if (gap == null) { return false; }
if (gap.ConnectedWall == null || gap.ConnectedDoor != null || gap.Open <= 0 || gap.linkedTo.All(l => l == null)) { return false; }
if (gap.Submarine == null) { return false; }
if (gap.Submarine.TeamID != character.TeamID) { return false; }
if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(gap, true)) { return false; }
return true;
}
public static float GetLeakSeverity(Gap leak)
@@ -73,6 +73,21 @@ namespace Barotrauma
}
}
public override void Update(float deltaTime)
{
if (objectiveManager.CurrentObjective == this)
{
if (randomTimer > 0)
{
randomTimer -= deltaTime;
}
else
{
SetRandom();
}
}
}
public override bool IsCompleted() => false;
public override bool CanBeCompleted => true;
@@ -94,6 +109,13 @@ namespace Barotrauma
{
character.SelectedConstruction = null;
}
if (!character.IsClimbing)
{
character.SelectedConstruction = null;
}
bool currentTargetIsInvalid = currentTarget == null || IsForbidden(currentTarget) ||
(PathSteering.CurrentPath != null && PathSteering.CurrentPath.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull)));
bool currentTargetIsInvalid = currentTarget == null || IsForbidden(currentTarget) ||
(PathSteering.CurrentPath != null && PathSteering.CurrentPath.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull)));
@@ -7,19 +7,34 @@ namespace Barotrauma
{
abstract class AIObjectiveLoop<T> : AIObjective
{
protected List<T> targets = new List<T>();
protected HashSet<T> targets = new HashSet<T>();
protected Dictionary<T, AIObjective> objectives = new Dictionary<T, AIObjective>();
protected HashSet<T> ignoreList = new HashSet<T>();
private float ignoreListTimer;
private float targetUpdateTimer;
private static AIObjectiveLoop<T> instance;
// By default, doesn't clear the list automatically
protected virtual float IgnoreListClearInterval => 0;
protected virtual float TargetUpdateInterval => 2;
public HashSet<T> ReportedTargets { get; private set; } = new HashSet<T>();
public bool AddTarget(T target)
{
if (Filter(target))
{
ReportedTargets.Add(target);
return true;
}
return false;
}
public AIObjectiveLoop(Character character, AIObjectiveManager objectiveManager, float priorityModifier, string option = null)
: base(character, objectiveManager, priorityModifier, option)
{
instance = this;
Reset();
}
@@ -118,8 +133,14 @@ namespace Barotrauma
{
foreach (T item in GetList())
{
if (objectiveManager.CurrentOrder != this)
{
// Battery or pump states cannot be reported and therefore we must ignore them -> the bots always know if they require attention.
bool ignore = this is AIObjectiveChargeBatteries || this is AIObjectivePumpWater;
if (!ignore && !ReportedTargets.Contains(item)) { continue; }
}
if (!Filter(item)) { continue; }
if (!ignoreList.Contains(item) && !targets.Contains(item))
if (!ignoreList.Contains(item))
{
targets.Add(item);
}
@@ -133,6 +154,7 @@ namespace Barotrauma
if (!objectives.TryGetValue(target, out AIObjective objective))
{
objective = ObjectiveConstructor(target);
objective.Completed += () => ReportedTargets.Remove(target);
objectives.Add(target, objective);
AddSubObjective(objective);
}
@@ -148,5 +170,7 @@ namespace Barotrauma
protected abstract AIObjective ObjectiveConstructor(T target);
protected abstract bool Filter(T target);
public static bool IsValidTarget(T target) => instance == null ? false : instance.Filter(target);
}
}
@@ -30,6 +30,7 @@ namespace Barotrauma
protected override bool Filter(Pump pump)
{
if (pump == null) { return false; }
if (pump.Item.HasTag("ballast")) { return false; }
if (pump.Item.Submarine == null) { return false; }
if (pump.Item.CurrentHull == null) { return false; }
@@ -47,34 +47,26 @@ namespace Barotrauma
protected override bool Filter(Item item)
{
bool ignore = item.IsFullCondition;
if (!ignore)
if (item == null) { return false; }
if (item.IsFullCondition) { return false; }
if (item.CurrentHull == null) { return false; }
if (item.Submarine == null) { return false; }
if (item.Submarine.TeamID != character.TeamID) { return false; }
if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(item, true)) { return false; }
if (item.Repairables.None()) { return false; }
if (item.CurrentHull.FireSources.Count > 0 || Character.CharacterList.Any(c => c.CurrentHull == item.CurrentHull && !HumanAIController.IsFriendly(c))) { return false; }
foreach (Repairable repairable in item.Repairables)
{
if (item.Submarine == null) { ignore = true; }
else if (item.Submarine.TeamID != character.TeamID) { ignore = true; }
else if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(item, true)) { ignore = true; }
else
if (!objectives.ContainsKey(item) && item.Condition > repairable.ShowRepairUIThreshold)
{
if (item.Repairables.None()) { ignore = true; }
else if (item.CurrentHull != null || item.CurrentHull.FireSources.Count > 0 || Character.CharacterList.Any(c => c.CurrentHull == item.CurrentHull && !HumanAIController.IsFriendly(c))) { ignore = true; }
else
{
foreach (Repairable repairable in item.Repairables)
{
if (!objectives.ContainsKey(item) && item.Condition > repairable.ShowRepairUIThreshold)
{
ignore = true;
}
else if (RequireAdequateSkills && !repairable.HasRequiredSkills(character))
{
ignore = true;
}
if (ignore) { break; }
}
}
return false;
}
else if (RequireAdequateSkills && !repairable.HasRequiredSkills(character))
{
return false;
}
}
return !ignore;
return true;
}
protected override float TargetEvaluation() => targets.Max(t => 100 - t.ConditionPercentage);