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

View File

@@ -515,7 +515,7 @@ namespace Barotrauma
ruins = new List<Ruin>();
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<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));
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;
}