Unstable 0.1500.7.0 (No edition)
This commit is contained in:
@@ -103,6 +103,9 @@ namespace Barotrauma
|
||||
!pathSteering.CurrentPath.Unreachable &&
|
||||
(!requireNonDirty || !pathSteering.IsPathDirty);
|
||||
|
||||
public bool IsCurrentPathUnreachable => steeringManager is IndoorsSteeringManager pathSteering && !pathSteering.IsPathDirty && pathSteering.CurrentPath != null && pathSteering.CurrentPath.Unreachable;
|
||||
public bool IsCurrentPathFinished => steeringManager is IndoorsSteeringManager pathSteering && !pathSteering.IsPathDirty && pathSteering.CurrentPath != null && pathSteering.CurrentPath.Finished;
|
||||
|
||||
protected readonly float colliderWidth;
|
||||
protected readonly float minGapSize;
|
||||
protected readonly float colliderLength;
|
||||
@@ -412,7 +415,7 @@ namespace Barotrauma
|
||||
}
|
||||
else if (EscapeTarget != null && EscapeTarget.FlowTargetHull != Character.CurrentHull)
|
||||
{
|
||||
if (pathSteering.CurrentPath != null && !pathSteering.IsPathDirty && pathSteering.CurrentPath.Unreachable)
|
||||
if (IsCurrentPathUnreachable)
|
||||
{
|
||||
unreachableGaps.Add(EscapeTarget);
|
||||
EscapeTarget = null;
|
||||
|
||||
@@ -453,7 +453,7 @@ namespace Barotrauma
|
||||
if (SelectedAiTarget?.Entity != null || EscapeTarget != null)
|
||||
{
|
||||
Entity t = SelectedAiTarget?.Entity ?? EscapeTarget;
|
||||
float referencePos = Vector2.DistanceSquared(Character.WorldPosition, t.WorldPosition) > 100 * 100 && HasValidPath(true) ? PathSteering.CurrentPath.CurrentNode.WorldPosition.X : t.WorldPosition.X;
|
||||
float referencePos = Vector2.DistanceSquared(Character.WorldPosition, t.WorldPosition) > 100 * 100 && HasValidPath(requireNonDirty: true) ? PathSteering.CurrentPath.CurrentNode.WorldPosition.X : t.WorldPosition.X;
|
||||
Character.AnimController.TargetDir = Character.WorldPosition.X < referencePos ? Direction.Right : Direction.Left;
|
||||
}
|
||||
else
|
||||
@@ -916,9 +916,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (SteeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
if (patrolTarget == null ||
|
||||
pathSteering.CurrentPath == null ||
|
||||
!pathSteering.IsPathDirty && (pathSteering.CurrentPath.Finished || pathSteering.CurrentPath.Unreachable))
|
||||
if (patrolTarget == null || IsCurrentPathUnreachable || IsCurrentPathFinished)
|
||||
{
|
||||
newPatrolTargetTimer = Math.Min(newPatrolTargetTimer, newPatrolTargetIntervalMin);
|
||||
}
|
||||
@@ -936,8 +934,7 @@ namespace Barotrauma
|
||||
else if (targetHulls.Any())
|
||||
{
|
||||
patrolTarget = ToolBox.SelectWeightedRandom(targetHulls, hullWeights, Rand.RandSync.Unsynced);
|
||||
var path = PathSteering.PathFinder.FindPath(Character.SimPosition, patrolTarget.SimPosition, minGapSize: minGapSize * 1.5f, nodeFilter: n => PatrolNodeFilter(n));
|
||||
|
||||
var path = PathSteering.PathFinder.FindPath(Character.SimPosition, patrolTarget.SimPosition, Character.Submarine, minGapSize: minGapSize * 1.5f, nodeFilter: n => PatrolNodeFilter(n));
|
||||
if (path.Unreachable)
|
||||
{
|
||||
//can't go to this room, remove it from the list and try another room
|
||||
@@ -2331,34 +2328,32 @@ namespace Barotrauma
|
||||
SelectedAiTarget.Entity is Character c && VisibleHulls.Contains(c.CurrentHull))
|
||||
{
|
||||
// Steer towards the target if in the same room and swimming
|
||||
Vector2 dir = Vector2.Normalize(SelectedAiTarget.Entity.WorldPosition - Character.WorldPosition);
|
||||
if (MathUtils.IsValid(dir))
|
||||
{
|
||||
SteeringManager.SteeringManual(deltaTime, dir);
|
||||
}
|
||||
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(SelectedAiTarget.Entity.WorldPosition - Character.WorldPosition));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use path finding
|
||||
PathSteering.SteeringSeek(Character.GetRelativeSimPosition(SelectedAiTarget.Entity), weight: 2, minGapWidth: minGapSize);
|
||||
if (!PathSteering.IsPathDirty && PathSteering.CurrentPath.Unreachable)
|
||||
{
|
||||
// Can't reach
|
||||
State = AIState.Idle;
|
||||
IgnoreTarget(SelectedAiTarget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Outside
|
||||
SteeringManager.SteeringSeek(Character.GetRelativeSimPosition(SelectedAiTarget.Entity), 5);
|
||||
if (Character.AnimController.InWater)
|
||||
}
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
if (!pathSteering.IsPathDirty && pathSteering.CurrentPath.Unreachable)
|
||||
{
|
||||
SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: avoidLookAheadDistance, weight: 15);
|
||||
// Can't reach
|
||||
State = AIState.Idle;
|
||||
IgnoreTarget(SelectedAiTarget);
|
||||
}
|
||||
}
|
||||
else if (Character.AnimController.InWater)
|
||||
{
|
||||
SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: avoidLookAheadDistance, weight: 15);
|
||||
}
|
||||
}
|
||||
|
||||
#region Targeting
|
||||
@@ -2510,6 +2505,11 @@ namespace Barotrauma
|
||||
else if (targetingFromOutsideToInside)
|
||||
{
|
||||
targetingTag = "room";
|
||||
if (item.Submarine?.Info.IsRuin != null)
|
||||
{
|
||||
// Ignore ruin items when the creature is outside.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targetingTag == "nasonov")
|
||||
|
||||
@@ -115,6 +115,11 @@ namespace Barotrauma
|
||||
IsPathDirty = true;
|
||||
}
|
||||
|
||||
public void SteeringSeekSimple(Vector2 targetSimPos, float weight = 1)
|
||||
{
|
||||
steering += base.DoSteeringSeek(targetSimPos, weight);
|
||||
}
|
||||
|
||||
public void SteeringSeek(Vector2 target, float weight, float minGapWidth = 0, Func<PathNode, bool> startNodeFilter = null, Func<PathNode, bool> endNodeFilter = null, Func<PathNode, bool> nodeFilter = null, bool checkVisiblity = true)
|
||||
{
|
||||
steering += CalculateSteeringSeek(target, weight, minGapWidth, startNodeFilter, endNodeFilter, nodeFilter, checkVisiblity);
|
||||
@@ -164,7 +169,7 @@ namespace Barotrauma
|
||||
|
||||
private Vector2 CalculateSteeringSeek(Vector2 target, float weight, float minGapSize = 0, Func<PathNode, bool> startNodeFilter = null, Func<PathNode, bool> endNodeFilter = null, Func<PathNode, bool> nodeFilter = null, bool checkVisibility = true)
|
||||
{
|
||||
bool needsNewPath = currentPath == null || currentPath.Unreachable;
|
||||
bool needsNewPath = currentPath == null || currentPath.Unreachable || currentPath.Finished;
|
||||
if (!needsNewPath && character.Submarine != null && character.Params.PathFinderPriority > 0.5f)
|
||||
{
|
||||
Vector2 targetDiff = target - currentTarget;
|
||||
@@ -194,16 +199,8 @@ namespace Barotrauma
|
||||
SkipCurrentPathNodes();
|
||||
currentTarget = target;
|
||||
Vector2 currentPos = host.SimPosition;
|
||||
if (character != null && character.Submarine == null)
|
||||
{
|
||||
var targetHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(target), null, false);
|
||||
if (targetHull != null && targetHull.Submarine != null)
|
||||
{
|
||||
currentPos -= targetHull.Submarine.SimPosition;
|
||||
}
|
||||
}
|
||||
pathFinder.InsideSubmarine = character.Submarine != null;
|
||||
pathFinder.ApplyPenaltyToOutsideNodes = character.PressureProtection <= 0;
|
||||
pathFinder.InsideSubmarine = character.Submarine != null && !character.Submarine.Info.IsRuin;
|
||||
pathFinder.ApplyPenaltyToOutsideNodes = character.Submarine != null && character.PressureProtection <= 0;
|
||||
var newPath = pathFinder.FindPath(currentPos, target, character.Submarine, "(Character: " + character.Name + ")", minGapSize, startNodeFilter, endNodeFilter, nodeFilter, checkVisibility: checkVisibility);
|
||||
bool useNewPath = needsNewPath || currentPath == null || currentPath.CurrentNode == null || character.Submarine != null && findPathTimer < -1 && Math.Abs(character.AnimController.TargetMovement.X) <= 0;
|
||||
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
|
||||
@@ -218,7 +215,7 @@ namespace Barotrauma
|
||||
// Use the new path if it has significantly lower cost (don't change the path if it has marginally smaller cost. This reduces navigating backwards due to new path that is calculated from the node just behind us).
|
||||
float t = (float)currentPath.CurrentIndex / (currentPath.Nodes.Count - 1);
|
||||
useNewPath = newPath.Cost < currentPath.Cost * MathHelper.Lerp(0.95f, 0, t);
|
||||
if (!useNewPath && character.Submarine != null)
|
||||
if (!useNewPath)
|
||||
{
|
||||
// It's possible that the current path was calculated from a start point that is no longer valid.
|
||||
// Therefore, let's accept also paths with a greater cost than the current, if the current node is much farther than the new start node.
|
||||
@@ -322,15 +319,26 @@ namespace Barotrauma
|
||||
doorsChecked = true;
|
||||
}
|
||||
Vector2 pos = host.SimPosition;
|
||||
if (character != null && CurrentPath.CurrentNode?.Submarine != null)
|
||||
if (character != null && CurrentPath.CurrentNode != null)
|
||||
{
|
||||
if (character.Submarine == null)
|
||||
var nodeSub = CurrentPath.CurrentNode.Submarine;
|
||||
if (nodeSub != null)
|
||||
{
|
||||
pos -= CurrentPath.CurrentNode.Submarine.SimPosition;
|
||||
if (character.Submarine == null)
|
||||
{
|
||||
// Going inside
|
||||
pos -= ConvertUnits.ToSimUnits(nodeSub.Position);
|
||||
}
|
||||
else if (character.Submarine != nodeSub)
|
||||
{
|
||||
// Different subs
|
||||
pos -= ConvertUnits.ToSimUnits(nodeSub.Position - character.Submarine.Position);
|
||||
}
|
||||
}
|
||||
else if (character.Submarine != currentPath.CurrentNode.Submarine)
|
||||
else if (character.Submarine != null)
|
||||
{
|
||||
pos -= ConvertUnits.ToSimUnits(currentPath.CurrentNode.Submarine.Position - character.Submarine.Position);
|
||||
// Going outside
|
||||
pos += ConvertUnits.ToSimUnits(character.Submarine.Position);
|
||||
}
|
||||
}
|
||||
bool isDiving = character.AnimController.InWater && character.AnimController.HeadInWater;
|
||||
|
||||
+5
-1
@@ -724,7 +724,10 @@ namespace Barotrauma
|
||||
}
|
||||
if (retreatTarget != null && character.CurrentHull != retreatTarget)
|
||||
{
|
||||
TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true),
|
||||
TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true)
|
||||
{
|
||||
UsePathingOutside = false
|
||||
},
|
||||
onAbandon: () =>
|
||||
{
|
||||
if (Enemy != null && HumanAIController.VisibleHulls.Contains(Enemy.CurrentHull))
|
||||
@@ -783,6 +786,7 @@ namespace Barotrauma
|
||||
TryAddSubObjective(ref followTargetObjective,
|
||||
constructor: () => new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true, closeEnough: 50)
|
||||
{
|
||||
UsePathingOutside = false,
|
||||
IgnoreIfTargetDead = true,
|
||||
DialogueIdentifier = "dialogcannotreachtarget",
|
||||
TargetName = Enemy.DisplayName,
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
// Don't allow to go outside if not already outside.
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition, nodeFilter: node => node.Waypoint.CurrentHull != null);
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition, character.Submarine, nodeFilter: node => node.Waypoint.CurrentHull != null);
|
||||
if (path.Unreachable)
|
||||
{
|
||||
HumanAIController.UnreachableHulls.Add(hull);
|
||||
|
||||
+1
-1
@@ -323,7 +323,7 @@ namespace Barotrauma
|
||||
// This is relatively expensive, so let's do this only when it significantly improves the behavior.
|
||||
// Only allow one path find call per frame.
|
||||
hasCalledPathFinder = true;
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, item.SimPosition, errorMsgStr: $"AIObjectiveGetItem {character.DisplayName}", nodeFilter: node => node.Waypoint.CurrentHull != null);
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, item.SimPosition, character.Submarine, errorMsgStr: $"AIObjectiveGetItem {character.DisplayName}", nodeFilter: node => node.Waypoint.CurrentHull != null);
|
||||
if (path.Unreachable) { continue; }
|
||||
}
|
||||
currItemPriority = itemPriority;
|
||||
|
||||
+44
-31
@@ -27,6 +27,7 @@ namespace Barotrauma
|
||||
public bool followControlledCharacter;
|
||||
public bool mimic;
|
||||
public bool SpeakIfFails { get; set; } = true;
|
||||
public bool UsePathingOutside { get; set; } = true;
|
||||
|
||||
public float extraDistanceWhileSwimming;
|
||||
public float extraDistanceOutsideSub;
|
||||
@@ -121,13 +122,14 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private readonly float avoidLookAheadDistance = 5;
|
||||
private readonly float pathWaitingTime = 3;
|
||||
|
||||
public AIObjectiveGoTo(ISpatialEntity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1, float closeEnough = 0)
|
||||
: base(character, objectiveManager, priorityModifier)
|
||||
{
|
||||
Target = target;
|
||||
this.repeat = repeat;
|
||||
waitUntilPathUnreachable = 3.0f;
|
||||
waitUntilPathUnreachable = pathWaitingTime;
|
||||
this.getDivingGearIfNeeded = getDivingGearIfNeeded;
|
||||
if (Target is Item i)
|
||||
{
|
||||
@@ -186,7 +188,6 @@ namespace Barotrauma
|
||||
// Wait
|
||||
character.AIController.SteeringManager.Reset();
|
||||
}
|
||||
waitUntilPathUnreachable -= deltaTime;
|
||||
if (!character.IsClimbing)
|
||||
{
|
||||
character.SelectedConstruction = null;
|
||||
@@ -222,11 +223,13 @@ namespace Barotrauma
|
||||
{
|
||||
Abandon = true;
|
||||
}
|
||||
else if (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.Unreachable && !PathSteering.IsPathDirty)
|
||||
else if (HumanAIController.IsCurrentPathUnreachable)
|
||||
{
|
||||
waitUntilPathUnreachable -= deltaTime;
|
||||
SteeringManager.Reset();
|
||||
if (waitUntilPathUnreachable < 0)
|
||||
{
|
||||
waitUntilPathUnreachable = pathWaitingTime;
|
||||
if (repeat)
|
||||
{
|
||||
SpeakCannotReach();
|
||||
@@ -325,25 +328,29 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
SeekGaps(maxGapDistance);
|
||||
seekGapsTimer = seekGapsInterval * Rand.Range(0.1f, 1.1f);
|
||||
if (TargetGap != null)
|
||||
bool isRuins = character.Submarine?.Info.IsRuin != null || Target.Submarine?.Info.IsRuin != null;
|
||||
if (!isRuins || !HumanAIController.HasValidPath(requireNonDirty: true, requireUnfinished: true))
|
||||
{
|
||||
// Check that nothing is blocking the way
|
||||
Vector2 rayStart = character.SimPosition;
|
||||
Vector2 rayEnd = TargetGap.SimPosition;
|
||||
if (TargetGap.Submarine != null && character.Submarine == null)
|
||||
SeekGaps(maxGapDistance);
|
||||
seekGapsTimer = seekGapsInterval * Rand.Range(0.1f, 1.1f);
|
||||
if (TargetGap != null)
|
||||
{
|
||||
rayStart -= TargetGap.Submarine.SimPosition;
|
||||
}
|
||||
else if (TargetGap.Submarine == null && character.Submarine != null)
|
||||
{
|
||||
rayEnd -= character.Submarine.SimPosition;
|
||||
}
|
||||
var closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
||||
if (closestBody != null)
|
||||
{
|
||||
TargetGap = null;
|
||||
// Check that nothing is blocking the way
|
||||
Vector2 rayStart = character.SimPosition;
|
||||
Vector2 rayEnd = TargetGap.SimPosition;
|
||||
if (TargetGap.Submarine != null && character.Submarine == null)
|
||||
{
|
||||
rayStart -= TargetGap.Submarine.SimPosition;
|
||||
}
|
||||
else if (TargetGap.Submarine == null && character.Submarine != null)
|
||||
{
|
||||
rayEnd -= character.Submarine.SimPosition;
|
||||
}
|
||||
var closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
||||
if (closestBody != null)
|
||||
{
|
||||
TargetGap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,19 +461,25 @@ namespace Barotrauma
|
||||
}
|
||||
else if (!isInside && HumanAIController.UseIndoorSteeringOutside)
|
||||
{
|
||||
if (character.Submarine == null && Target.Submarine != null)
|
||||
{
|
||||
targetPos += Target.Submarine.SimPosition;
|
||||
}
|
||||
nodeFilter = n => n.Waypoint.Tunnel != null;
|
||||
nodeFilter = n => n.Waypoint.Submarine == null;
|
||||
}
|
||||
|
||||
PathSteering.SteeringSeek(targetPos, weight: 1,
|
||||
startNodeFilter: n => (n.Waypoint.CurrentHull == null) == (character.CurrentHull == null),
|
||||
endNodeFilter: endNodeFilter,
|
||||
nodeFilter: nodeFilter,
|
||||
checkVisiblity: CheckVisibility);
|
||||
|
||||
if (!isInside && !UsePathingOutside)
|
||||
{
|
||||
PathSteering.SteeringSeekSimple(character.GetRelativeSimPosition(Target), 10);
|
||||
if (character.AnimController.InWater)
|
||||
{
|
||||
SteeringManager.SteeringAvoid(deltaTime, avoidLookAheadDistance, weight: 15);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PathSteering.SteeringSeek(targetPos, weight: 1,
|
||||
startNodeFilter: n => (n.Waypoint.CurrentHull == null) == (character.CurrentHull == null),
|
||||
endNodeFilter: endNodeFilter,
|
||||
nodeFilter: nodeFilter,
|
||||
checkVisiblity: CheckVisibility);
|
||||
}
|
||||
if (!isInside && (PathSteering.CurrentPath == null || PathSteering.IsPathDirty || PathSteering.CurrentPath.Unreachable))
|
||||
{
|
||||
if (useScooter)
|
||||
|
||||
+1
-1
@@ -251,7 +251,7 @@ namespace Barotrauma
|
||||
currentTarget = ToolBox.SelectWeightedRandom(targetHulls, hullWeights, Rand.RandSync.Unsynced);
|
||||
bool isInWrongSub = (character.TeamID == CharacterTeamType.FriendlyNPC && !character.IsEscorted) && character.Submarine.TeamID != character.TeamID;
|
||||
bool isCurrentHullAllowed = !isInWrongSub && !IsForbidden(character.CurrentHull);
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsgStr: null, nodeFilter: node =>
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, character.Submarine, nodeFilter: node =>
|
||||
{
|
||||
if (node.Waypoint.CurrentHull == null) { return false; }
|
||||
// Check that there is no unsafe hulls on the way to the target
|
||||
|
||||
+16
-20
@@ -1,7 +1,6 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -69,7 +68,7 @@ namespace Barotrauma
|
||||
HumanAIController.ResetEscape();
|
||||
}
|
||||
HumanAIController.Escape(deltaTime);
|
||||
if (HumanAIController.EscapeTarget == null || !HumanAIController.HasValidPath(requireNonDirty: true, requireUnfinished: false))
|
||||
if (HumanAIController.EscapeTarget == null || HumanAIController.IsCurrentPathUnreachable)
|
||||
{
|
||||
Abandon = true;
|
||||
}
|
||||
@@ -92,14 +91,16 @@ namespace Barotrauma
|
||||
{
|
||||
RemoveSubObjective(ref moveInCaveObjective);
|
||||
RemoveSubObjective(ref moveOutsideObjective);
|
||||
// TODO: Check 'repeat' and 'onAbandon' parameters
|
||||
TryAddSubObjective(ref moveInsideObjective,
|
||||
constructor: () => new AIObjectiveGoTo(targetHull, character, objectiveManager),
|
||||
onCompleted: () => moveInsideObjective = null);
|
||||
onCompleted: () => RemoveSubObjective(ref moveInsideObjective),
|
||||
onAbandon: () => Abandon = true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Error with a Return objective: no suitable target for 'moveInsideObjective'");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,8 +118,7 @@ namespace Barotrauma
|
||||
float closestDistance = float.MaxValue;
|
||||
foreach (var w in WayPoint.WayPointList)
|
||||
{
|
||||
if (w.Tunnel == null) { continue; }
|
||||
if (w.Tunnel.Type == Level.TunnelType.Cave) { continue; }
|
||||
if (w.Tunnel != null && w.Tunnel.Type == Level.TunnelType.Cave) { continue; }
|
||||
if (w.linkedTo.None(l => l is WayPoint linkedWaypoint && linkedWaypoint.Tunnel?.Type == Level.TunnelType.Cave)) { continue; }
|
||||
float distance = Vector2.DistanceSquared(character.WorldPosition, w.WorldPosition);
|
||||
if (closestOutsideWaypoint == null || distance < closestDistance)
|
||||
@@ -131,17 +131,19 @@ namespace Barotrauma
|
||||
{
|
||||
RemoveSubObjective(ref moveInsideObjective);
|
||||
RemoveSubObjective(ref moveOutsideObjective);
|
||||
// TODO: Check 'repeat' and 'onAbandon' parameters
|
||||
TryAddSubObjective(ref moveInCaveObjective,
|
||||
constructor: () => new AIObjectiveGoTo(closestOutsideWaypoint, character, objectiveManager)
|
||||
{
|
||||
endNodeFilter = n => n.Waypoint == closestOutsideWaypoint
|
||||
},
|
||||
onCompleted: () => moveInCaveObjective = null);
|
||||
onCompleted: () => RemoveSubObjective(ref moveInCaveObjective),
|
||||
onAbandon: () => Abandon = true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Error with a Return objective: no suitable main or side path node target found for 'moveOutsideObjective'");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -167,14 +169,16 @@ namespace Barotrauma
|
||||
{
|
||||
RemoveSubObjective(ref moveInsideObjective);
|
||||
RemoveSubObjective(ref moveInCaveObjective);
|
||||
// TODO: Check 'repeat' and 'onAbandon' parameters
|
||||
TryAddSubObjective(ref moveOutsideObjective,
|
||||
constructor: () => new AIObjectiveGoTo(targetHull, character, objectiveManager),
|
||||
onCompleted: () => moveOutsideObjective = null);
|
||||
onCompleted: () => RemoveSubObjective(ref moveOutsideObjective),
|
||||
onAbandon: () => Abandon = true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Error with a Return objective: no suitable target for 'moveOutsideObjective'");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,19 +186,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (HumanAIController.IsInsideCave)
|
||||
{
|
||||
if (moveOutsideObjective != null)
|
||||
{
|
||||
RemoveSubObjective(ref moveOutsideObjective);
|
||||
moveOutsideObjective = null;
|
||||
}
|
||||
RemoveSubObjective(ref moveOutsideObjective);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moveInCaveObjective != null)
|
||||
{
|
||||
RemoveSubObjective(ref moveInCaveObjective);
|
||||
moveInCaveObjective = null;
|
||||
}
|
||||
RemoveSubObjective(ref moveInCaveObjective);
|
||||
}
|
||||
}
|
||||
usingEscapeBehavior = shouldUseEscapeBehavior;
|
||||
|
||||
@@ -119,7 +119,8 @@ namespace Barotrauma
|
||||
|
||||
public PathFinder(List<WayPoint> wayPoints, bool isCharacter)
|
||||
{
|
||||
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => (w.Submarine != null == isCharacter) || (isCharacter && w.Tunnel != null)), removeOrphans: true);
|
||||
var filtered = isCharacter ? wayPoints : wayPoints.FindAll(w => w.Submarine == null);
|
||||
nodes = PathNode.GenerateNodes(filtered, removeOrphans: true);
|
||||
foreach (WayPoint wp in wayPoints)
|
||||
{
|
||||
wp.OnLinksChanged += WaypointLinksChanged;
|
||||
@@ -179,17 +180,37 @@ namespace Barotrauma
|
||||
foreach (PathNode node in nodes)
|
||||
{
|
||||
node.TempPosition = node.Position;
|
||||
if (hostSub != null)
|
||||
var wpSub = node.Waypoint.Submarine;
|
||||
if (hostSub != null && wpSub == null)
|
||||
{
|
||||
Vector2 diff = node.Waypoint.Submarine != null ?
|
||||
hostSub.SimPosition - node.Waypoint.Submarine.SimPosition :
|
||||
hostSub.SimPosition - node.Waypoint.SimPosition;
|
||||
node.TempPosition -= diff;
|
||||
// inside and targeting outside
|
||||
node.TempPosition -= hostSub.SimPosition;
|
||||
}
|
||||
else if (wpSub != null && hostSub != null && wpSub != hostSub)
|
||||
{
|
||||
// different subs
|
||||
node.TempPosition -= hostSub.SimPosition - wpSub.SimPosition;
|
||||
}
|
||||
else if (hostSub == null && wpSub != null)
|
||||
{
|
||||
// Outside and targeting inside
|
||||
node.TempPosition += wpSub.SimPosition;
|
||||
}
|
||||
float xDiff = Math.Abs(start.X - node.TempPosition.X);
|
||||
float yDiff = Math.Abs(start.Y - node.TempPosition.Y);
|
||||
if (yDiff > 1.0f && node.Waypoint.Ladders == null && node.Waypoint.Stairs == null) { yDiff += 10.0f; }
|
||||
node.TempDistance = xDiff + (InsideSubmarine ? yDiff * 10.0f : yDiff); //higher cost for vertical movement when inside the sub
|
||||
if (InsideSubmarine)
|
||||
{
|
||||
//higher cost for vertical movement when inside the sub
|
||||
if (yDiff > 1.0f && node.Waypoint.Ladders == null && node.Waypoint.Stairs == null)
|
||||
{
|
||||
yDiff += 10.0f;
|
||||
}
|
||||
node.TempDistance = xDiff + yDiff * 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
node.TempDistance = xDiff + yDiff;
|
||||
}
|
||||
|
||||
//much higher cost to waypoints that are outside
|
||||
if (node.Waypoint.CurrentHull == null && ApplyPenaltyToOutsideNodes) { node.TempDistance *= 10.0f; }
|
||||
|
||||
@@ -57,7 +57,10 @@ namespace Barotrauma
|
||||
|
||||
public void SteeringManual(float deltaTime, Vector2 velocity)
|
||||
{
|
||||
steering += velocity;
|
||||
if (MathUtils.IsValid(velocity))
|
||||
{
|
||||
steering += velocity;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
||||
Reference in New Issue
Block a user