Skip to content

Commit

Permalink
RoomSpawner mask (space-wizards#33110)
Browse files Browse the repository at this point in the history
* RoolFill can now spaw rooms with any size

* tile ignoring

* upgrade interior

* simplify

* Update DungeonSystem.Rooms.cs

* center rooms

* Update RoomFillComponent.cs

* Update RoomFillComponent.cs

* Update DungeonSystem.Rooms.cs

* Remove roomfillcoponent from integration test

* Update EntityTest.cs

* remove nullable size, replaced with minsize and maxsize

* clear existing logic refactor

* delete this one
  • Loading branch information
TheShuEd authored Feb 12, 2025
1 parent 0d33e61 commit 47cb8a0
Show file tree
Hide file tree
Showing 8 changed files with 968 additions and 580 deletions.
3 changes: 3 additions & 0 deletions Content.IntegrationTests/Tests/EntityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ await server.WaitPost(() =>
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
.Select(p => p.ID)
.ToList();

Expand Down Expand Up @@ -101,6 +102,7 @@ await server.WaitPost(() =>
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
.Select(p => p.ID)
.ToList();
foreach (var protoId in protoIds)
Expand Down Expand Up @@ -341,6 +343,7 @@ public async Task AllComponentsOneToOneDeleteTest()
"DebugExceptionInitialize",
"DebugExceptionStartup",
"GridFill",
"RoomFill",
"Map", // We aren't testing a map entity in this test
"MapGrid",
"Broadphase",
Expand Down
56 changes: 31 additions & 25 deletions Content.Server/Procedural/DungeonSystem.Rooms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,20 @@ public sealed partial class DungeonSystem
private readonly List<DungeonRoomPrototype> _availableRooms = new();

/// <summary>
/// Gets a random dungeon room matching the specified area and whitelist.
/// Gets a random dungeon room matching the specified area, whitelist and size.
/// </summary>
public DungeonRoomPrototype? GetRoomPrototype(Vector2i size, Random random, EntityWhitelist? whitelist = null)
{
return GetRoomPrototype(random, whitelist, minSize: size, maxSize: size);
}

/// <summary>
/// Gets a random dungeon room matching the specified area and whitelist and size range
/// </summary>
public DungeonRoomPrototype? GetRoomPrototype(Random random,
EntityWhitelist? whitelist = null,
Vector2i? minSize = null,
Vector2i? maxSize = null)
{
// Can never be true.
if (whitelist is { Tags: null })
Expand All @@ -31,7 +42,10 @@ public sealed partial class DungeonSystem

foreach (var proto in _prototype.EnumeratePrototypes<DungeonRoomPrototype>())
{
if (proto.Size != size)
if (minSize is not null && (proto.Size.X < minSize.Value.X || proto.Size.Y < minSize.Value.Y))
continue;

if (maxSize is not null && (proto.Size.X > maxSize.Value.X || proto.Size.Y > maxSize.Value.Y))
continue;

if (whitelist == null)
Expand Down Expand Up @@ -115,29 +129,6 @@ public void SpawnRoom(

var finalRoomRotation = roomTransform.Rotation();

// go BRRNNTTT on existing stuff
if (clearExisting)
{
var gridBounds = new Box2(Vector2.Transform(-room.Size/2, roomTransform), Vector2.Transform(room.Size/2, roomTransform));
_entitySet.Clear();
// Polygon skin moment
gridBounds = gridBounds.Enlarged(-0.05f);
_lookup.GetLocalEntitiesIntersecting(gridUid, gridBounds, _entitySet, LookupFlags.Uncontained);

foreach (var templateEnt in _entitySet)
{
Del(templateEnt);
}

if (TryComp(gridUid, out DecalGridComponent? decalGrid))
{
foreach (var decal in _decals.GetDecalsIntersecting(gridUid, gridBounds, decalGrid))
{
_decals.RemoveDecal(gridUid, decal.Index, decalGrid);
}
}
}

var roomCenter = (room.Offset + room.Size / 2f) * grid.TileSize;
var tileOffset = -roomCenter + grid.TileSizeHalfVector;
_tiles.Clear();
Expand All @@ -156,7 +147,22 @@ public void SpawnRoom(
if (!clearExisting && reservedTiles?.Contains(rounded) == true)
continue;

if (room.IgnoreTile is not null)
{
if (_maps.TryGetTileDef(templateGrid, indices, out var tileDef) && room.IgnoreTile == tileDef.ID)
continue;
}

_tiles.Add((rounded, tileRef.Tile));

if (clearExisting)
{
var anchored = _maps.GetAnchoredEntities((gridUid, grid), rounded);
foreach (var ent in anchored)
{
QueueDel(ent);
}
}
}
}

Expand Down
18 changes: 11 additions & 7 deletions Content.Server/Procedural/RoomFillComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Content.Shared.Procedural;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;

namespace Content.Server.Procedural;

Expand All @@ -18,20 +16,26 @@ public sealed partial class RoomFillComponent : Component
public bool Rotation = true;

/// <summary>
/// Size of the room to fill.
/// Min size of the possible selected room.
/// </summary>
[DataField(required: true)]
public Vector2i Size;
[DataField]
public Vector2i MinSize = new (3, 3);

/// <summary>
/// Max size of the possible selected room.
/// </summary>
[DataField]
public Vector2i MaxSize = new (10, 10);

/// <summary>
/// Rooms allowed for the marker.
/// </summary>
[DataField]
public EntityWhitelist? RoomWhitelist;

/// <summary>
/// Should any existing entities / decals be bulldozed first.
/// </summary>
[DataField]
public bool ClearExisting;
public bool ClearExisting = true;
}
8 changes: 2 additions & 6 deletions Content.Server/Procedural/RoomFillSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,20 @@ public override void Initialize()

private void OnRoomFillMapInit(EntityUid uid, RoomFillComponent component, MapInitEvent args)
{
// Just test things.
if (component.Size == Vector2i.Zero)
return;

var xform = Transform(uid);

if (xform.GridUid != null)
{
var random = new Random();
var room = _dungeon.GetRoomPrototype(component.Size, random, component.RoomWhitelist);
var room = _dungeon.GetRoomPrototype(random, component.RoomWhitelist, component.MinSize, component.MaxSize);

if (room != null)
{
var mapGrid = Comp<MapGridComponent>(xform.GridUid.Value);
_dungeon.SpawnRoom(
xform.GridUid.Value,
mapGrid,
_maps.LocalToTile(xform.GridUid.Value, mapGrid, xform.Coordinates),
_maps.LocalToTile(xform.GridUid.Value, mapGrid, xform.Coordinates) - new Vector2i(room.Size.X/2,room.Size.Y/2),
room,
random,
null,
Expand Down
22 changes: 16 additions & 6 deletions Content.Shared/Procedural/DungeonRoomPrototype.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Content.Shared.Maps;
using Content.Shared.Tag;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Utility;

namespace Content.Shared.Procedural;
Expand All @@ -10,18 +10,28 @@ public sealed partial class DungeonRoomPrototype : IPrototype
{
[IdDataField] public string ID { get; } = string.Empty;

[ViewVariables(VVAccess.ReadWrite), DataField("tags", customTypeSerializer:typeof(PrototypeIdListSerializer<TagPrototype>))]
public List<string> Tags = new();
[ViewVariables(VVAccess.ReadWrite), DataField]
public List<ProtoId<TagPrototype>> Tags = new();

[DataField("size", required: true)] public Vector2i Size;
[DataField(required: true)]
public Vector2i Size;

/// <summary>
/// Path to the file to use for the room.
/// </summary>
[DataField("atlas", required: true)] public ResPath AtlasPath;
[DataField("atlas", required: true)]
public ResPath AtlasPath;

/// <summary>
/// Tile offset into the atlas to use for the room.
/// </summary>
[DataField("offset", required: true)] public Vector2i Offset;
[DataField(required: true)]
public Vector2i Offset;

/// <summary>
/// These tiles will be ignored when copying from the atlas into the actual game,
/// allowing you to make rooms of irregular shapes that blend seamlessly into their surroundings
/// </summary>
[DataField]
public ProtoId<ContentTileDefinition>? IgnoreTile;
}
Loading

0 comments on commit 47cb8a0

Please sign in to comment.