Unstable 0.1500.5.0 (almost forgor edition 💀)
This commit is contained in:
@@ -325,6 +325,7 @@ namespace Barotrauma
|
||||
get { return LevelData.Seed; }
|
||||
}
|
||||
|
||||
|
||||
public static float? ForcedDifficulty;
|
||||
public float Difficulty
|
||||
{
|
||||
@@ -527,6 +528,7 @@ namespace Barotrauma
|
||||
|
||||
//create a tunnel from the lowest point in the main path to the abyss
|
||||
//to ensure there's a way to the abyss in all levels
|
||||
Tunnel abyssTunnel = null;
|
||||
if (GenerationParams.CreateHoleToAbyss)
|
||||
{
|
||||
Point lowestPoint = mainPath.Nodes.First();
|
||||
@@ -534,7 +536,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (pathNode.Y < lowestPoint.Y) { lowestPoint = pathNode; }
|
||||
}
|
||||
var abyssTunnel = new Tunnel(
|
||||
abyssTunnel = new Tunnel(
|
||||
TunnelType.SidePath,
|
||||
new List<Point>() { lowestPoint, new Point(lowestPoint.X, 0) },
|
||||
minWidth / 2, parentTunnel: mainPath);
|
||||
@@ -545,7 +547,7 @@ namespace Barotrauma
|
||||
for (int j = 0; j < sideTunnelCount; j++)
|
||||
{
|
||||
if (mainPath.Nodes.Count < 4) { break; }
|
||||
var validTunnels = Tunnels.FindAll(t => t.Type != TunnelType.Cave && t != startPath && t != endPath && t != endHole);
|
||||
var validTunnels = Tunnels.FindAll(t => t.Type != TunnelType.Cave && t != startPath && t != endPath && t != endHole && t != abyssTunnel);
|
||||
Tunnel tunnelToBranchOff = validTunnels[Rand.Int(validTunnels.Count, Rand.RandSync.Server)];
|
||||
if (tunnelToBranchOff == null) { tunnelToBranchOff = mainPath; }
|
||||
|
||||
@@ -558,7 +560,7 @@ namespace Barotrauma
|
||||
Tunnels.Add(new Tunnel(TunnelType.SidePath, sidePathNodes, pathWidth, parentTunnel: tunnelToBranchOff));
|
||||
}
|
||||
|
||||
CalculateTunnelDistanceField(density: 1000);
|
||||
CalculateTunnelDistanceField(null);
|
||||
GenerateSeaFloorPositions();
|
||||
GenerateAbyssArea();
|
||||
GenerateCaves(mainPath);
|
||||
@@ -690,7 +692,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
GenerateWaypoints(tunnel, parentTunnel: tunnel.ParentTunnel);
|
||||
|
||||
bool connectToParentTunnel = tunnel.Type != TunnelType.Cave || tunnel.ParentTunnel.Type == TunnelType.Cave;
|
||||
GenerateWaypoints(tunnel, parentTunnel: connectToParentTunnel ? tunnel.ParentTunnel : null);
|
||||
|
||||
EnlargePath(tunnel.Cells, tunnel.MinWidth);
|
||||
foreach (var pathCell in tunnel.Cells)
|
||||
{
|
||||
@@ -790,6 +795,15 @@ namespace Barotrauma
|
||||
cells.AddRange(abyssIsland.Cells);
|
||||
}
|
||||
|
||||
List<Point> ruinPositions = new List<Point>();
|
||||
for (int i = 0; i < GenerationParams.RuinCount; i++)
|
||||
{
|
||||
Point ruinSize = new Point(5000);
|
||||
ruinPositions.Add(FindPosAwayFromMainPath((Math.Max(ruinSize.X, ruinSize.Y) + mainPath.MinWidth) * 1.2f, asCloseAsPossible: true,
|
||||
limits: new Rectangle(new Point(ruinSize.X / 2, ruinSize.Y / 2), Size - ruinSize)));
|
||||
CalculateTunnelDistanceField(ruinPositions);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// initialize the cells that are still left and insert them into the cell grid
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -812,7 +826,9 @@ namespace Barotrauma
|
||||
//----------------------------------------------------------------------------------
|
||||
// mirror if needed
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
int asdfasdf = Rand.Int(int.MaxValue, Rand.RandSync.Server);
|
||||
|
||||
if (mirror)
|
||||
{
|
||||
HashSet<GraphEdge> mirroredEdges = new HashSet<GraphEdge>();
|
||||
@@ -850,6 +866,11 @@ namespace Barotrauma
|
||||
island.Area = new Rectangle(borders.Width - island.Area.Right, island.Area.Y, island.Area.Width, island.Area.Height);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ruinPositions.Count; i++)
|
||||
{
|
||||
ruinPositions[i] = new Point(borders.Width - ruinPositions[i].X, ruinPositions[i].Y);
|
||||
}
|
||||
|
||||
foreach (Cave cave in Caves)
|
||||
{
|
||||
cave.Area = new Rectangle(borders.Width - cave.Area.Right, cave.Area.Y, cave.Area.Width, cave.Area.Height);
|
||||
@@ -895,7 +916,7 @@ namespace Barotrauma
|
||||
startExitPosition.X = borders.Width - startExitPosition.X;
|
||||
endExitPosition.X = borders.Width - endExitPosition.X;
|
||||
|
||||
CalculateTunnelDistanceField(density: 1000);
|
||||
CalculateTunnelDistanceField(ruinPositions);
|
||||
}
|
||||
|
||||
foreach (VoronoiCell cell in cells)
|
||||
@@ -912,8 +933,23 @@ namespace Barotrauma
|
||||
foreach (Cave cave in Caves)
|
||||
{
|
||||
if (cave.Area.Y > 0)
|
||||
{
|
||||
CreatePathToClosestTunnel(cave.StartPos);
|
||||
{
|
||||
List<VoronoiCell> cavePathCells = CreatePathToClosestTunnel(cave.StartPos);
|
||||
|
||||
var mainTunnel = cave.Tunnels.Find(t => t.ParentTunnel.Type != TunnelType.Cave);
|
||||
|
||||
WayPoint prevWp = mainTunnel.WayPoints.First();
|
||||
if (prevWp != null)
|
||||
{
|
||||
for (int i = 0; i < cavePathCells.Count; i++)
|
||||
{
|
||||
var newWaypoint = new WayPoint(cavePathCells[i].Center, SpawnType.Path, submarine: null);
|
||||
ConnectWaypoints(prevWp, newWaypoint, 500.0f);
|
||||
prevWp = newWaypoint;
|
||||
}
|
||||
var closestPathPoint = FindClosestWayPoint(prevWp.WorldPosition, mainTunnel.ParentTunnel.WayPoints);
|
||||
ConnectWaypoints(prevWp, closestPathPoint, 500.0f);
|
||||
}
|
||||
}
|
||||
|
||||
List<VoronoiCell> caveCells = new List<VoronoiCell>();
|
||||
@@ -939,9 +975,10 @@ namespace Barotrauma
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
Ruins = new List<Ruin>();
|
||||
for (int i = 0; i < GenerationParams.RuinCount; i++)
|
||||
for (int i = 0; i < ruinPositions.Count; i++)
|
||||
{
|
||||
GenerateRuin(mainPath, mirror);
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed) + i);
|
||||
GenerateRuin(ruinPositions[i], mirror);
|
||||
}
|
||||
|
||||
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.Server));
|
||||
@@ -1003,7 +1040,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if CLIENT
|
||||
List<(List<VoronoiCell> cells, Cave parentCave)> cellBatches = new List<(List<VoronoiCell>, Cave)>
|
||||
{
|
||||
@@ -1082,7 +1118,6 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.Server));
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -1100,6 +1135,11 @@ namespace Barotrauma
|
||||
// connect side paths and cave branches to their parents
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
foreach (Ruin ruin in Ruins)
|
||||
{
|
||||
GenerateRuinWayPoints(ruin);
|
||||
}
|
||||
|
||||
foreach (Tunnel tunnel in Tunnels)
|
||||
{
|
||||
if (tunnel.ParentTunnel == null) { continue; }
|
||||
@@ -1342,18 +1382,7 @@ namespace Barotrauma
|
||||
|
||||
if (wayPoints.Count > 1)
|
||||
{
|
||||
wayPoints[wayPoints.Count - 2].linkedTo.Add(newWaypoint);
|
||||
newWaypoint.linkedTo.Add(wayPoints[wayPoints.Count - 2]);
|
||||
}
|
||||
|
||||
for (int n = 0; n < wayPoints.Count; n++)
|
||||
{
|
||||
if (wayPoints[n].Position != newWaypoint.Position) { continue; }
|
||||
|
||||
wayPoints[n].linkedTo.Add(newWaypoint);
|
||||
newWaypoint.linkedTo.Add(wayPoints[n]);
|
||||
|
||||
break;
|
||||
wayPoints[wayPoints.Count - 2].ConnectTo(newWaypoint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1362,19 +1391,17 @@ namespace Barotrauma
|
||||
//connect to the tunnel we're branching off from
|
||||
if (parentTunnel != null)
|
||||
{
|
||||
var parentStart = FindClosestWayPoint(wayPoints.First(), parentTunnel);
|
||||
var parentStart = FindClosestWayPoint(wayPoints.First().WorldPosition, parentTunnel);
|
||||
if (parentStart != null)
|
||||
{
|
||||
wayPoints.First().linkedTo.Add(parentStart);
|
||||
parentStart.linkedTo.Add(wayPoints.First());
|
||||
wayPoints.First().ConnectTo(parentStart);
|
||||
}
|
||||
if (tunnel.Type != TunnelType.Cave || tunnel.ParentTunnel.Type == TunnelType.Cave)
|
||||
{
|
||||
var parentEnd = FindClosestWayPoint(wayPoints.Last(), parentTunnel);
|
||||
var parentEnd = FindClosestWayPoint(wayPoints.Last().WorldPosition, parentTunnel);
|
||||
if (parentEnd != null)
|
||||
{
|
||||
wayPoints.Last().linkedTo.Add(parentEnd);
|
||||
parentEnd.linkedTo.Add(wayPoints.Last());
|
||||
wayPoints.Last().ConnectTo(parentEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1384,45 +1411,58 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (WayPoint wayPoint in tunnel.WayPoints)
|
||||
{
|
||||
var closestWaypoint = FindClosestWayPoint(wayPoint, parentTunnel);
|
||||
var closestWaypoint = FindClosestWayPoint(wayPoint.WorldPosition, parentTunnel);
|
||||
if (closestWaypoint == null) { continue; }
|
||||
if (Submarine.PickBody(
|
||||
ConvertUnits.ToSimUnits(wayPoint.WorldPosition),
|
||||
ConvertUnits.ToSimUnits(closestWaypoint.WorldPosition), collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) == null)
|
||||
{
|
||||
Vector2 diff = closestWaypoint.WorldPosition - wayPoint.WorldPosition;
|
||||
float dist = diff.Length();
|
||||
float step = ConvertUnits.ToDisplayUnits(Steering.AutopilotMinDistToPathNode) * 0.8f;
|
||||
|
||||
WayPoint prevWaypoint = wayPoint;
|
||||
for (float x = step; x < dist - step; x += step)
|
||||
{
|
||||
var newWaypoint = new WayPoint(wayPoint.WorldPosition + (diff / dist * x), SpawnType.Path, submarine: null)
|
||||
{
|
||||
Tunnel = tunnel
|
||||
};
|
||||
prevWaypoint.linkedTo.Add(newWaypoint);
|
||||
newWaypoint.linkedTo.Add(prevWaypoint);
|
||||
prevWaypoint = newWaypoint;
|
||||
}
|
||||
prevWaypoint.linkedTo.Add(closestWaypoint);
|
||||
closestWaypoint.linkedTo.Add(prevWaypoint);
|
||||
ConnectWaypoints(wayPoint, closestWaypoint, step).ForEach(wp => wp.Tunnel = tunnel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static WayPoint FindClosestWayPoint(WayPoint wayPoint, Tunnel otherTunnel)
|
||||
private List<WayPoint> ConnectWaypoints(WayPoint wp1, WayPoint wp2, float interval)
|
||||
{
|
||||
List<WayPoint> newWaypoints = new List<WayPoint>();
|
||||
|
||||
Vector2 diff = wp2.WorldPosition - wp1.WorldPosition;
|
||||
float dist = diff.Length();
|
||||
|
||||
WayPoint prevWaypoint = wp1;
|
||||
for (float x = interval; x < dist - interval; x += interval)
|
||||
{
|
||||
var newWaypoint = new WayPoint(wp1.WorldPosition + (diff / dist * x), SpawnType.Path, submarine: null);
|
||||
prevWaypoint.ConnectTo(newWaypoint);
|
||||
prevWaypoint = newWaypoint;
|
||||
newWaypoints.Add(newWaypoint);
|
||||
}
|
||||
prevWaypoint.ConnectTo(wp2);
|
||||
|
||||
return newWaypoints;
|
||||
}
|
||||
|
||||
private static WayPoint FindClosestWayPoint(Vector2 worldPosition, Tunnel otherTunnel)
|
||||
{
|
||||
return FindClosestWayPoint(worldPosition, otherTunnel.WayPoints);
|
||||
}
|
||||
|
||||
private static WayPoint FindClosestWayPoint(Vector2 worldPosition, IEnumerable<WayPoint> waypoints, Func<WayPoint, bool> filter = null)
|
||||
{
|
||||
float closestDist = float.PositiveInfinity;
|
||||
WayPoint closestWayPoint = null;
|
||||
foreach (WayPoint otherWayPoint in otherTunnel.WayPoints)
|
||||
foreach (WayPoint otherWayPoint in waypoints)
|
||||
{
|
||||
float dist = Vector2.DistanceSquared(otherWayPoint.WorldPosition, wayPoint.WorldPosition);
|
||||
float dist = Vector2.DistanceSquared(otherWayPoint.WorldPosition, worldPosition);
|
||||
if (dist < closestDist)
|
||||
{
|
||||
if (filter != null)
|
||||
{
|
||||
if (!filter(otherWayPoint)) { continue; }
|
||||
}
|
||||
closestDist = dist;
|
||||
closestWayPoint = otherWayPoint;
|
||||
|
||||
}
|
||||
}
|
||||
return closestWayPoint;
|
||||
@@ -1705,7 +1745,7 @@ namespace Barotrauma
|
||||
|
||||
GenerateCave(caveParams, parentTunnel, cavePos, caveSize);
|
||||
|
||||
CalculateTunnelDistanceField(density: 1000);
|
||||
CalculateTunnelDistanceField(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1787,84 +1827,145 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateRuin(Tunnel mainPath, bool mirror)
|
||||
private void GenerateRuin(Point ruinPos, bool mirror)
|
||||
{
|
||||
var ruinGenerationParams = RuinGenerationParams.GetRandom();
|
||||
|
||||
Point ruinSize = new Point(
|
||||
Rand.Range(ruinGenerationParams.SizeMin.X, ruinGenerationParams.SizeMax.X, Rand.RandSync.Server),
|
||||
Rand.Range(ruinGenerationParams.SizeMin.Y, ruinGenerationParams.SizeMax.Y, Rand.RandSync.Server));
|
||||
int ruinRadius = Math.Max(ruinSize.X, ruinSize.Y) / 2;
|
||||
|
||||
Point ruinPos = FindPosAwayFromMainPath((ruinRadius + mainPath.MinWidth) * 1.2f, asCloseAsPossible: true,
|
||||
limits: new Rectangle(new Point(ruinSize.X / 2, ruinSize.Y / 2), Size - ruinSize));
|
||||
|
||||
VoronoiCell closestPathCell = null;
|
||||
double closestDist = 0.0f;
|
||||
foreach (VoronoiCell pathCell in mainPath.Cells)
|
||||
LocationType locationType = StartLocation?.Type;
|
||||
if (locationType == null)
|
||||
{
|
||||
double dist = MathUtils.DistanceSquared(pathCell.Site.Coord.X, pathCell.Site.Coord.Y, ruinPos.X, ruinPos.Y);
|
||||
if (closestPathCell == null || dist < closestDist)
|
||||
locationType = LocationType.List.GetRandom(Rand.RandSync.Server);
|
||||
if (ruinGenerationParams.AllowedLocationTypes.Any())
|
||||
{
|
||||
closestPathCell = pathCell;
|
||||
closestDist = dist;
|
||||
locationType = LocationType.List.Where(lt =>
|
||||
ruinGenerationParams.AllowedLocationTypes.Any(allowedType =>
|
||||
allowedType.Equals("any", StringComparison.OrdinalIgnoreCase) || lt.Identifier.Equals(allowedType, StringComparison.OrdinalIgnoreCase))).GetRandom();
|
||||
}
|
||||
}
|
||||
|
||||
var ruin = new Ruin(closestPathCell, cells, ruinGenerationParams, new Rectangle(ruinPos - new Point(ruinSize.X / 2, ruinSize.Y / 2), ruinSize), mirror);
|
||||
|
||||
var ruin = new Ruin(this, ruinGenerationParams, locationType, ruinPos, mirror);
|
||||
Ruins.Add(ruin);
|
||||
|
||||
ruin.RuinShapes.Sort((shape1, shape2) => shape2.DistanceFromEntrance.CompareTo(shape1.DistanceFromEntrance));
|
||||
// TODO: autogenerate waypoints inside the ruins and connect them to the main path in multiple places.
|
||||
// We need the waypoints for the AI navigation and we could use them for spawning the creatures too.
|
||||
int waypointCount = 0;
|
||||
foreach (WayPoint wp in WayPoint.WayPointList)
|
||||
var tooClose = GetTooCloseCells(ruinPos.ToVector2(), Math.Max(ruin.Area.Width, ruin.Area.Height) * 4);
|
||||
|
||||
foreach (VoronoiCell cell in tooClose)
|
||||
{
|
||||
if (wp.SpawnType != SpawnType.Enemy || wp.Submarine != null) { continue; }
|
||||
if (ruin.RuinShapes.Any(rs => rs.Rect.Contains(wp.WorldPosition)))
|
||||
if (cell.CellType == CellType.Empty) { continue; }
|
||||
if (ExtraWalls.Any(w => w.Cells.Contains(cell))) { continue; }
|
||||
foreach (GraphEdge e in cell.Edges)
|
||||
{
|
||||
PositionsOfInterest.Add(new InterestingPosition(new Point((int)wp.WorldPosition.X, (int)wp.WorldPosition.Y), PositionType.Ruin, ruin: ruin));
|
||||
waypointCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//not enough waypoints inside ruins -> create some spawn positions manually
|
||||
for (int i = 0; i < 4 - waypointCount && i < ruin.RuinShapes.Count; i++)
|
||||
{
|
||||
PositionsOfInterest.Add(new InterestingPosition(ruin.RuinShapes[i].Rect.Center, PositionType.Ruin, ruin: ruin));
|
||||
}
|
||||
|
||||
foreach (RuinShape ruinShape in ruin.RuinShapes)
|
||||
{
|
||||
var tooClose = GetTooCloseCells(ruinShape.Rect.Center.ToVector2(), Math.Max(ruinShape.Rect.Width, ruinShape.Rect.Height) * 4);
|
||||
|
||||
foreach (VoronoiCell cell in tooClose)
|
||||
{
|
||||
if (cell.CellType == CellType.Empty) { continue; }
|
||||
if (ExtraWalls.Any(w => w.Cells.Contains(cell))) { continue; }
|
||||
foreach (GraphEdge e in cell.Edges)
|
||||
if (ruin.Area.Contains(e.Point1) || ruin.Area.Contains(e.Point2) ||
|
||||
MathUtils.GetLineRectangleIntersection(e.Point1, e.Point2, ruin.Area, out _))
|
||||
{
|
||||
Rectangle rect = ruinShape.Rect;
|
||||
rect.Y += rect.Height;
|
||||
if (ruinShape.Rect.Contains(e.Point1) || ruinShape.Rect.Contains(e.Point2) ||
|
||||
MathUtils.GetLineRectangleIntersection(e.Point1, e.Point2, rect, out _))
|
||||
cell.CellType = CellType.Removed;
|
||||
for (int x = 0; x < cellGrid.GetLength(0); x++)
|
||||
{
|
||||
cell.CellType = CellType.Removed;
|
||||
for (int x = 0; x < cellGrid.GetLength(0); x++)
|
||||
for (int y = 0; y < cellGrid.GetLength(1); y++)
|
||||
{
|
||||
for (int y = 0; y < cellGrid.GetLength(1); y++)
|
||||
{
|
||||
cellGrid[x, y].Remove(cell);
|
||||
}
|
||||
cellGrid[x, y].Remove(cell);
|
||||
}
|
||||
cells.Remove(cell);
|
||||
break;
|
||||
}
|
||||
cells.Remove(cell);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CreatePathToClosestTunnel(ruinPos);
|
||||
ruin.PathCells = CreatePathToClosestTunnel(ruin.Area.Center);
|
||||
}
|
||||
|
||||
private void GenerateRuinWayPoints(Ruin ruin)
|
||||
{
|
||||
var tooClose = GetTooCloseCells(ruin.Area.Center.ToVector2(), Math.Max(ruin.Area.Width, ruin.Area.Height) * 6);
|
||||
|
||||
List<WayPoint> wayPoints = new List<WayPoint>();
|
||||
float outSideWaypointInterval = 500.0f;
|
||||
WayPoint[,] cornerWaypoint = new WayPoint[2, 2];
|
||||
Rectangle waypointArea = ruin.Area;
|
||||
waypointArea.Inflate(100, 100);
|
||||
|
||||
//generate waypoints around the ruin
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (float x = waypointArea.X + outSideWaypointInterval; x < waypointArea.Right - outSideWaypointInterval; x += outSideWaypointInterval)
|
||||
{
|
||||
var wayPoint = new WayPoint(new Vector2(x, waypointArea.Y + waypointArea.Height * i), SpawnType.Path, null);
|
||||
wayPoints.Add(wayPoint);
|
||||
if (x == waypointArea.X + outSideWaypointInterval)
|
||||
{
|
||||
cornerWaypoint[i, 0] = wayPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
wayPoint.ConnectTo(wayPoints[wayPoints.Count - 2]);
|
||||
}
|
||||
}
|
||||
cornerWaypoint[i, 1] = wayPoints[wayPoints.Count - 1];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
WayPoint wayPoint = null;
|
||||
for (float y = waypointArea.Y; y < waypointArea.Y + waypointArea.Height; y += outSideWaypointInterval)
|
||||
{
|
||||
wayPoint = new WayPoint(new Vector2(waypointArea.X + waypointArea.Width * i, y), SpawnType.Path, null);
|
||||
wayPoints.Add(wayPoint);
|
||||
if (y == waypointArea.Y)
|
||||
{
|
||||
wayPoint.ConnectTo(cornerWaypoint[0, i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wayPoint.ConnectTo(wayPoints[wayPoints.Count - 2]);
|
||||
}
|
||||
}
|
||||
wayPoint.ConnectTo(cornerWaypoint[1, i]);
|
||||
}
|
||||
|
||||
//remove waypoints that are inside walls
|
||||
for (int i = wayPoints.Count - 1; i >= 0; i--)
|
||||
{
|
||||
WayPoint wp = wayPoints[i];
|
||||
var overlappingCell = tooClose.Find(c => c.CellType != CellType.Removed && c.IsPointInside(wp.WorldPosition));
|
||||
if (overlappingCell == null) { continue; }
|
||||
if (wp.linkedTo.Count > 1)
|
||||
{
|
||||
WayPoint linked1 = wp.linkedTo[0] as WayPoint;
|
||||
WayPoint linked2 = wp.linkedTo[1] as WayPoint;
|
||||
linked1.ConnectTo(linked2);
|
||||
}
|
||||
wp.Remove();
|
||||
wayPoints.RemoveAt(i);
|
||||
}
|
||||
|
||||
//connect ruin entrances to the outside waypoints
|
||||
foreach (Gap g in Gap.GapList)
|
||||
{
|
||||
if (g.Submarine != ruin.Submarine || g.IsRoomToRoom) { continue; }
|
||||
var gapWaypoint = WayPoint.WayPointList.Find(wp => wp.ConnectedGap == g);
|
||||
if (gapWaypoint == null) { continue; }
|
||||
var closestWp = FindClosestWayPoint(gapWaypoint.WorldPosition, wayPoints);
|
||||
if (closestWp == null) { continue; }
|
||||
gapWaypoint.ConnectTo(closestWp);
|
||||
}
|
||||
|
||||
//create a waypoint path from the ruin to the closest tunnel
|
||||
WayPoint prevWp = FindClosestWayPoint(ruin.PathCells.First().Center, wayPoints, (wp) =>
|
||||
{
|
||||
return Submarine.PickBody(
|
||||
ConvertUnits.ToSimUnits(wp.WorldPosition),
|
||||
ConvertUnits.ToSimUnits(ruin.PathCells.First().Center), collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) == null;
|
||||
});
|
||||
if (prevWp != null)
|
||||
{
|
||||
for (int i = 0; i < ruin.PathCells.Count; i++)
|
||||
{
|
||||
var newWaypoint = new WayPoint(ruin.PathCells[i].Center, SpawnType.Path, submarine: null);
|
||||
ConnectWaypoints(prevWp, newWaypoint, outSideWaypointInterval);
|
||||
prevWp = newWaypoint;
|
||||
}
|
||||
var closestPathPoint = FindClosestWayPoint(prevWp.WorldPosition, Tunnels.SelectMany(t => t.WayPoints));
|
||||
ConnectWaypoints(prevWp, closestPathPoint, outSideWaypointInterval);
|
||||
}
|
||||
}
|
||||
|
||||
private Point FindPosAwayFromMainPath(double minDistance, bool asCloseAsPossible, Rectangle? limits = null)
|
||||
@@ -1890,8 +1991,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateTunnelDistanceField(int density)
|
||||
private void CalculateTunnelDistanceField(List<Point> ruinPositions)
|
||||
{
|
||||
int density = 1000;
|
||||
distanceField = new List<(Point point, double distance)>();
|
||||
|
||||
if (Mirrored)
|
||||
@@ -1926,6 +2028,23 @@ namespace Barotrauma
|
||||
shortestDistSqr = Math.Min(shortestDistSqr, MathUtils.LineSegmentToPointDistanceSquared(tunnel.Nodes[i - 1], tunnel.Nodes[i], point));
|
||||
}
|
||||
}
|
||||
if (ruinPositions != null)
|
||||
{
|
||||
int ruinSize = 10000;
|
||||
foreach (Point ruinPos in ruinPositions)
|
||||
{
|
||||
double xDiff = Math.Abs(point.X - ruinPos.X);
|
||||
double yDiff = Math.Abs(point.Y - ruinPos.Y);
|
||||
if (xDiff < ruinSize || yDiff < ruinSize)
|
||||
{
|
||||
shortestDistSqr = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
shortestDistSqr = Math.Min(xDiff * xDiff + yDiff * yDiff, shortestDistSqr);
|
||||
}
|
||||
}
|
||||
}
|
||||
shortestDistSqr = Math.Min(shortestDistSqr, MathUtils.DistanceSquared((double)point.X, (double)point.Y, (double)startPosition.X, (double)startPosition.Y));
|
||||
shortestDistSqr = Math.Min(shortestDistSqr, MathUtils.DistanceSquared((double)point.X, (double)point.Y, (double)startExitPosition.X, (double)borders.Bottom));
|
||||
shortestDistSqr = Math.Min(shortestDistSqr, MathUtils.DistanceSquared((double)point.X, (double)point.Y, (double)endPosition.X, (double)endPosition.Y));
|
||||
@@ -2953,7 +3072,7 @@ namespace Barotrauma
|
||||
return closestCell;
|
||||
}
|
||||
|
||||
private void CreatePathToClosestTunnel(Point pos)
|
||||
private List<VoronoiCell> CreatePathToClosestTunnel(Point pos)
|
||||
{
|
||||
VoronoiCell closestPathCell = null;
|
||||
double closestDist = 0.0f;
|
||||
@@ -2973,6 +3092,7 @@ namespace Barotrauma
|
||||
|
||||
//cast a ray from the closest path cell towards the position and remove the cells it hits
|
||||
List<VoronoiCell> validCells = cells.FindAll(c => c.CellType != CellType.Empty && c.CellType != CellType.Removed);
|
||||
List<VoronoiCell> pathCells = new List<VoronoiCell>() { closestPathCell };
|
||||
foreach (VoronoiCell cell in validCells)
|
||||
{
|
||||
foreach (GraphEdge e in cell.Edges)
|
||||
@@ -2987,6 +3107,7 @@ namespace Barotrauma
|
||||
cellGrid[x, y].Remove(cell);
|
||||
}
|
||||
}
|
||||
pathCells.Add(cell);
|
||||
cells.Remove(cell);
|
||||
|
||||
//go through the edges of this cell and find the ones that are next to a removed cell
|
||||
@@ -3019,12 +3140,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pathCells.Sort((c1, c2) => { return Vector2.DistanceSquared(c1.Center, pos.ToVector2()).CompareTo(Vector2.DistanceSquared(c2.Center, pos.ToVector2())); });
|
||||
return pathCells;
|
||||
}
|
||||
|
||||
public string GetWreckIDTag(string originalTag, Submarine wreck)
|
||||
{
|
||||
string shortSeed = ToolBox.StringToInt(LevelData.Seed + wreck?.Info.Name).ToString();
|
||||
if (shortSeed.Length > 6) { shortSeed = shortSeed.Substring(0, 6); }
|
||||
return originalTag + "_" + shortSeed;
|
||||
}
|
||||
|
||||
public bool IsCloseToStart(Vector2 position, float minDist) => IsCloseToStart(position.ToPoint(), minDist);
|
||||
@@ -3049,10 +3177,8 @@ namespace Barotrauma
|
||||
var waypoints = WayPoint.WayPointList.Where(wp =>
|
||||
wp.Submarine == null &&
|
||||
wp.SpawnType == SpawnType.Path &&
|
||||
wp.WorldPosition.X < EndExitPosition.X &&
|
||||
!IsCloseToStart(wp.WorldPosition, minDistance) &&
|
||||
!IsCloseToEnd(wp.WorldPosition, minDistance)
|
||||
).ToList();
|
||||
!IsCloseToEnd(wp.WorldPosition, minDistance)).ToList();
|
||||
|
||||
var subDoc = SubmarineInfo.OpenFile(contentFile.Path);
|
||||
Rectangle subBorders = Submarine.GetBorders(subDoc.Root);
|
||||
@@ -3137,7 +3263,7 @@ namespace Barotrauma
|
||||
}
|
||||
tempSW.Stop();
|
||||
Debug.WriteLine($"Sub {sub.Info.Name} loaded in { tempSW.ElapsedMilliseconds} (ms)");
|
||||
sub.SetPosition(spawnPoint, forceUndockFromStaticSubmarines: false);
|
||||
sub.SetPosition(spawnPoint);
|
||||
wreckPositions.Add(sub, positions);
|
||||
blockedRects.Add(sub, rects);
|
||||
return sub;
|
||||
|
||||
Reference in New Issue
Block a user