From 48c07cfce5ab94b9a3db0a9f9174ba2e4228fa77 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 27 Oct 2016 21:18:45 +0300 Subject: [PATCH] - doors aren't ignored when checking visibility during waypoint generation or when finding a starting node for a path - AICharacter will mark their path unreachable if their path is blocked by a door they cant open (may happen if someone closes the door after calculating the path) - fixed exception when creating a Steering component when there's no active GameSession (i.e. in the editor) --- .../Source/Characters/AI/HumanAIController.cs | 5 ++++ .../Characters/AI/IndoorsSteeringManager.cs | 6 +++++ Subsurface/Source/Characters/AI/PathFinder.cs | 7 ++++- .../Items/Components/Machines/Steering.cs | 4 +-- Subsurface/Source/Map/WayPoint.cs | 26 ++++++++++++------- Subsurface/Source/Physics/PhysicsBody.cs | 2 +- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs index 68b2e0102..fe25a7bb6 100644 --- a/Subsurface/Source/Characters/AI/HumanAIController.cs +++ b/Subsurface/Source/Characters/AI/HumanAIController.cs @@ -185,6 +185,11 @@ namespace Barotrauma new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y), new Vector2(pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.Y), Color.LightGreen); + + spriteBatch.DrawString(GUI.SmallFont, + pathSteering.CurrentPath.Nodes[i].ID.ToString(), + new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y - 10), + Color.LightGreen); } } } diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index 3d3320bcc..a1aa98d75 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -258,6 +258,12 @@ namespace Barotrauma if (closestButton != null) { + if (!closestButton.HasRequiredItems(character, false) && shouldBeOpen) + { + currentPath.Unreachable = true; + return; + } + closestButton.Item.Pick(character, false, true); break; } diff --git a/Subsurface/Source/Characters/AI/PathFinder.cs b/Subsurface/Source/Characters/AI/PathFinder.cs index 45dd9a4c5..7ddef2f11 100644 --- a/Subsurface/Source/Characters/AI/PathFinder.cs +++ b/Subsurface/Source/Characters/AI/PathFinder.cs @@ -172,7 +172,12 @@ namespace Barotrauma start, node.Waypoint.SimPosition, null, Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs | Physics.CollisionPlatform); - if (body != null && body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; + if (body != null) + { + if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; + if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; + + } } closestDist = dist; diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index d11797694..6c97cf2ff 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -123,14 +123,14 @@ namespace Barotrauma.Items.Components levelStartTickBox = new GUITickBox( new Rectangle(5, 70, 15, 15), - ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), + GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), Alignment.TopLeft, GUI.SmallFont, GuiFrame); levelStartTickBox.Enabled = false; levelStartTickBox.OnSelected = SelectDestination; levelEndTickBox = new GUITickBox( new Rectangle(5, 90, 15, 15), - ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, 20), + GameMain.GameSession == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), Alignment.TopLeft, GUI.SmallFont, GuiFrame); levelEndTickBox.Enabled = false; levelEndTickBox.OnSelected = SelectDestination; diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 7b6809526..efb67f350 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -437,11 +437,11 @@ namespace Barotrauma WayPoint[] stairPoints = new WayPoint[2]; stairPoints[0] = new WayPoint( - new Vector2(stairs.Rect.X - 75.0f, + new Vector2(stairs.Rect.X - 32.0f, stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? 80 : stairs.Rect.Height) + heightFromFloor), SpawnType.Path, submarine); stairPoints[1] = new WayPoint( - new Vector2(stairs.Rect.Right + 75.0f, + new Vector2(stairs.Rect.Right + 32.0f, stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? stairs.Rect.Height : 80) + heightFromFloor), SpawnType.Path, submarine); for (int i = 0; i < 2; i++ ) @@ -536,11 +536,11 @@ namespace Barotrauma //ladderPoints[0].ConnectTo(ladderPoints[1]); } - + foreach (Gap gap in Gap.GapList) { if (!gap.isHorizontal) continue; - + //too small to walk through if (gap.Rect.Height < 150.0f) continue; @@ -550,9 +550,15 @@ namespace Barotrauma for (int dir = -1; dir <= 1; dir += 2) { float tolerance = gap.IsRoomToRoom ? 50.0f : outSideWaypointInterval / 2.0f; - WayPoint closest = wayPoint.FindClosest(dir, true, new Vector2(-tolerance, tolerance)); - if (closest == null) continue; - wayPoint.ConnectTo(closest); + + WayPoint closest = wayPoint.FindClosest( + dir, true, new Vector2(-tolerance, tolerance), + gap.ConnectedDoor == null ? null : gap.ConnectedDoor.Body.FarseerBody); + + if (closest != null) + { + wayPoint.ConnectTo(closest); + } } } @@ -582,7 +588,7 @@ namespace Barotrauma } } - private WayPoint FindClosest(int dir, bool horizontalSearch, Vector2 tolerance) + private WayPoint FindClosest(int dir, bool horizontalSearch, Vector2 tolerance, Body ignoredBody = null) { if (dir != -1 && dir != 1) return null; @@ -614,9 +620,9 @@ namespace Barotrauma if (closest == null || dist < closestDist) { var body = Submarine.CheckVisibility(SimPosition, wp.SimPosition, true); - if (body != null) + if (body != null && body != ignoredBody && !(body.UserData is Submarine)) { - if (body.UserData is Structure) continue; + if (body.UserData is Structure || body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; } closestDist = dist; diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index e3e4b2e25..f528d4af9 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -231,7 +231,7 @@ namespace Barotrauma public PhysicsBody(Body farseerBody) { body = farseerBody; - body.UserData = this; + if (body.UserData == null) body.UserData = this; LastSentPosition = body.Position;