Release v0.15.13.0
This commit is contained in:
@@ -104,6 +104,7 @@ namespace Barotrauma
|
||||
!pathSteering.CurrentPath.Unreachable &&
|
||||
(!requireNonDirty || !pathSteering.IsPathDirty);
|
||||
|
||||
public bool IsCurrentPathNullOrUnreachable => IsCurrentPathUnreachable || steeringManager is IndoorsSteeringManager pathSteering && pathSteering.CurrentPath == null;
|
||||
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;
|
||||
|
||||
@@ -431,7 +432,7 @@ namespace Barotrauma
|
||||
Vector2 diff = EscapeTarget.WorldPosition - Character.WorldPosition;
|
||||
float sqrDist = diff.LengthSquared();
|
||||
bool isClose = sqrDist < MathUtils.Pow2(100);
|
||||
if (Character.CurrentHull == null || isClose && !isClosedDoor || pathSteering == null || IsCurrentPathUnreachable || IsCurrentPathFinished)
|
||||
if (Character.CurrentHull == null || isClose && !isClosedDoor || pathSteering == null || IsCurrentPathNullOrUnreachable || IsCurrentPathFinished)
|
||||
{
|
||||
// Very close to the target, outside, or at the end of the path -> try to steer through the gap
|
||||
SteeringManager.Reset();
|
||||
|
||||
@@ -3659,15 +3659,15 @@ namespace Barotrauma
|
||||
{
|
||||
if (SelectedAiTarget == null) { return; }
|
||||
Vector2 escapeDir = Vector2.Normalize(WorldPosition - SelectedAiTarget.WorldPosition);
|
||||
if (!MathUtils.IsValid(escapeDir))
|
||||
{
|
||||
escapeDir = Vector2.UnitY;
|
||||
}
|
||||
if (Character.CurrentHull != null && !Character.AnimController.InWater)
|
||||
{
|
||||
// Inside
|
||||
escapeDir = new Vector2(Math.Sign(escapeDir.X), 0);
|
||||
}
|
||||
if (!MathUtils.IsValid(escapeDir))
|
||||
{
|
||||
escapeDir = Vector2.UnitY;
|
||||
}
|
||||
SteeringManager.Reset();
|
||||
SteeringManager.SteeringManual(deltaTime, escapeDir);
|
||||
}
|
||||
|
||||
@@ -250,7 +250,17 @@ namespace Barotrauma
|
||||
{
|
||||
rayEnd += SelectedAiTarget.Entity.Submarine.SimPosition;
|
||||
}
|
||||
UseIndoorSteeringOutside = Submarine.PickBody(SimPosition, rayEnd, collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) != null;
|
||||
IEnumerable<FarseerPhysics.Dynamics.Body> ignoredBodies = null;
|
||||
if (SelectedAiTarget.Entity is ISpatialEntity spatialTarget)
|
||||
{
|
||||
Submarine targetSub = spatialTarget.Submarine;
|
||||
if (targetSub != null)
|
||||
{
|
||||
ignoredBodies = targetSub.PhysicsBody.FarseerBody.ToEnumerable();
|
||||
}
|
||||
}
|
||||
var obstacle = Submarine.PickBody(SimPosition, rayEnd, ignoredBodies, collisionCategory: Physics.CollisionLevel | Physics.CollisionWall);
|
||||
UseIndoorSteeringOutside = obstacle != null;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -340,14 +350,21 @@ namespace Barotrauma
|
||||
IsInsideCave = Character.CurrentHull == null && Level.Loaded?.Caves.FirstOrDefault(c => c.Area.Contains(Character.WorldPosition)) is Level.Cave;
|
||||
}
|
||||
|
||||
if (UseIndoorSteeringOutside || IsInsideCave || Character.CurrentHull?.Submarine != null || hasValidPath && IsCloseEnoughToTarget(maxSteeringBuffer) || IsCloseEnoughToTarget(steeringBuffer))
|
||||
if (UseIndoorSteeringOutside || IsInsideCave || Character.CurrentHull?.Submarine != null || hasValidPath || IsCloseEnoughToTarget(steeringBuffer))
|
||||
{
|
||||
if (steeringManager != insideSteering)
|
||||
{
|
||||
insideSteering.Reset();
|
||||
steeringManager = insideSteering;
|
||||
}
|
||||
steeringBuffer += steeringBufferIncreaseSpeed * deltaTime;
|
||||
if (IsCloseEnoughToTarget(maxSteeringBuffer))
|
||||
{
|
||||
steeringBuffer += steeringBufferIncreaseSpeed * deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
steeringBuffer = minSteeringBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -201,9 +201,9 @@ namespace Barotrauma
|
||||
currentTarget = target;
|
||||
Vector2 currentPos = host.SimPosition;
|
||||
pathFinder.InsideSubmarine = character.Submarine != null && !character.Submarine.Info.IsRuin;
|
||||
pathFinder.ApplyPenaltyToOutsideNodes = character.Submarine != null && character.PressureProtection <= 0;
|
||||
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;
|
||||
bool useNewPath = needsNewPath || currentPath == null || currentPath.CurrentNode == null || character.Submarine != null && findPathTimer < -1 && Math.Abs(character.AnimController.TargetMovement.Combine()) <= 0;
|
||||
if (newPath.Unreachable || newPath.Nodes.None())
|
||||
{
|
||||
useNewPath = false;
|
||||
@@ -220,10 +220,12 @@ 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 && character.Submarine != null && !character.IsClimbing)
|
||||
{
|
||||
// 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.
|
||||
// This is a special case for cases e.g. where the character falls and thus needs a new path.
|
||||
// Don't do this outside or when climbing ladders, because both cause issues.
|
||||
useNewPath = Vector2.DistanceSquared(character.WorldPosition, currentPath.CurrentNode.WorldPosition) > Math.Pow(Vector2.Distance(character.WorldPosition, newPath.Nodes.First().WorldPosition) * 3, 2);
|
||||
}
|
||||
}
|
||||
@@ -310,8 +312,7 @@ namespace Barotrauma
|
||||
if (currentPath.Finished)
|
||||
{
|
||||
Vector2 pos2 = host.SimPosition;
|
||||
if (character != null && character.Submarine == null &&
|
||||
CurrentPath.Nodes.Count > 0 && CurrentPath.Nodes.Last().Submarine != null)
|
||||
if (character != null && character.Submarine == null && CurrentPath.Nodes.Count > 0 && CurrentPath.Nodes.Last().Submarine != null)
|
||||
{
|
||||
pos2 -= CurrentPath.Nodes.Last().Submarine.SimPosition;
|
||||
}
|
||||
@@ -323,29 +324,7 @@ namespace Barotrauma
|
||||
CheckDoorsInPath();
|
||||
doorsChecked = true;
|
||||
}
|
||||
Vector2 pos = host.SimPosition;
|
||||
if (character != null && CurrentPath.CurrentNode != null)
|
||||
{
|
||||
var nodeSub = CurrentPath.CurrentNode.Submarine;
|
||||
if (nodeSub != null)
|
||||
{
|
||||
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 != null)
|
||||
{
|
||||
// Going outside
|
||||
pos += ConvertUnits.ToSimUnits(character.Submarine.Position);
|
||||
}
|
||||
}
|
||||
Vector2 pos = host.WorldPosition;
|
||||
bool isDiving = character.AnimController.InWater && character.AnimController.HeadInWater;
|
||||
// Only humanoids can climb ladders
|
||||
bool canClimb = character.AnimController is HumanoidAnimController && !character.LockHands;
|
||||
@@ -384,7 +363,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (character.IsClimbing && useLadders)
|
||||
{
|
||||
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
|
||||
Vector2 diff = currentPath.CurrentNode.WorldPosition - pos;
|
||||
bool nextLadderSameAsCurrent = IsNextLadderSameAsCurrent;
|
||||
if (nextLadderSameAsCurrent)
|
||||
{
|
||||
@@ -397,7 +376,7 @@ namespace Barotrauma
|
||||
float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY;
|
||||
if (heightFromFloor <= 0.0f)
|
||||
{
|
||||
diff.Y = Math.Max(diff.Y, 1.0f);
|
||||
diff.Y = Math.Max(diff.Y, 100);
|
||||
}
|
||||
// We need some margin, because if a hatch has closed, it's possible that the height from floor is slightly negative.
|
||||
bool isAboveFloor = heightFromFloor > -0.1f;
|
||||
@@ -430,7 +409,7 @@ namespace Barotrauma
|
||||
NextNode(!doorsChecked);
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
return ConvertUnits.ToSimUnits(diff);
|
||||
}
|
||||
else if (character.AnimController.InWater)
|
||||
{
|
||||
@@ -481,7 +460,7 @@ namespace Barotrauma
|
||||
{
|
||||
return Vector2.Zero;
|
||||
}
|
||||
return currentPath.CurrentNode.SimPosition - pos;
|
||||
return ConvertUnits.ToSimUnits(currentPath.CurrentNode.WorldPosition - pos);
|
||||
}
|
||||
|
||||
private void NextNode(bool checkDoors)
|
||||
|
||||
+6
-2
@@ -45,6 +45,10 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public bool AllowStealing { get; set; }
|
||||
public bool TakeWholeStack { get; set; }
|
||||
/// <summary>
|
||||
/// Are variants of the specified item allowed
|
||||
/// </summary>
|
||||
public bool AllowVariants { get; set; }
|
||||
public bool Equip { get; set; }
|
||||
public bool Wear { get; set; }
|
||||
|
||||
@@ -265,7 +269,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float priority = Math.Clamp(objectiveManager.GetCurrentPriority(), 10, 100);
|
||||
bool checkPath = priority >= AIObjectiveManager.LowestOrderPriority && (objectiveManager.IsCurrentOrder<AIObjectiveFixLeaks>() || objectiveManager.CurrentOrder is AIObjectiveGoTo gotoOrder && gotoOrder.followControlledCharacter);
|
||||
bool checkPath = priority >= AIObjectiveManager.LowestOrderPriority && (objectiveManager.IsCurrentOrder<AIObjectiveFixLeaks>() || objectiveManager.CurrentOrder is AIObjectiveGoTo gotoOrder && gotoOrder.isFollowOrderObjective);
|
||||
bool hasCalledPathFinder = false;
|
||||
int itemsPerFrame = (int)priority;
|
||||
for (int i = 0; i < itemsPerFrame && currSearchIndex < Item.ItemList.Count - 1; i++)
|
||||
@@ -408,7 +412,7 @@ namespace Barotrauma
|
||||
if (ignoredItems.Contains(item)) { return false; };
|
||||
if (item.Condition < TargetCondition) { return false; }
|
||||
if (ItemFilter != null && !ItemFilter(item)) { return false; }
|
||||
return identifiersOrTags.Any(id => id == item.Prefab.Identifier || item.HasTag(id));
|
||||
return identifiersOrTags.Any(id => id == item.Prefab.Identifier || item.HasTag(id) || (AllowVariants && item.Prefab.VariantOf?.Identifier == id));
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
|
||||
+10
-17
@@ -24,7 +24,7 @@ namespace Barotrauma
|
||||
|
||||
public Func<float> priorityGetter;
|
||||
|
||||
public bool followControlledCharacter;
|
||||
public bool isFollowOrderObjective;
|
||||
public bool mimic;
|
||||
public bool SpeakIfFails { get; set; } = true;
|
||||
public bool UsePathingOutside { get; set; } = true;
|
||||
@@ -165,17 +165,10 @@ namespace Barotrauma
|
||||
|
||||
protected override void Act(float deltaTime)
|
||||
{
|
||||
if (followControlledCharacter)
|
||||
if (Target == null)
|
||||
{
|
||||
if (Character.Controlled != null && HumanAIController.IsFriendly(Character.Controlled))
|
||||
{
|
||||
Target = Character.Controlled;
|
||||
}
|
||||
if (Target == null)
|
||||
{
|
||||
Abandon = true;
|
||||
return;
|
||||
}
|
||||
Abandon = true;
|
||||
return;
|
||||
}
|
||||
if (Target == character || character.SelectedBy != null && HumanAIController.IsFriendly(character.SelectedBy))
|
||||
{
|
||||
@@ -205,7 +198,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
Hull targetHull = GetTargetHull();
|
||||
if (!followControlledCharacter)
|
||||
if (!isFollowOrderObjective)
|
||||
{
|
||||
// Abandon if going through unsafe paths. Note ignores unsafe nodes when following an order or when the objective is set to ignore unsafe hulls.
|
||||
bool containsUnsafeNodes = character.IsDismissed && !HumanAIController.ObjectiveManager.CurrentObjective.IgnoreUnsafeHulls
|
||||
@@ -223,7 +216,7 @@ namespace Barotrauma
|
||||
{
|
||||
Abandon = true;
|
||||
}
|
||||
else if (HumanAIController.IsCurrentPathUnreachable)
|
||||
else if (HumanAIController.IsCurrentPathNullOrUnreachable)
|
||||
{
|
||||
waitUntilPathUnreachable -= deltaTime;
|
||||
SteeringManager.Reset();
|
||||
@@ -317,8 +310,8 @@ namespace Barotrauma
|
||||
Character targetCharacter = Target as Character;
|
||||
if (character.AnimController.InWater)
|
||||
{
|
||||
if (character.CurrentHull == null ||
|
||||
followControlledCharacter &&
|
||||
if (character.CurrentHull == null ||
|
||||
isFollowOrderObjective &&
|
||||
targetCharacter != null && (targetCharacter.CurrentHull == null) != (character.CurrentHull == null) &&
|
||||
Vector2.DistanceSquared(character.WorldPosition, Target.WorldPosition) < maxGapDistance * maxGapDistance)
|
||||
{
|
||||
@@ -361,7 +354,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (TargetGap != null)
|
||||
{
|
||||
if (TargetGap.FlowTargetHull != null && HumanAIController.SteerThroughGap(TargetGap, followControlledCharacter ? Target.WorldPosition : TargetGap.FlowTargetHull.WorldPosition, deltaTime))
|
||||
if (TargetGap.FlowTargetHull != null && HumanAIController.SteerThroughGap(TargetGap, isFollowOrderObjective ? Target.WorldPosition : TargetGap.FlowTargetHull.WorldPosition, deltaTime))
|
||||
{
|
||||
SteeringManager.SteeringAvoid(deltaTime, avoidLookAheadDistance, weight: 1);
|
||||
return;
|
||||
@@ -595,7 +588,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (gap.Open < 1) { continue; }
|
||||
if (gap.Submarine == null) { continue; }
|
||||
if (!followControlledCharacter)
|
||||
if (!isFollowOrderObjective)
|
||||
{
|
||||
if (gap.FlowTargetHull == null) { continue; }
|
||||
if (gap.Submarine != Target.Submarine) { continue; }
|
||||
|
||||
+1
-1
@@ -452,7 +452,7 @@ namespace Barotrauma
|
||||
extraDistanceWhileSwimming = 100,
|
||||
AllowGoingOutside = true,
|
||||
IgnoreIfTargetDead = true,
|
||||
followControlledCharacter = true,
|
||||
isFollowOrderObjective = true,
|
||||
mimic = true,
|
||||
DialogueIdentifier = "dialogcannotreachplace"
|
||||
};
|
||||
|
||||
+4
-1
@@ -107,7 +107,10 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (RelatedItem requiredItem in kvp.Value)
|
||||
{
|
||||
var getItemObjective = new AIObjectiveGetItem(character, requiredItem.Identifiers, objectiveManager, true);
|
||||
var getItemObjective = new AIObjectiveGetItem(character, requiredItem.Identifiers, objectiveManager, true)
|
||||
{
|
||||
AllowVariants = requiredItem.AllowVariants
|
||||
};
|
||||
if (objectiveManager.IsCurrentOrder<AIObjectiveRepairItems>())
|
||||
{
|
||||
if (character.IsOnPlayerTeam)
|
||||
|
||||
+1
-1
@@ -408,7 +408,7 @@ namespace Barotrauma
|
||||
}
|
||||
bool isCompleted =
|
||||
AIObjectiveRescueAll.GetVitalityFactor(targetCharacter) >= AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager, character, targetCharacter) ||
|
||||
targetCharacter.CharacterHealth.GetAllAfflictions().All(a => a.Strength <= a.Prefab.TreatmentThreshold);
|
||||
targetCharacter.CharacterHealth.GetAllAfflictions().All(a => a.Prefab.IsBuff || a.Strength <= a.Prefab.TreatmentThreshold);
|
||||
|
||||
if (isCompleted && targetCharacter != character && character.IsOnPlayerTeam)
|
||||
{
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ namespace Barotrauma
|
||||
if (character.AIController is HumanAIController humanAI)
|
||||
{
|
||||
if (GetVitalityFactor(target) >= GetVitalityThreshold(humanAI.ObjectiveManager, character, target) ||
|
||||
target.CharacterHealth.GetAllAfflictions().All(a => a.Strength <= a.Prefab.TreatmentThreshold))
|
||||
target.CharacterHealth.GetAllAfflictions().All(a => a.Prefab.IsBuff || a.Strength <= a.Prefab.TreatmentThreshold))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user