diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs index 419bab0b6..943546cfe 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs @@ -515,7 +515,7 @@ namespace Barotrauma ruins = new List(); for (int i = 0; i < generationParams.RuinCount; i++) { - GenerateRuin(mainPath, mirror); + GenerateRuin(mainPath, this, mirror); } //---------------------------------------------------------------------------------- @@ -896,7 +896,7 @@ namespace Barotrauma return tunnelNodes; } - private void GenerateRuin(List mainPath, bool mirror) + private void GenerateRuin(List mainPath, Level level, bool mirror) { Vector2 ruinSize = new Vector2(Rand.Range(5000.0f, 8000.0f, Rand.RandSync.Server), Rand.Range(5000.0f, 8000.0f, Rand.RandSync.Server)); float ruinRadius = Math.Max(ruinSize.X, ruinSize.Y) * 0.5f; @@ -917,7 +917,8 @@ namespace Barotrauma float minDistSqr = minDist * minDist; int iter = 0; - while (mainPath.Any(p => Vector2.DistanceSquared(ruinPos, p.Center) < minDistSqr)) + while (mainPath.Any(p => Vector2.DistanceSquared(ruinPos, p.Center) < minDistSqr) || + ruins.Any(r => r.Area.Intersects(new Rectangle(MathUtils.ToPoint(ruinPos - ruinSize / 2), MathUtils.ToPoint(ruinSize))))) { Vector2 weighedPathPos = ruinPos; iter++; @@ -934,12 +935,27 @@ namespace Barotrauma if (distSqr > 10000.0f * 10000.0f) continue; Vector2 moveAmount = Vector2.Normalize(diff) * 100000.0f / (float)Math.Sqrt(distSqr); - + weighedPathPos += moveAmount; weighedPathPos.Y = Math.Min(borders.Y + borders.Height - ruinSize.Y / 2, weighedPathPos.Y); } + Rectangle ruinArea = new Rectangle(MathUtils.ToPoint(ruinPos - ruinSize / 2), MathUtils.ToPoint(ruinSize)); + foreach (Ruin otherRuin in ruins) + { + if (!otherRuin.Area.Intersects(ruinArea)) continue; + Vector2 diff = (ruinArea.Center - otherRuin.Area.Center).ToVector2(); + if (diff.LengthSquared() < 0.01f) { diff = -Vector2.UnitY; } + weighedPathPos += Vector2.Normalize(diff) * + (Math.Max(ruinArea.Width, ruinArea.Height) + Math.Max(otherRuin.Area.Width, otherRuin.Area.Height)) / 2.0f; + } + ruinPos = weighedPathPos; + if (ruinPos.Y + ruinSize.Y / 2.0f > level.Size.Y) + { + ruinPos.Y -= ((ruinPos.Y + ruinSize.Y / 2.0f) - level.Size.Y); + } + if (iter > 10000) break; }