diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index 05d3bbd44..83c22d31b 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -33,12 +33,6 @@ namespace Barotrauma get { return currentTarget; } } - public bool HasOutdoorsNodes - { - get; - private set; - } - public IndoorsSteeringManager(ISteerable host, bool canOpenDoors) : base(host) { @@ -87,8 +81,6 @@ namespace Barotrauma currentPath = pathFinder.FindPath(pos, target); - HasOutdoorsNodes = currentPath.Nodes.Find(n => n.CurrentHull == null) != null; - findPathTimer = Rand.Range(1.0f,1.2f); return DiffToCurrentNode(); diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs index d978607d4..342d76439 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs @@ -112,7 +112,7 @@ namespace Barotrauma { indoorsSteering.SteeringWander(); } - else if (getDivingGearIfNeeded && indoorsSteering.CurrentPath != null && indoorsSteering.HasOutdoorsNodes) + else if (getDivingGearIfNeeded && indoorsSteering.CurrentPath != null && indoorsSteering.CurrentPath.HasOutdoorsNodes) { AddSubObjective(new AIObjectiveFindDivingGear(character, true)); } diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs index 0b9540f3f..49073653d 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -54,9 +54,12 @@ namespace Barotrauma newTargetTimer -= deltaTime; - //wander randomly if reached the end of the path or the target is unreachable + //wander randomly + // - if reached the end of the path + // - if the target is unreachable + // - if the path requires going outside if (pathSteering==null || (pathSteering.CurrentPath != null && - (pathSteering.CurrentPath.NextNode == null || pathSteering.CurrentPath.Unreachable))) + (pathSteering.CurrentPath.NextNode == null || pathSteering.CurrentPath.Unreachable || pathSteering.CurrentPath.HasOutdoorsNodes))) { //steer away from edges of the hull if (character.AnimController.CurrentHull!=null) diff --git a/Subsurface/Source/Characters/AI/SteeringPath.cs b/Subsurface/Source/Characters/AI/SteeringPath.cs index 2a98ac366..9229c08a9 100644 --- a/Subsurface/Source/Characters/AI/SteeringPath.cs +++ b/Subsurface/Source/Characters/AI/SteeringPath.cs @@ -25,6 +25,14 @@ namespace Barotrauma { if (node == null) return; nodes.Add(node); + + if (node.CurrentHull == null) HasOutdoorsNodes = true; + } + + public bool HasOutdoorsNodes + { + get; + private set; } public int CurrentIndex diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs index a600e0cfc..47075b53f 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs @@ -260,7 +260,7 @@ namespace Barotrauma.Tutorials infoBox = CreateInfoFrame("The green rectangle in the middle is the submarine, and the flickering shapes outside it are the walls of an underwater cavern. " + "Try moving the submarine by clicking somewhere on the monitor and dragging the pointer to the direction you want to go to."); - while (steering.CurrTargetVelocity == Vector2.Zero && steering.CurrTargetVelocity.Length() < 50.0f) + while (steering.TargetVelocity == Vector2.Zero && steering.TargetVelocity.Length() < 50.0f) { yield return CoroutineStatus.Running; } diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index b0afc57d6..9a4e6cdf4 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -81,7 +81,7 @@ namespace Barotrauma.Items.Components } } - private Vector2 TargetVelocity + public Vector2 TargetVelocity { get { return targetVelocity;} set @@ -91,12 +91,7 @@ namespace Barotrauma.Items.Components targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f); } } - - public Vector2 CurrTargetVelocity - { - get { return targetVelocity; } - } - + public SteeringPath SteeringPath { get { return steeringPath; } @@ -227,7 +222,7 @@ namespace Barotrauma.Items.Components steeringPath.CheckProgress(ConvertUnits.ToSimUnits(item.Submarine.WorldPosition), 10.0f); if (autopilotRayCastTimer <= 0.0f && steeringPath.NextNode != null) - { + { Vector2 diff = Vector2.Normalize(ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - item.Submarine.WorldPosition)); bool nextVisible = true; @@ -259,6 +254,25 @@ namespace Barotrauma.Items.Components { SteerTowardsPosition(steeringPath.CurrentNode.WorldPosition); } + + foreach (Submarine sub in Submarine.Loaded) + { + if (sub == item.Submarine) continue; + + float thisSize = Math.Max(item.Submarine.Borders.Width, item.Submarine.Borders.Height); + float otherSize = Math.Max(sub.Borders.Width, sub.Borders.Height); + + Vector2 diff = sub.WorldPosition - item.Submarine.WorldPosition; + + float dist = diff == Vector2.Zero ? 0.0f : diff.Length(); + + if (dist > thisSize + otherSize) continue; + + diff = Vector2.Normalize(diff); + + TargetVelocity = Vector2.Lerp(-diff * 100.0f, TargetVelocity, (dist / (thisSize + otherSize)) - 0.5f); + } + } private void SteerTowardsPosition(Vector2 worldPosition) @@ -275,7 +289,7 @@ namespace Barotrauma.Items.Components } else { - targetVelocity = targetSpeed/5.0f; + TargetVelocity = targetSpeed/5.0f; }