409d4d9...aeafa16 (merge human-ai)
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
abstract class AIObjectiveLoop<T> : AIObjective
|
||||
{
|
||||
protected List<T> targets = new List<T>();
|
||||
protected Dictionary<T, AIObjective> objectives = new Dictionary<T, AIObjective>();
|
||||
protected HashSet<T> ignoreList = new HashSet<T>();
|
||||
protected readonly float ignoreListClearInterval = 30;
|
||||
private float ignoreListTimer;
|
||||
protected readonly float targetUpdateInterval = 2;
|
||||
private float targetUpdateTimer;
|
||||
|
||||
public AIObjectiveLoop(Character character, string option) : base(character, option)
|
||||
{
|
||||
FindTargets();
|
||||
CreateObjectives();
|
||||
}
|
||||
|
||||
protected override void Act(float deltaTime) { }
|
||||
public override bool IsCompleted() => false;
|
||||
public override bool CanBeCompleted => true;
|
||||
|
||||
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
|
||||
{
|
||||
base.Update(objectiveManager, deltaTime);
|
||||
if (ignoreListTimer > ignoreListClearInterval)
|
||||
{
|
||||
ignoreList.Clear();
|
||||
ignoreListTimer = 0;
|
||||
UpdateTargets();
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoreListTimer += deltaTime;
|
||||
}
|
||||
if (targetUpdateTimer > targetUpdateInterval)
|
||||
{
|
||||
targetUpdateTimer = 0;
|
||||
UpdateTargets();
|
||||
}
|
||||
else
|
||||
{
|
||||
targetUpdateTimer += deltaTime;
|
||||
}
|
||||
// Sync objectives, subobjectives and targets
|
||||
foreach (var objective in objectives)
|
||||
{
|
||||
var target = objective.Key;
|
||||
if (!objective.Value.CanBeCompleted)
|
||||
{
|
||||
ignoreList.Add(target);
|
||||
}
|
||||
if (!targets.Contains(target))
|
||||
{
|
||||
subObjectives.Remove(objective.Value);
|
||||
}
|
||||
}
|
||||
SyncRemovedObjectives(objectives, GetList());
|
||||
if (objectives.None())
|
||||
{
|
||||
CreateObjectives();
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||
{
|
||||
if (character.Submarine == null) { return 0; }
|
||||
if (targets.None()) { return 0; }
|
||||
float avg = targets.Average(t => Average(t));
|
||||
if (objectiveManager.CurrentOrder == this)
|
||||
{
|
||||
return AIObjectiveManager.OrderPriority - MathHelper.Max(0, AIObjectiveManager.OrderPriority - avg);
|
||||
}
|
||||
return MathHelper.Lerp(0, AIObjectiveManager.OrderPriority, avg / 100);
|
||||
}
|
||||
|
||||
protected void UpdateTargets()
|
||||
{
|
||||
targets.Clear();
|
||||
FindTargets();
|
||||
CreateObjectives();
|
||||
}
|
||||
|
||||
protected virtual void FindTargets()
|
||||
{
|
||||
foreach (T item in GetList())
|
||||
{
|
||||
if (Filter(item)) { continue; }
|
||||
if (!targets.Contains(item))
|
||||
{
|
||||
targets.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void CreateObjectives()
|
||||
{
|
||||
foreach (T target in targets)
|
||||
{
|
||||
if (!objectives.TryGetValue(target, out AIObjective objective))
|
||||
{
|
||||
objective = ObjectiveConstructor(target);
|
||||
objectives.Add(target, objective);
|
||||
AddSubObjective(objective);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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 AIObjective ObjectiveConstructor(T target);
|
||||
protected abstract bool Filter(T target);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user