Unstable 0.1500.7.0 (No edition)

This commit is contained in:
Markus Isberg
2021-10-14 00:42:06 +09:00
parent c8943ef9c4
commit de917c5d74
105 changed files with 871 additions and 443 deletions
@@ -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,
@@ -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);
@@ -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;
@@ -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)
@@ -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
@@ -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;