(c45394988) Refactor and fix button interaction and access checks in the indoors steering manager.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:40:00 +03:00
parent 704e0731c9
commit ddd84a4f9e
82 changed files with 1867 additions and 1608 deletions
@@ -7,18 +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 AIObjectiveLoop(Character character, string option) : base(character, option)
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();
}
@@ -26,9 +42,11 @@ namespace Barotrauma
public override bool IsCompleted() => false;
public override bool CanBeCompleted => true;
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
public override bool IsLoop { get => true; set => throw new System.Exception("Trying to set the value for IsLoop from: " + System.Environment.StackTrace); }
public override void Update(float deltaTime)
{
base.Update(objectiveManager, deltaTime);
base.Update(deltaTime);
if (IgnoreListClearInterval > 0)
{
if (ignoreListTimer > IgnoreListClearInterval)
@@ -79,15 +97,29 @@ namespace Barotrauma
public override void OnSelected()
{
Reset();
base.OnSelected();
if (HumanAIController.ObjectiveManager.CurrentOrder == this)
{
Reset();
}
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (character.Submarine == null) { return 0; }
if (targets.None()) { return 0; }
float avg = targets.Average(t => Average(t));
return MathHelper.Lerp(0, AIObjectiveManager.OrderPriority + 20, avg / 100);
// Allow the target value to be more than 100.
float targetValue = TargetEvaluation();
// If the target value is less than 1% of the max value, let's just treat it as zero.
if (targetValue < 1) { return 0; }
if (objectiveManager.CurrentOrder == this)
{
return AIObjectiveManager.OrderPriority;
}
float max = MathHelper.Min(AIObjectiveManager.OrderPriority - 1, 90);
float devotion = MathHelper.Min(10, Priority);
float value = MathHelper.Clamp((devotion + targetValue * PriorityModifier) / 100, 0, 1);
return MathHelper.Lerp(0, max, value);
}
protected void UpdateTargets()
@@ -99,12 +131,19 @@ namespace Barotrauma
protected virtual void FindTargets()
{
foreach (T item in GetList())
foreach (T target in GetList())
{
if (Filter(item)) { continue; }
if (!targets.Contains(item))
// The bots always find targets when the objective is an order.
if (objectiveManager.CurrentOrder != this)
{
targets.Add(item);
// Battery or pump states cannot currently be reported (not implemented) 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(target)) { continue; }
}
if (!Filter(target)) { continue; }
if (!ignoreList.Contains(target))
{
targets.Add(target);
}
}
}
@@ -116,6 +155,7 @@ namespace Barotrauma
if (!objectives.TryGetValue(target, out AIObjective objective))
{
objective = ObjectiveConstructor(target);
objective.Completed += () => ReportedTargets.Remove(target);
objectives.Add(target, objective);
AddSubObjective(objective);
}
@@ -126,8 +166,12 @@ namespace Barotrauma
/// List of all possible items of the specified type. Used for filtering the removed objectives.
/// </summary>
protected abstract IEnumerable<T> GetList();
protected abstract float Average(T target);
protected abstract float TargetEvaluation();
protected abstract AIObjective ObjectiveConstructor(T target);
protected abstract bool Filter(T target);
public static bool IsValidTarget(T target) => instance == null ? false : instance.Filter(target);
}
}