* DungeonData rework Back to fields, serializes better, just make new layers dumby. * wawawewa * Fix this * Fixes * Port the work over * wawawewa * zoom * Kinda workin * Adjust wawa * Unloading work * Ore + entitytable fixes Iterate every dungeon not just last. * Big shot * wawawewa * Fixes * true * Fixes # Conflicts: # Content.Server/Procedural/DungeonJob/DungeonJob.cs * wawawewa * Fixes * Fix * Lot of work * wawawewa * Fixing * eh? * a * Fix a heap of stuff * Better ignored check * Reserve tile changes * biome * changes * wawawewa * Fixes & snow * Shadow fixes * wawawewa * smol * Add layer API * More work * wawawewa * Preloads and running again * wawawewa * Modified * Replacements and command * Runtime support * werk * Fix expeds + dungeon alltiles * reh --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
145 lines
5.2 KiB
C#
145 lines
5.2 KiB
C#
using System.Threading.Tasks;
|
|
using Content.Shared.Maps;
|
|
using Content.Shared.Procedural;
|
|
using Content.Shared.Procedural.PostGeneration;
|
|
using Content.Shared.Storage;
|
|
using Robust.Shared.Map.Components;
|
|
|
|
namespace Content.Server.Procedural.DungeonJob;
|
|
|
|
public sealed partial class DungeonJob
|
|
{
|
|
/// <summary>
|
|
/// <see cref="JunctionDunGen"/>
|
|
/// </summary>
|
|
private async Task PostGen(JunctionDunGen gen, Dungeon dungeon, HashSet<Vector2i> reservedTiles, Random random)
|
|
{
|
|
var tileDef = _tileDefManager[gen.Tile];
|
|
var contents = _prototype.Index(gen.Contents);
|
|
|
|
// N-wide junctions
|
|
foreach (var tile in dungeon.CorridorTiles)
|
|
{
|
|
if (!_anchorable.TileFree((_gridUid, _grid), tile, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
|
|
continue;
|
|
|
|
// Check each direction:
|
|
// - Check if immediate neighbors are free
|
|
// - Check if the neighbors beyond that are not free
|
|
// - Then check either side if they're slightly more free
|
|
var exteriorWidth = (int) Math.Floor(gen.Width / 2f);
|
|
var width = (int) Math.Ceiling(gen.Width / 2f);
|
|
|
|
for (var i = 0; i < 2; i++)
|
|
{
|
|
var isValid = true;
|
|
var neighborDir = (Direction) (i * 2);
|
|
var neighborVec = neighborDir.ToIntVec();
|
|
|
|
for (var j = -width; j <= width; j++)
|
|
{
|
|
if (j == 0)
|
|
continue;
|
|
|
|
var neighbor = tile + neighborVec * j;
|
|
|
|
// If it's an end tile then check it's occupied.
|
|
if (j == -width ||
|
|
j == width)
|
|
{
|
|
if (!HasWall(neighbor))
|
|
{
|
|
isValid = false;
|
|
break;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// If we're not at the end tile then check it + perpendicular are free.
|
|
if (!_anchorable.TileFree((_gridUid, _grid), neighbor, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
|
|
{
|
|
isValid = false;
|
|
break;
|
|
}
|
|
|
|
var perp1 = tile + neighborVec * j + ((Direction) ((i * 2 + 2) % 8)).ToIntVec();
|
|
var perp2 = tile + neighborVec * j + ((Direction) ((i * 2 + 6) % 8)).ToIntVec();
|
|
|
|
if (!_anchorable.TileFree((_gridUid, _grid), perp1, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
|
|
{
|
|
isValid = false;
|
|
break;
|
|
}
|
|
|
|
if (!_anchorable.TileFree((_gridUid, _grid), perp2, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
|
|
{
|
|
isValid = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isValid)
|
|
continue;
|
|
|
|
// Check corners to see if either side opens up (if it's just a 1x wide corridor do nothing, needs to be a funnel.
|
|
foreach (var j in new [] {-exteriorWidth, exteriorWidth})
|
|
{
|
|
var freeCount = 0;
|
|
|
|
// Need at least 3 of 4 free
|
|
for (var k = 0; k < 4; k++)
|
|
{
|
|
var cornerDir = (Direction) (k * 2 + 1);
|
|
var cornerVec = cornerDir.ToIntVec();
|
|
var cornerNeighbor = tile + neighborVec * j + cornerVec;
|
|
|
|
if (_anchorable.TileFree((_gridUid, _grid), cornerNeighbor, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
|
|
{
|
|
freeCount++;
|
|
}
|
|
}
|
|
|
|
if (freeCount < gen.Width)
|
|
continue;
|
|
|
|
// Valid!
|
|
isValid = true;
|
|
|
|
for (var x = -width + 1; x < width; x++)
|
|
{
|
|
var weh = tile + neighborDir.ToIntVec() * x;
|
|
|
|
if (reservedTiles.Contains(weh))
|
|
continue;
|
|
|
|
var tileVariant = _tile.GetVariantTile((ContentTileDefinition)tileDef, random);
|
|
_maps.SetTile(_gridUid, _grid, weh, tileVariant);
|
|
AddLoadedTile(weh, tileVariant);
|
|
|
|
var coords = _maps.GridTileToLocal(_gridUid, _grid, weh);
|
|
var uids = _entManager.SpawnEntitiesAttachedTo(coords, _entTable.GetSpawns(contents, random));
|
|
|
|
foreach (var uid in uids)
|
|
{
|
|
AddLoadedEntity(weh, uid);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (isValid)
|
|
{
|
|
await SuspendDungeon();
|
|
|
|
if (!ValidateResume())
|
|
return;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|