Unstable 1.8.4.0
This commit is contained in:
@@ -320,8 +320,7 @@ namespace Barotrauma
|
||||
Vector2 pos = host.WorldPosition;
|
||||
Vector2 diff = currentPath.CurrentNode.WorldPosition - pos;
|
||||
bool isDiving = character.AnimController.InWater && character.AnimController.HeadInWater;
|
||||
// Only humanoids can climb ladders
|
||||
bool canClimb = character.AnimController is HumanoidAnimController && !character.LockHands;
|
||||
bool canClimb = character.CanClimb;
|
||||
Ladder currentLadder = GetCurrentLadder();
|
||||
Ladder nextLadder = GetNextLadder();
|
||||
var ladders = currentLadder ?? nextLadder;
|
||||
@@ -559,26 +558,42 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
// We'll want this to run each time, because the delegate is used to find a valid button component.
|
||||
bool canAccessButtons = false;
|
||||
foreach (var button in door.Item.GetConnectedComponents<Controller>(true, connectionFilter: c => c.Name == "toggle" || c.Name == "set_state"))
|
||||
bool buttonsFound = false;
|
||||
// Check wired controllers (e.g. buttons)
|
||||
// Always run the buttonFilter delegate (inside CanAccessButton method), if defined, because it's used for find a valid controller component that can be used for closing the door, when needed.
|
||||
// TODO: connectionFilter is ignored in the recursive searches, so it does nothing here.
|
||||
foreach (Controller button in door.Item.GetConnectedComponents<Controller>(recursive: true, connectionFilter: c => c.Name is "toggle" or "set_state"))
|
||||
{
|
||||
if (button.HasAccess(character) && (buttonFilter == null || buttonFilter(button)))
|
||||
buttonsFound = true;
|
||||
if (CanAccessButton(button))
|
||||
{
|
||||
canAccessButtons = true;
|
||||
}
|
||||
}
|
||||
foreach (var linked in door.Item.linkedTo)
|
||||
if (!canAccessButtons)
|
||||
{
|
||||
if (linked is not Item linkedItem) { continue; }
|
||||
var button = linkedItem.GetComponent<Controller>();
|
||||
if (button == null) { continue; }
|
||||
if (button.HasAccess(character) && (buttonFilter == null || buttonFilter(button)))
|
||||
// Check linked controllers (more complex circuits)
|
||||
foreach (MapEntity linked in door.Item.linkedTo)
|
||||
{
|
||||
canAccessButtons = true;
|
||||
}
|
||||
}
|
||||
return canAccessButtons || door.IsOpen || ShouldBreakDoor(door);
|
||||
if (linked is not Item linkedItem) { continue; }
|
||||
var button = linkedItem.GetComponent<Controller>();
|
||||
if (button == null) { continue; }
|
||||
buttonsFound = true;
|
||||
if (CanAccessButton(button))
|
||||
{
|
||||
canAccessButtons = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (door.IsOpen || ShouldBreakDoor(door))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// If no buttons were found, just trust it if we should have the access to the door. Could be there's some other mechanism controlling the door.
|
||||
return buttonsFound ? canAccessButtons : door.HasAccess(character);
|
||||
|
||||
bool CanAccessButton(Controller button) => button.HasAccess(character) && (buttonFilter == null || buttonFilter(button));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,12 +728,15 @@ namespace Barotrauma
|
||||
float distance = Vector2.DistanceSquared(button.Item.WorldPosition, character.WorldPosition);
|
||||
//heavily prefer buttons linked to the door, so sub builders can help the bots figure out which button to use by linking them
|
||||
if (door.Item.linkedTo.Contains(button.Item)) { distance *= 0.1f; }
|
||||
if (closestButton == null || distance < closestDist && character.CanSeeTarget(button.Item))
|
||||
if (closestButton == null || distance < closestDist)
|
||||
{
|
||||
closestButton = button;
|
||||
closestDist = distance;
|
||||
if (distance < MathUtils.Pow2(button.Item.InteractDistance + GetColliderLength()) && character.CanSeeTarget(button.Item))
|
||||
{
|
||||
closestButton = button;
|
||||
closestDist = distance;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return closestButton != null;
|
||||
});
|
||||
if (canAccess)
|
||||
{
|
||||
@@ -741,41 +759,19 @@ namespace Barotrauma
|
||||
}
|
||||
else if (closestButton != null)
|
||||
{
|
||||
if (closestDist < MathUtils.Pow2(closestButton.Item.InteractDistance + GetColliderLength()))
|
||||
if (pressButton)
|
||||
{
|
||||
if (pressButton)
|
||||
if (closestButton.Item.TryInteract(character, forceSelectKey: true))
|
||||
{
|
||||
if (closestButton.Item.TryInteract(character, forceSelectKey: true))
|
||||
{
|
||||
lastDoor = (door, shouldBeOpen);
|
||||
buttonPressTimer = shouldBeOpen ? ButtonPressCooldown : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonPressTimer = 0;
|
||||
}
|
||||
lastDoor = (door, shouldBeOpen);
|
||||
buttonPressTimer = shouldBeOpen ? ButtonPressCooldown : 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't reach the button closest to the character.
|
||||
// It's possible that we could reach another buttons.
|
||||
// If this becomes an issue, we could go through them here and check if any of them are reachable
|
||||
// (would have to cache a collection of buttons instead of a single reference in the CanAccess filter method above)
|
||||
var body = Submarine.PickBody(character.SimPosition, character.GetRelativeSimPosition(closestButton.Item), collisionCategory: Physics.CollisionWall | Physics.CollisionLevel);
|
||||
if (body != null)
|
||||
else
|
||||
{
|
||||
if (body.UserData is Item item)
|
||||
{
|
||||
var d = item.GetComponent<Door>();
|
||||
if (d == null || d.IsOpen) { return; }
|
||||
}
|
||||
// The button is on the wrong side of the door or a wall
|
||||
currentPath.Unreachable = true;
|
||||
buttonPressTimer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (shouldBeOpen)
|
||||
@@ -796,10 +792,9 @@ namespace Barotrauma
|
||||
float? penalty = GetSingleNodePenalty(nextNode);
|
||||
if (penalty == null) { return null; }
|
||||
bool nextNodeAboveWaterLevel = nextNode.Waypoint.CurrentHull != null && nextNode.Waypoint.CurrentHull.Surface < nextNode.Waypoint.Position.Y;
|
||||
//non-humanoids can't climb up ladders
|
||||
if (!(character.AnimController is HumanoidAnimController))
|
||||
if (!character.CanClimb)
|
||||
{
|
||||
if (node.Waypoint.Ladders != null && nextNode.Waypoint.Ladders != null && (!nextNode.Waypoint.Ladders.Item.IsInteractable(character) || character.LockHands)||
|
||||
if (node.Waypoint.Ladders != null && nextNode.Waypoint.Ladders != null && (!nextNode.Waypoint.Ladders.Item.IsInteractable(character) || character.LockHands) ||
|
||||
(nextNode.Position.Y - node.Position.Y > 1.0f && //more than one sim unit to climb up
|
||||
nextNodeAboveWaterLevel)) //upper node not underwater
|
||||
{
|
||||
@@ -847,7 +842,7 @@ namespace Barotrauma
|
||||
if (!node.Waypoint.IsTraversable) { return null; }
|
||||
if (node.IsBlocked()) { return null; }
|
||||
float penalty = 0.0f;
|
||||
if (node.Waypoint.ConnectedGap != null && node.Waypoint.ConnectedGap.Open < 0.9f)
|
||||
if (node.Waypoint.ConnectedGap is { Open: < 0.9f })
|
||||
{
|
||||
var door = node.Waypoint.ConnectedDoor;
|
||||
if (door == null)
|
||||
@@ -858,19 +853,29 @@ namespace Barotrauma
|
||||
{
|
||||
if (!CanAccessDoor(door, button =>
|
||||
{
|
||||
// Ignore buttons that are on the wrong side of the door
|
||||
if (Vector2.DistanceSquared(door.Item.WorldPosition, button.Item.WorldPosition) > MathUtils.Pow2(button.Item.InteractDistance + GetColliderLength()))
|
||||
{
|
||||
// Too far from the door.
|
||||
return false;
|
||||
}
|
||||
if (!ISpatialEntity.IsTargetVisible(button.Item, door.Item))
|
||||
{
|
||||
// Obstructed.
|
||||
return false;
|
||||
}
|
||||
// Ignore buttons that are on the wrong side of the door, unless there's a motion sensor connected to the door, which can be triggered by the character.
|
||||
if (door.IsHorizontal)
|
||||
{
|
||||
if (Math.Sign(button.Item.WorldPosition.Y - door.Item.WorldPosition.Y) != Math.Sign(character.WorldPosition.Y - door.Item.WorldPosition.Y))
|
||||
{
|
||||
return false;
|
||||
return door.Item.GetDirectlyConnectedComponent<MotionSensor>() is MotionSensor ms && ms.TriggersOn(character);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Math.Sign(button.Item.WorldPosition.X - door.Item.WorldPosition.X) != Math.Sign(character.WorldPosition.X - door.Item.WorldPosition.X))
|
||||
{
|
||||
return false;
|
||||
return door.Item.GetDirectlyConnectedComponent<MotionSensor>() is MotionSensor ms && ms.TriggersOn(character);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user