(551008fc1) Abandon FixLeakObjective when the goto subobjective cannot be completed. Reset AIObjectiveLoops when the objective is activated or added. Don't clear ignored targets periodically by default. Calculate AIObjectiveGoTo CloseEnough when the objective is created. Don't use arm length in CloseEnough, because it's not used in range checks. Partial fixes to #1343.
This commit is contained in:
@@ -140,6 +140,7 @@ namespace Barotrauma
|
||||
|
||||
protected virtual bool ShouldInterruptSubObjective(AIObjective subObjective) => false;
|
||||
public virtual void OnSelected() { }
|
||||
public virtual void Reset() { }
|
||||
|
||||
protected abstract void Act(float deltaTime);
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ namespace Barotrauma
|
||||
HumanAIController.AnimController.Crouching = true;
|
||||
}
|
||||
|
||||
float reach = HumanAIController.AnimController.ArmLength + ConvertUnits.ToSimUnits(repairTool.Range);
|
||||
//float reach = HumanAIController.AnimController.ArmLength + ConvertUnits.ToSimUnits(repairTool.Range);
|
||||
float reach = ConvertUnits.ToSimUnits(repairTool.Range);
|
||||
bool cannotReach = ConvertUnits.ToSimUnits(gapDiff.Length()) > reach;
|
||||
if (cannotReach)
|
||||
{
|
||||
@@ -110,14 +111,19 @@ namespace Barotrauma
|
||||
// Check if the objective is already removed -> completed/impossible
|
||||
if (!subObjectives.Contains(gotoObjective))
|
||||
{
|
||||
if (!gotoObjective.CanBeCompleted)
|
||||
{
|
||||
abandon = true;
|
||||
}
|
||||
gotoObjective = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character)
|
||||
{
|
||||
CloseEnough = reach * 0.75f
|
||||
CloseEnough = reach
|
||||
};
|
||||
if (!subObjectives.Contains(gotoObjective))
|
||||
{
|
||||
|
||||
@@ -66,9 +66,12 @@ namespace Barotrauma
|
||||
if (!canComplete)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target.");
|
||||
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {(Target != null ? Target.ToString() : TargetPos.ToString())}", Color.Yellow);
|
||||
#endif
|
||||
character.Speak(TextManager.Get("DialogCannotReach"), identifier: "cannotreach", minDurationBetweenSimilar: 10.0f);
|
||||
if (HumanAIController.ObjectiveManager.CurrentOrder != null)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogCannotReach"), identifier: "cannotreach", minDurationBetweenSimilar: 10.0f);
|
||||
}
|
||||
character.AIController.SteeringManager.Reset();
|
||||
}
|
||||
return canComplete;
|
||||
@@ -89,6 +92,7 @@ namespace Barotrauma
|
||||
|
||||
waitUntilPathUnreachable = 1.0f;
|
||||
this.getDivingGearIfNeeded = getDivingGearIfNeeded;
|
||||
CalculateCloseEnough();
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +104,7 @@ namespace Barotrauma
|
||||
|
||||
waitUntilPathUnreachable = 5.0f;
|
||||
this.getDivingGearIfNeeded = getDivingGearIfNeeded;
|
||||
CalculateCloseEnough();
|
||||
}
|
||||
|
||||
protected override void Act(float deltaTime)
|
||||
@@ -149,9 +154,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
bool targetIsOutside = (Target != null && Target.Submarine == null) ||
|
||||
(SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.HasOutdoorsNodes);
|
||||
if (targetIsOutside && character.CurrentHull != null && !AllowGoingOutside)
|
||||
bool isInside = character.CurrentHull != null;
|
||||
bool insideSteering = SteeringManager == PathSteering && PathSteering.CurrentPath != null;
|
||||
bool targetIsOutside = (Target != null && Target.Submarine == null) || (insideSteering && PathSteering.CurrentPath.HasOutdoorsNodes);
|
||||
if (isInside && targetIsOutside && !AllowGoingOutside)
|
||||
{
|
||||
cannotReach = true;
|
||||
}
|
||||
@@ -186,11 +192,8 @@ namespace Barotrauma
|
||||
|
||||
bool completed = false;
|
||||
|
||||
float allowedDistance = CloseEnough;
|
||||
|
||||
if (Target is Item item)
|
||||
{
|
||||
allowedDistance = Math.Max(ConvertUnits.ToSimUnits(item.InteractDistance), CloseEnough);
|
||||
if (item.IsInsideTrigger(character.WorldPosition)) completed = true;
|
||||
}
|
||||
else if (Target is Character targetCharacter)
|
||||
@@ -198,7 +201,7 @@ namespace Barotrauma
|
||||
if (character.CanInteractWith(targetCharacter)) completed = true;
|
||||
}
|
||||
|
||||
completed = completed || Vector2.DistanceSquared(Target != null ? Target.SimPosition : targetPos, character.SimPosition) < allowedDistance * allowedDistance;
|
||||
completed = completed || Vector2.DistanceSquared(Target != null ? Target.SimPosition : targetPos, character.SimPosition) < CloseEnough * CloseEnough;
|
||||
|
||||
if (completed) character.AIController.SteeringManager.Reset();
|
||||
|
||||
@@ -214,5 +217,11 @@ namespace Barotrauma
|
||||
|
||||
return (objective.targetPos == targetPos);
|
||||
}
|
||||
|
||||
private void CalculateCloseEnough()
|
||||
{
|
||||
float interactionDistance = Target is Item i ? ConvertUnits.ToSimUnits(i.InteractDistance) : 0;
|
||||
CloseEnough = Math.Max(interactionDistance, CloseEnough);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,16 @@ namespace Barotrauma
|
||||
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;
|
||||
|
||||
// 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)
|
||||
{
|
||||
FindTargets();
|
||||
CreateObjectives();
|
||||
Reset();
|
||||
}
|
||||
|
||||
protected override void Act(float deltaTime) { }
|
||||
@@ -28,15 +29,18 @@ namespace Barotrauma
|
||||
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
|
||||
{
|
||||
base.Update(objectiveManager, deltaTime);
|
||||
if (ignoreListTimer > ignoreListClearInterval)
|
||||
if (IgnoreListClearInterval > 0)
|
||||
{
|
||||
Reset();
|
||||
if (ignoreListTimer > IgnoreListClearInterval)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoreListTimer += deltaTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoreListTimer += deltaTime;
|
||||
}
|
||||
if (targetUpdateTimer > targetUpdateInterval)
|
||||
if (targetUpdateTimer >= TargetUpdateInterval)
|
||||
{
|
||||
targetUpdateTimer = 0;
|
||||
UpdateTargets();
|
||||
@@ -52,6 +56,7 @@ namespace Barotrauma
|
||||
if (!objective.Value.CanBeCompleted)
|
||||
{
|
||||
ignoreList.Add(target);
|
||||
targetUpdateTimer = TargetUpdateInterval;
|
||||
}
|
||||
if (!targets.Contains(target))
|
||||
{
|
||||
@@ -59,13 +64,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
SyncRemovedObjectives(objectives, GetList());
|
||||
if (objectives.None())
|
||||
if (objectives.None() && targets.Any())
|
||||
{
|
||||
CreateObjectives();
|
||||
}
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
public override void Reset()
|
||||
{
|
||||
ignoreList.Clear();
|
||||
ignoreListTimer = 0;
|
||||
|
||||
@@ -34,9 +34,15 @@ namespace Barotrauma
|
||||
|
||||
public void AddObjective(AIObjective objective)
|
||||
{
|
||||
if (Objectives.Find(o => o.IsDuplicate(objective)) != null) return;
|
||||
|
||||
Objectives.Add(objective);
|
||||
var duplicate = Objectives.Find(o => o.IsDuplicate(objective));
|
||||
if (duplicate != null)
|
||||
{
|
||||
duplicate.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
Objectives.Add(objective);
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<AIObjective, CoroutineHandle> DelayedObjectives { get; private set; } = new Dictionary<AIObjective, CoroutineHandle>();
|
||||
|
||||
@@ -131,7 +131,8 @@ namespace Barotrauma
|
||||
goToObjective = new AIObjectiveGoTo(Item, character);
|
||||
if (repairTool != null)
|
||||
{
|
||||
goToObjective.CloseEnough = (HumanAIController.AnimController.ArmLength + ConvertUnits.ToSimUnits(repairTool.Range)) * 0.75f;
|
||||
//goToObjective.CloseEnough = (HumanAIController.AnimController.ArmLength + ConvertUnits.ToSimUnits(repairTool.Range)) * 0.75f;
|
||||
goToObjective.CloseEnough = ConvertUnits.ToSimUnits(repairTool.Range);
|
||||
}
|
||||
AddSubObjective(goToObjective);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user