Prevent ruins from overlapping with each other or ending up above the upper boundary of the level. Closes #894

This commit is contained in:
Joonas Rikkonen
2018-11-12 13:46:12 +02:00
parent a415f1fe23
commit 98e05e8483
@@ -515,7 +515,7 @@ namespace Barotrauma
ruins = new List<Ruin>(); ruins = new List<Ruin>();
for (int i = 0; i < generationParams.RuinCount; i++) for (int i = 0; i < generationParams.RuinCount; i++)
{ {
GenerateRuin(mainPath, mirror); GenerateRuin(mainPath, this, mirror);
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@@ -896,7 +896,7 @@ namespace Barotrauma
return tunnelNodes; return tunnelNodes;
} }
private void GenerateRuin(List<VoronoiCell> mainPath, bool mirror) private void GenerateRuin(List<VoronoiCell> 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)); 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; float ruinRadius = Math.Max(ruinSize.X, ruinSize.Y) * 0.5f;
@@ -917,7 +917,8 @@ namespace Barotrauma
float minDistSqr = minDist * minDist; float minDistSqr = minDist * minDist;
int iter = 0; 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; Vector2 weighedPathPos = ruinPos;
iter++; iter++;
@@ -938,8 +939,23 @@ namespace Barotrauma
weighedPathPos += moveAmount; weighedPathPos += moveAmount;
weighedPathPos.Y = Math.Min(borders.Y + borders.Height - ruinSize.Y / 2, weighedPathPos.Y); 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; 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; if (iter > 10000) break;
} }