(62a89ce6a) Refactor and fix priority calculations. WIP, but should already improve things.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:05:53 +03:00
parent d0795791e7
commit ff5a819ad3
25 changed files with 142 additions and 65 deletions
@@ -1054,6 +1054,8 @@ namespace Barotrauma
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
//goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range
@@ -224,7 +224,7 @@ namespace Barotrauma
}
//only humanoids can climb ladders
if (character.AnimController is HumanoidAnimController && IsNextLadderSameAsCurrent)
if (!character.AnimController.InWater && character.AnimController is HumanoidAnimController && IsNextLadderSameAsCurrent)
{
if (character.SelectedConstruction != currentPath.CurrentNode.Ladders.Item &&
currentPath.CurrentNode.Ladders.Item.IsInsideTrigger(character.WorldPosition))
@@ -234,7 +234,7 @@ namespace Barotrauma
}
var collider = character.AnimController.Collider;
if (character.IsClimbing)
if (character.IsClimbing && !character.AnimController.InWater)
{
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
bool nextLadderSameAsCurrent = IsNextLadderSameAsCurrent;
@@ -278,6 +278,12 @@ namespace Barotrauma
}
else if (character.AnimController.InWater)
{
// If the character is underwater, we don't need the ladders anymore
if (character.IsClimbing)
{
character.AnimController.Anim = AnimController.Animation.None;
character.SelectedConstruction = null;
}
if (Vector2.DistanceSquared(pos, currentPath.CurrentNode.SimPosition) < MathUtils.Pow(collider.radius * 3, 2))
{
currentPath.SkipToNextNode();
@@ -105,7 +105,7 @@ namespace Barotrauma
CurrentSubObjective.SortSubObjectives(objectiveManager);
}
public virtual float GetPriority(AIObjectiveManager objectiveManager) => Priority;
public virtual float GetPriority(AIObjectiveManager objectiveManager) => Priority * PriorityModifier;
public virtual void Update(AIObjectiveManager objectiveManager, float deltaTime)
{
@@ -116,9 +116,8 @@ namespace Barotrauma
}
else if (objectiveManager.CurrentObjective == this || subObjective == this)
{
Priority += Devotion * deltaTime;
Priority += Devotion * PriorityModifier * deltaTime;
}
Priority *= PriorityModifier;
Priority = MathHelper.Clamp(Priority, 0, 100);
subObjectives.ForEach(so => so.Update(objectiveManager, deltaTime));
}
@@ -296,7 +296,7 @@ namespace Barotrauma
}
public override bool CanBeCompleted => !abandon && (reloadWeaponObjective == null || reloadWeaponObjective.CanBeCompleted) && (retreatObjective == null || retreatObjective.CanBeCompleted);
public override float GetPriority(AIObjectiveManager objectiveManager) => (Enemy != null && (Enemy.Removed || Enemy.IsDead)) ? 0 : 100;
public override float GetPriority(AIObjectiveManager objectiveManager) => (Enemy != null && (Enemy.Removed || Enemy.IsDead)) ? 0 : 100 * PriorityModifier;
public override bool IsDuplicate(AIObjective otherObjective)
{
@@ -32,7 +32,7 @@ namespace Barotrauma
float dist = Math.Abs(character.WorldPosition.X - targetHull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - targetHull.WorldPosition.Y) * 2.0f;
float distanceFactor = MathHelper.Lerp(1, 0.1f, MathUtils.InverseLerp(0, 10000, dist));
float severityFactor = MathHelper.Lerp(0, 1, MathHelper.Clamp(targetHull.FireSources.Sum(fs => fs.Size.X) / targetHull.Size.X, 0, 1));
return MathHelper.Clamp(Priority * severityFactor * distanceFactor, 0, 100);
return MathHelper.Lerp(0, 100, severityFactor * distanceFactor);
}
public override bool IsCompleted()
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework;
namespace Barotrauma
{
// TODO: use objective loop and sort the targets by severity
class AIObjectiveExtinguishFires : AIObjective
{
public override string DebugTag => "extinguish fires";
@@ -23,8 +24,8 @@ namespace Barotrauma
{
return AIObjectiveManager.OrderPriority;
}
return MathHelper.Clamp(fireCount * 20, 0, 100);
float basePriority = MathHelper.Clamp(Priority, 0, 10);
return MathHelper.Clamp(basePriority + fireCount * 20, 0, 100);
}
public override bool IsCompleted() => false;
@@ -40,11 +40,15 @@ namespace Barotrauma
{
if (leak.Open == 0.0f) { return 0.0f; }
float leakSize = (leak.IsHorizontal ? leak.Rect.Height : leak.Rect.Width) * Math.Max(leak.Open, 0.1f);
//float leakSize = (leak.IsHorizontal ? leak.Rect.Height : leak.Rect.Width) * Math.Max(leak.Open, 0.1f);
//float dist = Vector2.DistanceSquared(character.SimPosition, leak.SimPosition);
//dist = Math.Max(dist / 100.0f, 1.0f);
//return Math.Min(leakSize / dist, 40.0f);
float leakSize = (leak.IsHorizontal ? leak.Rect.Height : leak.Rect.Width) * Math.Max(leak.Open, 0.1f);
float dist = Vector2.DistanceSquared(character.SimPosition, leak.SimPosition);
dist = Math.Max(dist / 100.0f, 1.0f);
return Math.Min(leakSize / dist, 40.0f);
return MathHelper.Clamp(Priority + leakSize / dist, 0, 100);
}
public override bool IsDuplicate(AIObjective otherObjective)
@@ -14,17 +14,6 @@ namespace Barotrauma
public AIObjectiveFixLeaks(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public override float GetPriority(AIObjectiveManager objectiveManager)
{
if (character.Submarine == null) { return 0; }
if (targets.None()) { return 0; }
if (objectiveManager.CurrentOrder == this)
{
return AIObjectiveManager.OrderPriority;
}
return MathHelper.Lerp(0, AIObjectiveManager.OrderPriority, targets.Average(t => Average(t)));
}
protected override void FindTargets()
{
base.FindTargets();
@@ -61,7 +50,7 @@ namespace Barotrauma
}
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFixLeaks;
protected override float Average(Gap gap) => gap.Open;
protected override float Average(Gap gap) => gap.Open * 100;
protected override IEnumerable<Gap> GetList() => Gap.GapList;
protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character);
}
@@ -86,8 +86,16 @@ namespace Barotrauma
{
if (character.Submarine == null) { return 0; }
if (targets.None()) { return 0; }
//if (objectiveManager.CurrentOrder == this)
//{
// return AIObjectiveManager.OrderPriority;
//}
float avg = targets.Average(t => Average(t));
return MathHelper.Lerp(0, AIObjectiveManager.OrderPriority + 20, avg / 100);
// If the avg is less than 1% of the max value, let's just treat it as zero.
if (avg < 1) { return 0; }
float max = MathHelper.Min(AIObjectiveManager.OrderPriority + 20, 100);
float value = MathHelper.Min((Priority + avg) / 100 * PriorityModifier, 1);
return MathHelper.Lerp(0, max, value);
}
protected void UpdateTargets()
@@ -126,6 +134,10 @@ namespace Barotrauma
/// List of all possible items of the specified type. Used for filtering the removed objectives.
/// </summary>
protected abstract IEnumerable<T> GetList();
/// <summary>
/// 0 to 100.
/// </summary>
protected abstract float Average(T target);
protected abstract AIObjective ObjectiveConstructor(T target);
protected abstract bool Filter(T target);
@@ -1,6 +1,7 @@
using Barotrauma.Items.Components;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
@@ -15,16 +16,6 @@ namespace Barotrauma
pumpList = character.Submarine.GetItems(true).Select(i => i.GetComponent<Pump>()).Where(p => p != null);
}
public override float GetPriority(AIObjectiveManager objectiveManager)
{
if (character.Submarine == null) { return 0; }
if (objectiveManager.CurrentOrder == this && targets.Count > 0)
{
return AIObjectiveManager.OrderPriority;
}
return 0.0f;
}
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectivePumpWater && otherObjective.Option == Option;
//availablePumps = allPumps.Where(p => !p.Item.HasTag("ballast") && p.Item.Connections.None(c => c.IsPower && p.Item.GetConnectedComponentsRecursive<Steering>(c).None())).ToList();
@@ -63,6 +54,6 @@ namespace Barotrauma
protected override bool Filter(Pump pump) => true;
protected override IEnumerable<Pump> GetList() => pumpList;
protected override AIObjective ObjectiveConstructor(Pump pump) => new AIObjectiveOperateItem(pump, character, Option, false);
protected override float Average(Pump target) => 0;
protected override float Average(Pump target) => MathHelper.Lerp(0, 100, target.CurrFlow / target.MaxFlow);
}
}
@@ -230,6 +230,7 @@ namespace Barotrauma
public override float GetPriority(AIObjectiveManager objectiveManager)
{
// TODO: review
if (targetCharacter.AnimController.CurrentHull == null || targetCharacter.IsDead) { return 0.0f; }
Vector2 diff = targetCharacter.WorldPosition - character.WorldPosition;
@@ -27,6 +27,7 @@ namespace Barotrauma
public override float GetPriority(AIObjectiveManager objectiveManager)
{
// TODO: review
if (character.Submarine == null) { return 0; }
GetRescueTargets();
if (!rescueTargets.Any()) { return 0.0f; }
@@ -2610,6 +2610,10 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif