Unstable 0.1500.5.0 (almost forgor edition 💀)
This commit is contained in:
@@ -6,7 +6,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.RuinGeneration;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -189,61 +188,141 @@ namespace Barotrauma
|
||||
door.Body.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isFlooded = submarine.Info.IsRuin || submarine.Info.Type == SubmarineType.OutpostModule && submarine.Info.OutpostModuleInfo.ModuleFlags.Contains("ruin");
|
||||
float diffFromHullEdge = 50;
|
||||
float minDist = 100.0f;
|
||||
float heightFromFloor = 110.0f;
|
||||
float hullMinHeight = 100;
|
||||
var removals = new List<WayPoint>();
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
// Ignore hulls that a human couldn't fit in.
|
||||
// Doesn't take multi-hull rooms into account, but it's probably best to leave them to be setup manually.
|
||||
if (hull.Rect.Height < hullMinHeight) { continue; }
|
||||
// Do five raycasts to check if there's a floor. Don't create waypoints unless we can find a floor.
|
||||
Body floor = null;
|
||||
for (int i = 0; i < 5; i++)
|
||||
if (isFlooded)
|
||||
{
|
||||
float horizontalOffset = 0;
|
||||
switch (i)
|
||||
diffFromHullEdge = 75;
|
||||
var hullWaypoints = new List<WayPoint>();
|
||||
float top = hull.Rect.Y;
|
||||
float bottom = hull.Rect.Y - hull.Rect.Height;
|
||||
if (hull.Rect.Width < 300 || hull.Rect.Height < 300)
|
||||
{
|
||||
case 1:
|
||||
horizontalOffset = hull.RectWidth * 0.2f;
|
||||
break;
|
||||
case 2:
|
||||
horizontalOffset = hull.RectWidth * 0.4f;
|
||||
break;
|
||||
case 3:
|
||||
horizontalOffset = -hull.RectWidth * 0.2f;
|
||||
break;
|
||||
case 4:
|
||||
horizontalOffset = -hull.RectWidth * 0.4f;
|
||||
break;
|
||||
// For narrow hulls, create one line of waypoints either horizontally or vertically
|
||||
if (hull.Rect.Width > hull.Rect.Height)
|
||||
{
|
||||
// Horizontal
|
||||
float y = hull.Rect.Y - hull.Rect.Height / 2;
|
||||
for (float x = hull.Rect.X + diffFromHullEdge; x <= hull.Rect.Right - diffFromHullEdge; x += minDist)
|
||||
{
|
||||
hullWaypoints.Add(new WayPoint(new Vector2(x, y), SpawnType.Path, submarine));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vertical
|
||||
float x = hull.Rect.X + hull.Rect.Width / 2;
|
||||
for (float y = top - diffFromHullEdge; y >= bottom + diffFromHullEdge; y -= minDist)
|
||||
{
|
||||
hullWaypoints.Add(new WayPoint(new Vector2(x, y), SpawnType.Path, submarine));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hullWaypoints.None())
|
||||
{
|
||||
// Try to create a grid-like network of waypoints
|
||||
for (float x = hull.Rect.X + diffFromHullEdge; x <= hull.Rect.Right - diffFromHullEdge; x += minDist)
|
||||
{
|
||||
for (float y = top - diffFromHullEdge; y >= bottom + diffFromHullEdge; y -= minDist)
|
||||
{
|
||||
hullWaypoints.Add(new WayPoint(new Vector2(x, y), SpawnType.Path, submarine));
|
||||
}
|
||||
}
|
||||
if (hullWaypoints.None())
|
||||
{
|
||||
// If that fails, just create one waypoint at the center.
|
||||
hullWaypoints.Add(new WayPoint(new Vector2(hull.Rect.X + hull.Rect.Width / 2.0f, hull.Rect.Y - hull.Rect.Height / 2), SpawnType.Path, submarine));
|
||||
}
|
||||
foreach (WayPoint wp in hullWaypoints)
|
||||
{
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
if (wall.HasBody)
|
||||
{
|
||||
// Remove waypoints that are too close/inside the walls.
|
||||
Rectangle rect = wall.Rect;
|
||||
rect.Inflate(10, 10);
|
||||
if (rect.ContainsWorld(wp.Position))
|
||||
{
|
||||
removals.Add(wp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Connect the waypoints
|
||||
foreach (var wayPoint in hullWaypoints)
|
||||
{
|
||||
for (int dir = -1; dir <= 1; dir += 2)
|
||||
{
|
||||
WayPoint closest = wayPoint.FindClosest(dir, horizontalSearch: true, new Vector2(minDist * 1.9f, minDist));
|
||||
if (closest != null && closest.CurrentHull == wayPoint.CurrentHull)
|
||||
{
|
||||
wayPoint.ConnectTo(closest);
|
||||
}
|
||||
closest = wayPoint.FindClosest(dir, horizontalSearch: false, new Vector2(minDist, minDist * 1.9f));
|
||||
if (closest != null && closest.CurrentHull == wayPoint.CurrentHull)
|
||||
{
|
||||
wayPoint.ConnectTo(closest);
|
||||
}
|
||||
}
|
||||
}
|
||||
horizontalOffset = ConvertUnits.ToSimUnits(horizontalOffset);
|
||||
Vector2 floorPos = new Vector2(hull.SimPosition.X + horizontalOffset, ConvertUnits.ToSimUnits(hull.Rect.Y - hull.RectHeight - 50));
|
||||
floor = Submarine.PickBody(new Vector2(hull.SimPosition.X + horizontalOffset, hull.SimPosition.Y), floorPos, collisionCategory: Physics.CollisionWall | Physics.CollisionPlatform, customPredicate: f => !(f.Body.UserData is Submarine));
|
||||
if (floor != null) { break; }
|
||||
}
|
||||
if (floor == null) { continue; }
|
||||
float waypointHeight = hull.Rect.Height > heightFromFloor * 2 ? heightFromFloor : hull.Rect.Height / 2;
|
||||
if (hull.Rect.Width < diffFromHullEdge * 3.0f)
|
||||
{
|
||||
new WayPoint(new Vector2(hull.Rect.X + hull.Rect.Width / 2.0f, hull.Rect.Y - hull.Rect.Height + waypointHeight), SpawnType.Path, submarine);
|
||||
}
|
||||
else
|
||||
{
|
||||
WayPoint prevWaypoint = null;
|
||||
for (float x = hull.Rect.X + diffFromHullEdge; x <= hull.Rect.Right - diffFromHullEdge; x += minDist)
|
||||
if (hull.Rect.Height < hullMinHeight) { continue; }
|
||||
// Do five raycasts to check if there's a floor. Don't create waypoints unless we can find a floor.
|
||||
Body floor = null;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
var wayPoint = new WayPoint(new Vector2(x, hull.Rect.Y - hull.Rect.Height + waypointHeight), SpawnType.Path, submarine);
|
||||
if (prevWaypoint != null) { wayPoint.ConnectTo(prevWaypoint); }
|
||||
prevWaypoint = wayPoint;
|
||||
float horizontalOffset = 0;
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
horizontalOffset = hull.RectWidth * 0.2f;
|
||||
break;
|
||||
case 2:
|
||||
horizontalOffset = hull.RectWidth * 0.4f;
|
||||
break;
|
||||
case 3:
|
||||
horizontalOffset = -hull.RectWidth * 0.2f;
|
||||
break;
|
||||
case 4:
|
||||
horizontalOffset = -hull.RectWidth * 0.4f;
|
||||
break;
|
||||
}
|
||||
horizontalOffset = ConvertUnits.ToSimUnits(horizontalOffset);
|
||||
Vector2 floorPos = new Vector2(hull.SimPosition.X + horizontalOffset, ConvertUnits.ToSimUnits(hull.Rect.Y - hull.RectHeight - 50));
|
||||
floor = Submarine.PickBody(new Vector2(hull.SimPosition.X + horizontalOffset, hull.SimPosition.Y), floorPos, collisionCategory: Physics.CollisionWall | Physics.CollisionPlatform, customPredicate: f => !(f.Body.UserData is Submarine));
|
||||
if (floor != null) { break; }
|
||||
}
|
||||
if (prevWaypoint == null)
|
||||
if (floor == null) { continue; }
|
||||
float waypointHeight = hull.Rect.Height > heightFromFloor * 2 ? heightFromFloor : hull.Rect.Height / 2;
|
||||
if (hull.Rect.Width < diffFromHullEdge * 3.0f)
|
||||
{
|
||||
// Ensure that we always create at least one waypoint per hull.
|
||||
new WayPoint(new Vector2(hull.Rect.X + hull.Rect.Width / 2.0f, hull.Rect.Y - hull.Rect.Height + waypointHeight), SpawnType.Path, submarine);
|
||||
}
|
||||
else
|
||||
{
|
||||
WayPoint previousWaypoint = null;
|
||||
for (float x = hull.Rect.X + diffFromHullEdge; x <= hull.Rect.Right - diffFromHullEdge; x += minDist)
|
||||
{
|
||||
var wayPoint = new WayPoint(new Vector2(x, hull.Rect.Y - hull.Rect.Height + waypointHeight), SpawnType.Path, submarine);
|
||||
if (previousWaypoint != null) { wayPoint.ConnectTo(previousWaypoint); }
|
||||
previousWaypoint = wayPoint;
|
||||
}
|
||||
if (previousWaypoint == null)
|
||||
{
|
||||
// Ensure that we always create at least one waypoint per hull.
|
||||
new WayPoint(new Vector2(hull.Rect.X + hull.Rect.Width / 2.0f, hull.Rect.Y - hull.Rect.Height + waypointHeight), SpawnType.Path, submarine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +357,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float outSideWaypointInterval = 100.0f;
|
||||
if (submarine.Info.Type != SubmarineType.OutpostModule)
|
||||
if (!isFlooded && submarine.Info.Type != SubmarineType.OutpostModule)
|
||||
{
|
||||
List<(WayPoint, int)> outsideWaypoints = new List<(WayPoint, int)>();
|
||||
|
||||
@@ -381,7 +460,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
// Remove unwanted points
|
||||
var removals = new List<WayPoint>();
|
||||
WayPoint previous = null;
|
||||
float tooClose = outSideWaypointInterval / 2;
|
||||
foreach (var wayPoint in outsideWaypoints)
|
||||
@@ -412,7 +490,6 @@ namespace Barotrauma
|
||||
foreach (WayPoint wp in removals)
|
||||
{
|
||||
outsideWaypoints.RemoveAll(w => w.Item1 == wp);
|
||||
wp.Remove();
|
||||
}
|
||||
for (int i = 0; i < outsideWaypoints.Count; i++)
|
||||
{
|
||||
@@ -433,41 +510,35 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Structure> stairList = new List<Structure>();
|
||||
foreach (MapEntity me in mapEntityList)
|
||||
{
|
||||
if (!(me is Structure stairs)) { continue; }
|
||||
|
||||
if (stairs.StairDirection != Direction.None) stairList.Add(stairs);
|
||||
}
|
||||
|
||||
foreach (Structure stairs in stairList)
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
if (wall.StairDirection == Direction.None) { continue; }
|
||||
WayPoint[] stairPoints = new WayPoint[3];
|
||||
|
||||
stairPoints[0] = new WayPoint(
|
||||
new Vector2(stairs.Rect.X - 32.0f,
|
||||
stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? 80 : stairs.Rect.Height) + heightFromFloor), SpawnType.Path, submarine);
|
||||
new Vector2(wall.Rect.X - 32.0f,
|
||||
wall.Rect.Y - (wall.StairDirection == Direction.Left ? 80 : wall.Rect.Height) + heightFromFloor), SpawnType.Path, submarine);
|
||||
|
||||
stairPoints[1] = new WayPoint(
|
||||
new Vector2(stairs.Rect.Right + 32.0f,
|
||||
stairs.Rect.Y - (stairs.StairDirection == Direction.Left ? stairs.Rect.Height : 80) + heightFromFloor), SpawnType.Path, submarine);
|
||||
new Vector2(wall.Rect.Right + 32.0f,
|
||||
wall.Rect.Y - (wall.StairDirection == Direction.Left ? wall.Rect.Height : 80) + heightFromFloor), SpawnType.Path, submarine);
|
||||
|
||||
for (int i = 0; i < 2; i++ )
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int dir = -1; dir <= 1; dir += 2)
|
||||
{
|
||||
WayPoint closest = stairPoints[i].FindClosest(dir, horizontalSearch: true, new Vector2(100, 70));
|
||||
if (closest == null) { continue; }
|
||||
stairPoints[i].ConnectTo(closest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stairPoints[2] = new WayPoint((stairPoints[0].Position + stairPoints[1].Position) / 2, SpawnType.Path, submarine);
|
||||
stairPoints[0].ConnectTo(stairPoints[2]);
|
||||
stairPoints[2].ConnectTo(stairPoints[1]);
|
||||
}
|
||||
removals.ForEach(wp => wp.Remove());
|
||||
removals.Clear();
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
@@ -605,12 +676,25 @@ namespace Barotrauma
|
||||
{
|
||||
if (gap.IsHorizontal)
|
||||
{
|
||||
// Too small to walk through
|
||||
if (gap.Rect.Height < hullMinHeight) { continue; }
|
||||
if ( isFlooded)
|
||||
{
|
||||
// Too small to swim through
|
||||
if (gap.Rect.Height < 50) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too small to walk through
|
||||
if (gap.Rect.Height < hullMinHeight) { continue; }
|
||||
}
|
||||
|
||||
Vector2 pos = new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height + heightFromFloor);
|
||||
if (isFlooded)
|
||||
{
|
||||
pos.Y = gap.Rect.Y - gap.Rect.Height / 2;
|
||||
}
|
||||
var wayPoint = new WayPoint(pos, SpawnType.Path, submarine, gap);
|
||||
// The closest waypoint can be quite far if the gap is at an exterior door.
|
||||
Vector2 tolerance = gap.IsRoomToRoom ? new Vector2(150, 70) : new Vector2(1000, 1000);
|
||||
Vector2 tolerance = gap.IsRoomToRoom && !isFlooded ? new Vector2(150, 70) : new Vector2(1000, 1000);
|
||||
for (int dir = -1; dir <= 1; dir += 2)
|
||||
{
|
||||
WayPoint closest = wayPoint.FindClosest(dir, horizontalSearch: true, tolerance, gap.ConnectedDoor?.Body.FarseerBody);
|
||||
@@ -623,7 +707,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
// Create waypoints on vertical gaps on the outer walls, also hatches.
|
||||
if (gap.IsRoomToRoom || gap.linkedTo.None(l => l is Hull)) { continue; }
|
||||
if (!isFlooded && (gap.IsRoomToRoom || gap.linkedTo.None(l => l is Hull))) { continue; }
|
||||
// Too small to swim through
|
||||
if (gap.Rect.Width < 50.0f) { continue; }
|
||||
Vector2 pos = new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height / 2);
|
||||
@@ -632,11 +716,20 @@ namespace Barotrauma
|
||||
var wayPoint = new WayPoint(pos, SpawnType.Path, submarine, gap);
|
||||
Hull connectedHull = (Hull)gap.linkedTo.First(l => l is Hull);
|
||||
int dir = Math.Sign(connectedHull.Position.Y - gap.Position.Y);
|
||||
WayPoint closest = wayPoint.FindClosest(dir, horizontalSearch: false, new Vector2(50, 100));
|
||||
WayPoint closest = wayPoint.FindClosest(dir, horizontalSearch: false, isFlooded ? new Vector2(500, 500) : new Vector2(50, 100));
|
||||
if (closest != null)
|
||||
{
|
||||
wayPoint.ConnectTo(closest);
|
||||
}
|
||||
if (isFlooded)
|
||||
{
|
||||
closest = wayPoint.FindClosest(-dir, horizontalSearch: false, isFlooded ? new Vector2(500, 500) : new Vector2(50, 100));
|
||||
if (closest != null)
|
||||
{
|
||||
wayPoint.ConnectTo(closest);
|
||||
}
|
||||
}
|
||||
// Link to outside
|
||||
for (dir = -1; dir <= 1; dir += 2)
|
||||
{
|
||||
closest = wayPoint.FindClosest(dir, horizontalSearch: true, new Vector2(500, 1000), gap.ConnectedDoor?.Body.FarseerBody, filter: wp => wp.CurrentHull == null);
|
||||
@@ -656,7 +749,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.CurrentHull == null && wp.Ladders == null && wp.linkedTo.Count < 2)
|
||||
if (wp.SpawnType == SpawnType.Path && wp.CurrentHull == null && wp.Ladders == null && wp.linkedTo.Count < 2)
|
||||
{
|
||||
DebugConsole.ThrowError($"Couldn't automatically link the waypoint {wp.ID} outside of the submarine. You should do it manually. The waypoint ID is shown in red color.");
|
||||
}
|
||||
@@ -775,11 +868,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.Human, JobPrefab assignedJob = null, Submarine sub = null, Ruin ruin = null, bool useSyncedRand = false)
|
||||
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.Human, JobPrefab assignedJob = null, Submarine sub = null, bool useSyncedRand = false)
|
||||
{
|
||||
return WayPointList.GetRandom(wp =>
|
||||
wp.Submarine == sub &&
|
||||
wp.ParentRuin == ruin &&
|
||||
wp.spawnType == spawnType &&
|
||||
(assignedJob == null || (assignedJob != null && wp.AssignedJob == assignedJob)),
|
||||
useSyncedRand ? Rand.RandSync.Server : Rand.RandSync.Unsynced);
|
||||
|
||||
Reference in New Issue
Block a user