From b49f47d3d9508b7e13a103fbf70bdb2c6222cfae Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Fri, 2 Mar 2018 17:45:13 +0200 Subject: [PATCH] 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. --- .../Characters/AI/IndoorsSteeringManager.cs | 58 ++++++++------ .../Source/Characters/Animation/Ragdoll.cs | 3 +- .../BarotraumaShared/Source/Map/WayPoint.cs | 76 +++++++++---------- 3 files changed, 74 insertions(+), 63 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs index b3a25d3db..97990978f 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs @@ -145,46 +145,56 @@ namespace Barotrauma 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) { 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 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) + float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY; + if (heightFromFloor <= 0.0f) { - float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY; - - //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 - if ((heightFromFloor > 0.0f && heightFromFloor < collider.height) || - (currentPath.NextNode != null && currentPath.NextNode.Ladders != null)) + 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 + 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; 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; } @@ -257,7 +267,7 @@ namespace Barotrauma return; } - closestButton.Item.TryInteract(character, false, true); + closestButton.Item.TryInteract(character, false, true, true); break; } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index 5ec638763..4ce8540ae 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -893,7 +893,8 @@ namespace Barotrauma else { 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; } diff --git a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs index 4076a3db1..1e371a465 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs @@ -302,62 +302,70 @@ namespace Barotrauma var ladders = item.GetComponent(); if (ladders == null) continue; - WayPoint[] ladderPoints = new WayPoint[2]; - - 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); + List ladderPoints = new List(); + ladderPoints.Add(new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height + heightFromFloor), SpawnType.Path, submarine)); WayPoint prevPoint = ladderPoints[0]; Vector2 prevPos = prevPoint.SimPosition; - List ignoredBodies = new List(); - - while (prevPoint != ladderPoints[1]) + for (float y = ladderPoints[0].Position.Y + 100.0f; y < item.Rect.Y - 100.0f; y += 100.0f) { - 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); - if (pickedBody.UserData is Item) + if (pickedBody.UserData is Item && ((Item)pickedBody.UserData).GetComponent() != null) { var door = ((Item)pickedBody.UserData).GetComponent(); - if (door != null) - { - WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine); - newPoint.Ladders = ladders; - newPoint.ConnectedGap = door.LinkedGap; - newPoint.ConnectTo(prevPoint); - - prevPoint = newPoint; - - prevPos = ConvertUnits.ToSimUnits(door.Item.Position - Vector2.UnitY * door.Item.Rect.Height); - } - else - { - prevPos = Submarine.LastPickedPosition; - } + WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine); + ladderPoints.Add(newPoint); + newPoint.ConnectedGap = door.LinkedGap; + newPoint.ConnectTo(prevPoint); + prevPoint = newPoint; + prevPos = new Vector2(prevPos.X, ConvertUnits.ToSimUnits(door.Item.Position.Y - door.Item.Rect.Height)); } 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]); - - for (int i = 0; i < 2; i++) + ladderPoints.Add(new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - 1.0f), SpawnType.Path, submarine)); + + prevPoint.ConnectTo(ladderPoints[ladderPoints.Count - 1]); + + for (int i = 0; i < ladderPoints.Count; i++) { ladderPoints[i].Ladders = ladders; - 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); } + + 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( 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()); @@ -460,7 +461,6 @@ namespace Barotrauma } } - return closest; }