Bunch of crew AI bugfixes/improvements:

- replacing empty oxygen tanks
- fixed characters only fixing leaks in the outer hull
- prioritizing large leaks over small ones
- fixed characters doing nothing after fixing all the leaks (and sinking to the bottom if they happen to be outside)
- more accurate welder aiming
- AIObjectiveGetItem makes the characters go to the cabinet/container an item is inside, not to the actual item (which may not be actually positioned at the container)
This commit is contained in:
Regalis
2016-03-16 17:41:59 +02:00
parent 804510b144
commit d6a57f9533
15 changed files with 228 additions and 163 deletions
@@ -45,16 +45,22 @@ namespace Barotrauma
if (containedItems == null) return; if (containedItems == null) return;
//check if there's an oxygen tank in the mask //check if there's an oxygen tank in the mask
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f); var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank");
if (oxygenTank != null) if (oxygenTank != null)
{ {
//isCompleted = true; if (oxygenTank.Condition > 0.0f)
return; {
return;
}
else
{
oxygenTank.Drop();
}
} }
if (!(subObjective is AIObjectiveContainItem)) if (!(subObjective is AIObjectiveContainItem) || subObjective.IsCompleted())
{ {
subObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>()); subObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>());
} }
@@ -68,6 +74,13 @@ namespace Barotrauma
} }
} }
public override float GetPriority(Character character)
{
if (character.AnimController.CurrentHull == null) return 100.0f;
return 100.0f - character.Oxygen;
}
public override bool IsDuplicate(AIObjective otherObjective) public override bool IsDuplicate(AIObjective otherObjective)
{ {
return otherObjective is AIObjectiveFindDivingGear; return otherObjective is AIObjectiveFindDivingGear;
@@ -29,68 +29,41 @@ namespace Barotrauma
protected override void Act(float deltaTime) protected override void Act(float deltaTime)
{ {
if (character.AnimController.CurrentHull == null) return;
currenthullSafety = OverrideCurrentHullSafety == null ?
GetHullSafety(character.AnimController.CurrentHull) : (float)OverrideCurrentHullSafety;
if (character.AnimController.CurrentHull == null || currenthullSafety > MinSafety)
{
character.AIController.SteeringManager.SteeringSeek(character.AnimController.CurrentHull.SimPosition);
character.AIController.SelectTarget(null);
goToObjective = null;
return;
}
var currentHull = character.AnimController.CurrentHull; var currentHull = character.AnimController.CurrentHull;
if (currentHull.Volume / currentHull.FullVolume > 0.5f)
currenthullSafety = OverrideCurrentHullSafety == null ?
GetHullSafety(currentHull) : (float)OverrideCurrentHullSafety;
if (currentHull != null)
{ {
if (!FindDivingGear(deltaTime)) return; if (currentHull.Volume / currentHull.FullVolume > 0.5f || character.Oxygen < 80.0f)
{
if (!FindDivingGear(deltaTime)) return;
}
if (currenthullSafety > MinSafety)
{
character.AIController.SteeringManager.SteeringSeek(currentHull.SimPosition, 0.5f);
character.AIController.SelectTarget(null);
goToObjective = null;
return;
}
} }
if (searchHullTimer>0.0f) if (searchHullTimer > 0.0f)
{ {
searchHullTimer -= deltaTime; searchHullTimer -= deltaTime;
//return;
} }
else else
{ {
Hull bestHull = null; var bestHull = FindBestHull();
float bestValue = currenthullSafety;
foreach (Hull hull in Hull.hullList)
{
if (hull == character.AnimController.CurrentHull) continue;
if (unreachable.Contains(hull)) continue;
float hullValue = GetHullSafety(hull);
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X- hull.Position.X));
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y)*2.0f);
if (bestHull == null || hullValue > bestValue)
{
bestHull = hull;
bestValue = hullValue;
}
}
if (bestHull != null) if (bestHull != null)
{ {
//var path = pathSteering.PathFinder.FindPath(character.SimPosition, bestHull.SimPosition); goToObjective = new AIObjectiveGoTo(bestHull, character);
//if (pathSteering.CurrentPath == null || (pathSteering.CurrentPath.NextNode==null && pathSteering.CurrentPath.Cost > path.Cost) ||
// pathSteering.CurrentPath.Unreachable || goToObjective==null)
//{
//pathSteering.SetPath(path);
goToObjective = new AIObjectiveGoTo(bestHull, character);
//}
//haracter.AIController.SelectTarget(bestHull.AiTarget);
} }
searchHullTimer = SearchHullInterval; searchHullTimer = SearchHullInterval;
} }
@@ -117,43 +90,29 @@ namespace Barotrauma
divingGearObjective.TryComplete(deltaTime); divingGearObjective.TryComplete(deltaTime);
return divingGearObjective.IsCompleted(); return divingGearObjective.IsCompleted();
}
//var item = character.Inventory.FindItem("diving"); private Hull FindBestHull()
//if (item == null) {
//{ Hull bestHull = null;
// //get a diving mask/suit first float bestValue = currenthullSafety;
// if (!(divingGearObjective is AIObjectiveGetItem))
// {
// divingGearObjective = new AIObjectiveGetItem(character, "diving", true);
// }
//}
//else
//{
// var containedItems = item.ContainedItems;
// if (containedItems == null) return true;
// //check if there's an oxygen tank in the mask foreach (Hull hull in Hull.hullList)
// var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f); {
if (hull == character.AnimController.CurrentHull || unreachable.Contains(hull)) continue;
// if (oxygenTank != null) return true; float hullValue = GetHullSafety(hull);
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X - hull.Position.X));
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y) * 2.0f);
if (bestHull == null || hullValue > bestValue)
{
bestHull = hull;
bestValue = hullValue;
}
}
// if (!(divingGearObjective is AIObjectiveContainItem)) return bestHull;
// {
// divingGearObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent<ItemContainer>());
// }
//}
//if (divingGearObjective != null)
//{
// divingGearObjective.TryComplete(deltaTime);
// bool isCompleted = divingGearObjective.IsCompleted();
// if (isCompleted) divingGearObjective = null;
// return isCompleted;
//}
//return false;
} }
public override bool IsDuplicate(AIObjective otherObjective) public override bool IsDuplicate(AIObjective otherObjective)
@@ -163,11 +122,15 @@ namespace Barotrauma
public override float GetPriority(Character character) public override float GetPriority(Character character)
{ {
if (character.AnimController.CurrentHull == null) return 0.0f; if (character.Oxygen < 80.0f)
{
return 150.0f - character.Oxygen;
}
if (character.AnimController.CurrentHull == null) return 5.0f;
currenthullSafety = GetHullSafety(character.AnimController.CurrentHull); currenthullSafety = GetHullSafety(character.AnimController.CurrentHull);
priority = 100.0f - currenthullSafety; priority = 100.0f - currenthullSafety;
if (divingGearObjective != null && !divingGearObjective.IsCompleted()) priority += 20.0f; if (divingGearObjective != null && !divingGearObjective.IsCompleted()) priority += 20.0f;
return priority; return priority;
@@ -175,6 +138,8 @@ namespace Barotrauma
private float GetHullSafety(Hull hull) private float GetHullSafety(Hull hull)
{ {
if (hull == null) return 0.0f;
float waterPercentage = (hull.Volume / hull.FullVolume)*100.0f; float waterPercentage = (hull.Volume / hull.FullVolume)*100.0f;
float fireAmount = 0.0f; float fireAmount = 0.0f;
@@ -185,7 +150,7 @@ namespace Barotrauma
float safety = 100.0f - fireAmount; float safety = 100.0f - fireAmount;
if (waterPercentage > 30.0f && character.Oxygen<80.0f) safety -= waterPercentage; if (waterPercentage > 30.0f && character.OxygenAvailable<=0.0f) safety -= waterPercentage;
if (hull.OxygenPercentage < 30.0f) safety -= (30.0f-hull.OxygenPercentage)*5.0f; if (hull.OxygenPercentage < 30.0f) safety -= (30.0f-hull.OxygenPercentage)*5.0f;
return safety; return safety;
@@ -63,14 +63,15 @@ namespace Barotrauma
} }
} }
if (Vector2.Distance(character.Position, leak.Position) > 300.0f) var repairTool = weldingTool.GetComponent<RepairTool>();
if (repairTool == null) return;
if (Vector2.Distance(character.WorldPosition, leak.WorldPosition) > 300.0f)
{ {
AddSubObjective(new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character)); AddSubObjective(new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character));
} }
else else
{ {
var repairTool = weldingTool.GetComponent<RepairTool>();
if (repairTool == null) return;
AddSubObjective(new AIObjectiveOperateItem(repairTool, character, "", leak)); AddSubObjective(new AIObjectiveOperateItem(repairTool, character, "", leak));
} }
} }
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework; using System;
using Microsoft.Xna.Framework;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -10,6 +11,8 @@ namespace Barotrauma
private float updateGapListTimer; private float updateGapListTimer;
private AIObjectiveIdle idleObjective;
private List<AIObjectiveFixLeak> objectiveList; private List<AIObjectiveFixLeak> objectiveList;
public AIObjectiveFixLeaks(Character character) public AIObjectiveFixLeaks(Character character)
@@ -36,13 +39,19 @@ namespace Barotrauma
if (objectiveList.Any()) if (objectiveList.Any())
{ {
objectiveList[objectiveList.Count-1].TryComplete(deltaTime); objectiveList[objectiveList.Count - 1].TryComplete(deltaTime);
if (!objectiveList[objectiveList.Count-1].CanBeCompleted || objectiveList[objectiveList.Count-1].IsCompleted()) if (!objectiveList[objectiveList.Count - 1].CanBeCompleted ||
objectiveList[objectiveList.Count - 1].IsCompleted())
{ {
objectiveList.RemoveAt(objectiveList.Count - 1); objectiveList.RemoveAt(objectiveList.Count - 1);
} }
} }
else
{
if (idleObjective == null) idleObjective = new AIObjectiveIdle(character);
idleObjective.TryComplete(deltaTime);
}
} }
private void UpdateGapList() private void UpdateGapList()
@@ -51,13 +60,14 @@ namespace Barotrauma
foreach (Gap gap in Gap.GapList) foreach (Gap gap in Gap.GapList)
{ {
if (gap.IsRoomToRoom || gap.ConnectedDoor != null || gap.Open < 0.1f) continue; if (gap.ConnectedWall == null) continue;
if (gap.ConnectedDoor != null || gap.Open <= 0.0f) continue;
float dist = Vector2.DistanceSquared(character.WorldPosition, gap.WorldPosition); float gapPriority = GetGapFixPriority(gap);
int index = 0; int index = 0;
while (index<objectiveList.Count && while (index < objectiveList.Count &&
Vector2.DistanceSquared(objectiveList[index].Leak.WorldPosition, character.WorldPosition)>dist) GetGapFixPriority(objectiveList[index].Leak) < gapPriority)
{ {
index++; index++;
} }
@@ -66,6 +76,23 @@ namespace Barotrauma
} }
} }
private float GetGapFixPriority(Gap gap)
{
if (gap == null) return 0.0f;
//larger gap -> higher priority
float gapPriority = (gap.isHorizontal ? gap.Rect.Width : gap.Rect.Height) * gap.Open;
//prioritize gaps that are close
gapPriority /= Math.Max(Vector2.Distance(character.WorldPosition, gap.WorldPosition), 1.0f);
//gaps to outside are much higher priority
if (!gap.IsRoomToRoom) gapPriority *= 10.0f;
return gapPriority;
}
public override bool IsDuplicate(AIObjective otherObjective) public override bool IsDuplicate(AIObjective otherObjective)
{ {
return otherObjective is AIObjectiveFixLeaks; return otherObjective is AIObjectiveFixLeaks;
@@ -11,7 +11,7 @@ namespace Barotrauma
{ {
private string itemName; private string itemName;
private Item targetItem; private Item targetItem, moveToTarget;
private int currSearchIndex; private int currSearchIndex;
@@ -52,83 +52,96 @@ namespace Barotrauma
protected override void Act(float deltaTime) protected override void Act(float deltaTime)
{ {
if (targetItem != null) if (targetItem == null)
{ {
if (Vector2.Distance(character.Position, targetItem.Position) < targetItem.PickDistance) FindTargetItem();
if (targetItem == null) return;
}
if (Vector2.Distance(character.Position, moveToTarget.Position) < targetItem.PickDistance*2.0f)
{
int targetSlot = -1;
if (equip)
{ {
int targetSlot = -1; var pickable = targetItem.GetComponent<Pickable>();
if (equip) //check if all the slots required by the item are free
foreach (LimbSlot slots in pickable.AllowedSlots)
{ {
var pickable = targetItem.GetComponent<Pickable>(); if (slots.HasFlag(LimbSlot.Any)) continue;
//check if all the slots required by the item are free
foreach (LimbSlot slots in pickable.AllowedSlots)
{
if (slots.HasFlag(LimbSlot.Any)) continue;
for (int i = 0; i<character.Inventory.Items.Length; i++) for (int i = 0; i<character.Inventory.Items.Length; i++)
{ {
//slot not needed by the item, continue //slot not needed by the item, continue
if (!slots.HasFlag(CharacterInventory.limbSlots[i])) continue; if (!slots.HasFlag(CharacterInventory.limbSlots[i])) continue;
targetSlot = i; targetSlot = i;
//slot free, continue //slot free, continue
if (character.Inventory.Items[i] == null) continue; if (character.Inventory.Items[i] == null) continue;
//try to move the existing item to LimbSlot.Any and continue if successful //try to move the existing item to LimbSlot.Any and continue if successful
if (character.Inventory.TryPutItem(character.Inventory.Items[i], new List<LimbSlot>() { LimbSlot.Any }, false)) continue; if (character.Inventory.TryPutItem(character.Inventory.Items[i], new List<LimbSlot>() { LimbSlot.Any }, false)) continue;
//if everything else fails, simply drop the existing item //if everything else fails, simply drop the existing item
character.Inventory.Items[i].Drop(); character.Inventory.Items[i].Drop();
}
} }
} }
targetItem.Pick(character, false, true);
if (targetSlot>-1 && character.Inventory.IsInLimbSlot(targetItem, LimbSlot.Any))
{
character.Inventory.TryPutItem(targetItem, targetSlot, true, false);
}
} }
return; targetItem.Pick(character, false, true);
if (targetSlot > -1 && character.Inventory.IsInLimbSlot(targetItem, LimbSlot.Any))
{
character.Inventory.TryPutItem(targetItem, targetSlot, true, false);
}
}
else if (!subObjectives.Any())
{
AddGoToObjective(targetItem);
} }
}
for (int i = 0; i<10 && currSearchIndex<Item.ItemList.Count-2; i++) /// <summary>
/// searches for an item that matches the desired item and adds a goto subobjective if one is found
/// </summary>
private void FindTargetItem()
{
float currDist = moveToTarget == null ? 0.0f : Vector2.DistanceSquared(moveToTarget.Position, character.Position);
for (int i = 0; i < 5 && currSearchIndex < Item.ItemList.Count - 2; i++)
{ {
currSearchIndex++; currSearchIndex++;
//don't try to get items from outside the sub var item = Item.ItemList[currSearchIndex];
if (Item.ItemList[currSearchIndex].CurrentHull == null) continue;
if (!Item.ItemList[currSearchIndex].HasTag(itemName) && Item.ItemList[currSearchIndex].Name != itemName) continue; if (item.CurrentHull == null || item.Condition <= 0.0f) continue;
if (IgnoreContainedItems && Item.ItemList[currSearchIndex].Container != null) continue; if (IgnoreContainedItems && item.Container != null) continue;
if (Item.ItemList[currSearchIndex].ParentInventory is CharacterInventory) continue; if (item.Name != itemName && !item.HasTag(itemName)) continue;
if (item.ParentInventory is CharacterInventory) continue;
//ignore if item is further away than the currently targeted item
Item rootContainer = item.GetRootContainer();
if (moveToTarget != null && Vector2.DistanceSquared((rootContainer ?? item).Position, character.Position) > currDist) continue;
targetItem = Item.ItemList[currSearchIndex]; targetItem = item;
moveToTarget = rootContainer ?? item;
AddGoToObjective(targetItem); AddGoToObjective(moveToTarget);
return;
} }
if (currSearchIndex >= Item.ItemList.Count) canBeCompleted = false; //if searched through all the items and a target wasn't found, can't be completed
if (currSearchIndex >= Item.ItemList.Count && targetItem == null) canBeCompleted = false;
} }
private void AddGoToObjective(Item item) private void AddGoToObjective(Item gotoToTarget)
{ {
Item moveToTarget = item; subObjectives.Clear();
while (moveToTarget.Container != null) AddSubObjective(new AIObjectiveGoTo(gotoToTarget, character));
{
moveToTarget = moveToTarget.Container;
}
AddSubObjective(new AIObjectiveGoTo(moveToTarget, character));
} }
public override bool IsDuplicate(AIObjective otherObjective) public override bool IsDuplicate(AIObjective otherObjective)
{ {
@@ -104,10 +104,13 @@ namespace Barotrauma
var indoorsSteering = character.AIController.SteeringManager as IndoorsSteeringManager; var indoorsSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
if (indoorsSteering.CurrentPath != null && indoorsSteering.HasOutdoorsNodes) if (indoorsSteering.CurrentPath.Unreachable)
{ {
indoorsSteering.SteeringWander();
AddSubObjective(new AIObjectiveGetItem(character, "Diving Suit", true)); }
else if (indoorsSteering.CurrentPath != null && indoorsSteering.HasOutdoorsNodes)
{
AddSubObjective(new AIObjectiveFindDivingGear(character, true));
} }
} }
} }
@@ -40,8 +40,11 @@ namespace Barotrauma
if (currentTarget != null) if (currentTarget != null)
{ {
var path = pathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition); Vector2 pos = character.SimPosition;
if (path.Cost > 200.0f) return; if (character != null && character.Submarine == null) pos -= Submarine.Loaded.SimPosition;
var path = pathSteering.PathFinder.FindPath(pos, currentTarget.SimPosition);
if (path.Cost > 200.0f && character.AnimController.CurrentHull!=null) return;
pathSteering.SetPath(path); pathSteering.SetPath(path);
} }
@@ -114,7 +114,7 @@ namespace Barotrauma
if (dist<closestDist || startNode==null) if (dist<closestDist || startNode==null)
{ {
//if searching for a path inside the sub, make sure the waypoint is visible //if searching for a path inside the sub, make sure the waypoint is visible
if (insideSubmarine && node.Waypoint.CurrentHull != null && Submarine.CheckVisibility(start, node.Waypoint.SimPosition) != null) continue; if (insideSubmarine && Submarine.CheckVisibility(start, node.Waypoint.SimPosition) != null) continue;
closestDist = dist; closestDist = dist;
startNode = node; startNode = node;
@@ -160,7 +160,7 @@ namespace Barotrauma
var path = FindPath(startNode,endNode); var path = FindPath(startNode,endNode);
sw.Stop(); sw.Stop();
System.Diagnostics.Debug.WriteLine("findpath: " + sw.ElapsedTicks); System.Diagnostics.Debug.WriteLine("findpath: " + sw.ElapsedMilliseconds+" ms");
return path; return path;
} }
+2 -2
View File
@@ -173,7 +173,7 @@ namespace Barotrauma
keyboardDispatcher = new KeyboardDispatcher(window); keyboardDispatcher = new KeyboardDispatcher(window);
} }
public T GetChild<T>() public T GetChild<T>() where T : GUIComponent
{ {
foreach (GUIComponent child in children) foreach (GUIComponent child in children)
{ {
@@ -182,7 +182,7 @@ namespace Barotrauma
return default(T); return default(T);
} }
public GUIComponent GetChild(object obj) public GUIComponent GetChild(object obj)
{ {
foreach (GUIComponent child in children) foreach (GUIComponent child in children)
@@ -220,7 +220,29 @@ namespace Barotrauma.Items.Components
Gap leak = objective.OperateTarget as Gap; Gap leak = objective.OperateTarget as Gap;
if (leak == null) return true; if (leak == null) return true;
if (Vector2.Distance(leak.WorldPosition, item.WorldPosition) > range) return true; float dist = Vector2.Distance(leak.WorldPosition, item.WorldPosition);
//too far away -> consider this done and hope the AI is smart enough to move closer
if (dist > range*5.0f) return true;
//steer closer if almost in range
if (dist > range)
{
Vector2 standPos = leak.isHorizontal ?
new Vector2(Math.Sign(item.WorldPosition.X - leak.WorldPosition.X), 0.0f)
: new Vector2(0.0f, Math.Sign(item.WorldPosition.Y - leak.WorldPosition.Y));
standPos = leak.WorldPosition + standPos * range;
character.AIController.SteeringManager.SteeringManual(deltaTime, (standPos - character.WorldPosition) / 1000.0f);
}
else
{
//close enough -> stop moving
character.AIController.SteeringManager.Reset();
}
character.CursorPosition = leak.Position; character.CursorPosition = leak.Position;
character.SetInput(InputType.Aim, false, true); character.SetInput(InputType.Aim, false, true);
@@ -171,7 +171,7 @@ namespace Barotrauma.Items.Components
} }
} }
ApplyStatusEffects(ActionType.OnUse, 1.0f, null); ApplyStatusEffects(ActionType.OnUse, 1.0f);
item.body.FarseerBody.OnCollision -= OnProjectileCollision; item.body.FarseerBody.OnCollision -= OnProjectileCollision;
+14
View File
@@ -466,6 +466,20 @@ namespace Barotrauma
} }
return CurrentHull; return CurrentHull;
} }
public Item GetRootContainer()
{
if (Container == null) return null;
Item rootContainer = Container;
while (rootContainer.Container != null)
{
rootContainer = rootContainer.Container;
}
return rootContainer;
}
public void AddTag(string tag) public void AddTag(string tag)
{ {
+2
View File
@@ -38,6 +38,8 @@ namespace Barotrauma
public Door ConnectedDoor; public Door ConnectedDoor;
public Structure ConnectedWall;
public Vector2 LerpedFlowForce public Vector2 LerpedFlowForce
{ {
get { return lerpedFlowForce; } get { return lerpedFlowForce; }
+4 -2
View File
@@ -577,8 +577,9 @@ namespace Barotrauma
gapRect.Width += 20; gapRect.Width += 20;
gapRect.Height += 20; gapRect.Height += 20;
sections[sectionIndex].gap = new Gap(gapRect, !isHorizontal, Submarine); sections[sectionIndex].gap = new Gap(gapRect, !isHorizontal, Submarine);
if(CastShadow) sections[sectionIndex].gap.ConnectedWall = this;
GenerateConvexHull();
if(CastShadow) GenerateConvexHull();
} }
} }
@@ -758,6 +759,7 @@ namespace Barotrauma
if (s.GapIndex == -1) continue; if (s.GapIndex == -1) continue;
s.gap = FindEntityByID((ushort)s.GapIndex) as Gap; s.gap = FindEntityByID((ushort)s.GapIndex) as Gap;
if (s.gap != null) s.gap.ConnectedWall = this;
} }
} }
+3 -3
View File
@@ -299,7 +299,7 @@ namespace Barotrauma
wayPoint.Remove(); wayPoint.Remove();
} }
float minDist = 200.0f; float minDist = 150.0f;
float heightFromFloor = 100.0f; float heightFromFloor = 100.0f;
foreach (Hull hull in Hull.hullList) foreach (Hull hull in Hull.hullList)
@@ -324,7 +324,7 @@ namespace Barotrauma
prevWaypoint = wayPoint; prevWaypoint = wayPoint;
} }
} }
float outSideWaypointInterval = 200.0f; float outSideWaypointInterval = 200.0f;
int outsideWaypointDist = 100; int outsideWaypointDist = 100;
@@ -521,7 +521,7 @@ namespace Barotrauma
for (int dir = -1; dir <= 1; dir += 2) for (int dir = -1; dir <= 1; dir += 2)
{ {
float tolerance = gap.IsRoomToRoom ? 30.0f : outSideWaypointInterval / 2.0f; float tolerance = gap.IsRoomToRoom ? 50.0f : outSideWaypointInterval / 2.0f;
WayPoint closest = wayPoint.FindClosest(dir, true, new Vector2(-tolerance, tolerance)); WayPoint closest = wayPoint.FindClosest(dir, true, new Vector2(-tolerance, tolerance));
if (closest == null) continue; if (closest == null) continue;
wayPoint.ConnectTo(closest); wayPoint.ConnectTo(closest);