Ladder waypoint generation fix: waypoints are not just placed at the top and bottom of the ladders (and at hatches on the ladders), but above every platform along the ladders (-> waypoints work correctly on ladders spanning through multiple floors). + Some ladder climbing fixes in IndoorsSteeringManager.
This commit is contained in:
@@ -145,46 +145,56 @@ namespace Barotrauma
|
|||||||
currentPath.CurrentNode.Ladders.Item.TryInteract(character, false, true);
|
currentPath.CurrentNode.Ladders.Item.TryInteract(character, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var collider = character.AnimController.Collider;
|
|
||||||
Vector2 colliderBottom = character.AnimController.GetColliderBottom();
|
|
||||||
|
|
||||||
if (Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X) < collider.radius * 2 &&
|
|
||||||
currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y &&
|
|
||||||
currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + 1.5f)
|
|
||||||
{
|
|
||||||
currentPath.SkipToNextNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPath.CurrentNode == null) return Vector2.Zero;
|
|
||||||
|
|
||||||
|
var collider = character.AnimController.Collider;
|
||||||
|
|
||||||
if (character.AnimController.Anim == AnimController.Animation.Climbing)
|
if (character.AnimController.Anim == AnimController.Animation.Climbing)
|
||||||
{
|
{
|
||||||
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
|
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
|
||||||
|
|
||||||
if (currentPath.CurrentNode.Ladders != null)
|
//climbing ladders -> don't move horizontally
|
||||||
|
diff.X = 0.0f;
|
||||||
|
|
||||||
|
//at the same height as the waypoint
|
||||||
|
if (Math.Abs(collider.SimPosition.Y - currentPath.CurrentNode.SimPosition.Y) < (collider.height / 2 + collider.radius) * 1.25f)
|
||||||
{
|
{
|
||||||
//climbing ladders -> don't move horizontally
|
//climbing ladders -> don't move horizontally
|
||||||
diff.X = 0.0f;
|
diff.X = 0.0f;
|
||||||
|
|
||||||
//at the same height as the waypoint
|
float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY;
|
||||||
if (Math.Abs(collider.SimPosition.Y - currentPath.CurrentNode.SimPosition.Y) < collider.height / 2 + collider.radius)
|
if (heightFromFloor <= 0.0f)
|
||||||
{
|
{
|
||||||
float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY;
|
diff.Y = Math.Max(diff.Y, 1.0f);
|
||||||
|
}
|
||||||
//we can safely skip to the next waypoint if the character is at a safe height above the floor,
|
|
||||||
//or if the next waypoint in the path is also on ladders
|
//we can safely skip to the next waypoint if the character is at a safe height above the floor,
|
||||||
if ((heightFromFloor > 0.0f && heightFromFloor < collider.height) ||
|
//or if the next waypoint in the path is also on ladders
|
||||||
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null))
|
if ((heightFromFloor > 0.0f && heightFromFloor < collider.height * 1.5f) ||
|
||||||
|
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null))
|
||||||
|
{
|
||||||
|
if (currentPath.NextNode.Ladders == null)
|
||||||
{
|
{
|
||||||
currentPath.SkipToNextNode();
|
character.AnimController.Anim = AnimController.Animation.None;
|
||||||
}
|
}
|
||||||
|
currentPath.SkipToNextNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
character.AnimController.IgnorePlatforms = false;
|
character.AnimController.IgnorePlatforms = false;
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector2 colliderBottom = character.AnimController.GetColliderBottom();
|
||||||
|
if (Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X) < collider.radius * 2 &&
|
||||||
|
currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y &&
|
||||||
|
currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + 1.5f)
|
||||||
|
{
|
||||||
|
currentPath.SkipToNextNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPath.CurrentNode == null) return Vector2.Zero;
|
||||||
|
|
||||||
return currentPath.CurrentNode.SimPosition - pos;
|
return currentPath.CurrentNode.SimPosition - pos;
|
||||||
}
|
}
|
||||||
@@ -257,7 +267,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
closestButton.Item.TryInteract(character, false, true);
|
closestButton.Item.TryInteract(character, false, true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -893,7 +893,8 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
float waterSurface = ConvertUnits.ToSimUnits(currentHull.Surface);
|
float waterSurface = ConvertUnits.ToSimUnits(currentHull.Surface);
|
||||||
if (Collider.SimPosition.Y < waterSurface && waterSurface - GetFloorY() > HeadPosition * 0.95f)
|
floorY = GetFloorY();
|
||||||
|
if (Collider.SimPosition.Y < waterSurface && waterSurface - floorY > HeadPosition * 0.95f)
|
||||||
{
|
{
|
||||||
inWater = true;
|
inWater = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,62 +302,70 @@ namespace Barotrauma
|
|||||||
var ladders = item.GetComponent<Items.Components.Ladder>();
|
var ladders = item.GetComponent<Items.Components.Ladder>();
|
||||||
if (ladders == null) continue;
|
if (ladders == null) continue;
|
||||||
|
|
||||||
WayPoint[] ladderPoints = new WayPoint[2];
|
List<WayPoint> ladderPoints = new List<WayPoint>();
|
||||||
|
ladderPoints.Add(new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height + heightFromFloor), SpawnType.Path, submarine));
|
||||||
ladderPoints[0] = new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height + heightFromFloor), SpawnType.Path, submarine);
|
|
||||||
ladderPoints[1] = new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y-1.0f), SpawnType.Path, submarine);
|
|
||||||
|
|
||||||
WayPoint prevPoint = ladderPoints[0];
|
WayPoint prevPoint = ladderPoints[0];
|
||||||
Vector2 prevPos = prevPoint.SimPosition;
|
Vector2 prevPos = prevPoint.SimPosition;
|
||||||
|
|
||||||
List<Body> ignoredBodies = new List<Body>();
|
List<Body> ignoredBodies = new List<Body>();
|
||||||
|
for (float y = ladderPoints[0].Position.Y + 100.0f; y < item.Rect.Y - 100.0f; y += 100.0f)
|
||||||
while (prevPoint != ladderPoints[1])
|
|
||||||
{
|
{
|
||||||
var pickedBody = Submarine.PickBody(prevPos, ladderPoints[1].SimPosition, ignoredBodies, null, false);
|
var pickedBody = Submarine.PickBody(
|
||||||
|
ConvertUnits.ToSimUnits(new Vector2(ladderPoints[0].Position.X, y)), prevPos,
|
||||||
|
ignoredBodies, null, false);
|
||||||
|
|
||||||
if (pickedBody == null) break;
|
if (pickedBody == null)
|
||||||
|
{
|
||||||
|
prevPos = Submarine.LastPickedPosition;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ignoredBodies.Add(pickedBody);
|
ignoredBodies.Add(pickedBody);
|
||||||
|
|
||||||
if (pickedBody.UserData is Item)
|
if (pickedBody.UserData is Item && ((Item)pickedBody.UserData).GetComponent<Door>() != null)
|
||||||
{
|
{
|
||||||
var door = ((Item)pickedBody.UserData).GetComponent<Door>();
|
var door = ((Item)pickedBody.UserData).GetComponent<Door>();
|
||||||
if (door != null)
|
|
||||||
{
|
|
||||||
WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine);
|
|
||||||
newPoint.Ladders = ladders;
|
|
||||||
newPoint.ConnectedGap = door.LinkedGap;
|
|
||||||
|
|
||||||
newPoint.ConnectTo(prevPoint);
|
WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine);
|
||||||
|
ladderPoints.Add(newPoint);
|
||||||
prevPoint = newPoint;
|
newPoint.ConnectedGap = door.LinkedGap;
|
||||||
|
newPoint.ConnectTo(prevPoint);
|
||||||
prevPos = ConvertUnits.ToSimUnits(door.Item.Position - Vector2.UnitY * door.Item.Rect.Height);
|
prevPoint = newPoint;
|
||||||
}
|
prevPos = new Vector2(prevPos.X, ConvertUnits.ToSimUnits(door.Item.Position.Y - door.Item.Rect.Height));
|
||||||
else
|
|
||||||
{
|
|
||||||
prevPos = Submarine.LastPickedPosition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevPos = Submarine.LastPickedPosition;
|
WayPoint newPoint = new WayPoint(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition) + Vector2.UnitY * heightFromFloor, SpawnType.Path, submarine);
|
||||||
|
ladderPoints.Add(newPoint);
|
||||||
|
newPoint.ConnectTo(prevPoint);
|
||||||
|
prevPoint = newPoint;
|
||||||
|
prevPos = ConvertUnits.ToSimUnits(newPoint.Position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevPoint.ConnectTo(ladderPoints[1]);
|
ladderPoints.Add(new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - 1.0f), SpawnType.Path, submarine));
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
prevPoint.ConnectTo(ladderPoints[ladderPoints.Count - 1]);
|
||||||
|
|
||||||
|
for (int i = 0; i < ladderPoints.Count; i++)
|
||||||
{
|
{
|
||||||
ladderPoints[i].Ladders = ladders;
|
ladderPoints[i].Ladders = ladders;
|
||||||
|
|
||||||
for (int dir = -1; dir <= 1; dir += 2)
|
for (int dir = -1; dir <= 1; dir += 2)
|
||||||
{
|
{
|
||||||
WayPoint closest = ladderPoints[i].FindClosest(dir, true, new Vector2(-150.0f, 10f));
|
WayPoint closest = ladderPoints[i].FindClosest(dir, true, new Vector2(-150.0f, 10f));
|
||||||
if (closest == null) continue;
|
if (closest == null) continue;
|
||||||
ladderPoints[i].ConnectTo(closest);
|
ladderPoints[i].ConnectTo(closest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == ladderPoints.Count - 1 && ladderPoints.Count > 2)
|
||||||
|
{
|
||||||
|
for (int dir = -1; dir <= 1; dir += 2)
|
||||||
|
{
|
||||||
|
WayPoint closest = ladderPoints[i].FindClosest(dir, true, new Vector2(-150.0f, 10f));
|
||||||
|
if (closest == null) continue;
|
||||||
|
ladderPoints[i].ConnectTo(closest);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,13 +403,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var wayPoint = new WayPoint(
|
var wayPoint = new WayPoint(
|
||||||
new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height / 2), SpawnType.Path, submarine, gap);
|
new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height / 2), SpawnType.Path, submarine, gap);
|
||||||
|
|
||||||
for (int dir = -1; dir <= 1; dir += 2)
|
|
||||||
{
|
|
||||||
WayPoint closest = wayPoint.FindClosest(dir, false, new Vector2(-outSideWaypointInterval, outSideWaypointInterval) / 2.0f);
|
|
||||||
if (closest == null) continue;
|
|
||||||
wayPoint.ConnectTo(closest);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var orphans = WayPointList.FindAll(w => w.spawnType == SpawnType.Path && !w.linkedTo.Any());
|
var orphans = WayPointList.FindAll(w => w.spawnType == SpawnType.Path && !w.linkedTo.Any());
|
||||||
@@ -460,7 +461,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user