(5670a7c58) Don't get stuck if cannot use the button.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:44:48 +03:00
parent 96b2d953d2
commit f8090d470e
87 changed files with 1711 additions and 2564 deletions
@@ -7,7 +7,7 @@ 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;
@@ -17,7 +17,24 @@ namespace Barotrauma
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 (ReportedTargets.Contains(target))
{
return false;
}
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)
{
Reset();
}
@@ -26,9 +43,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 +98,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 +132,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 +156,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,7 +167,9 @@ 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);
}