RoomSpawner mask (#33110)
* 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
This commit is contained in:
@@ -39,6 +39,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
.Where(p => !p.Abstract)
|
.Where(p => !p.Abstract)
|
||||||
.Where(p => !pair.IsTestPrototype(p))
|
.Where(p => !pair.IsTestPrototype(p))
|
||||||
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
|
.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)
|
.Select(p => p.ID)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
.Where(p => !p.Abstract)
|
.Where(p => !p.Abstract)
|
||||||
.Where(p => !pair.IsTestPrototype(p))
|
.Where(p => !pair.IsTestPrototype(p))
|
||||||
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
|
.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)
|
.Select(p => p.ID)
|
||||||
.ToList();
|
.ToList();
|
||||||
foreach (var protoId in protoIds)
|
foreach (var protoId in protoIds)
|
||||||
@@ -341,6 +343,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
"DebugExceptionInitialize",
|
"DebugExceptionInitialize",
|
||||||
"DebugExceptionStartup",
|
"DebugExceptionStartup",
|
||||||
"GridFill",
|
"GridFill",
|
||||||
|
"RoomFill",
|
||||||
"Map", // We aren't testing a map entity in this test
|
"Map", // We aren't testing a map entity in this test
|
||||||
"MapGrid",
|
"MapGrid",
|
||||||
"Broadphase",
|
"Broadphase",
|
||||||
|
|||||||
@@ -17,9 +17,20 @@ public sealed partial class DungeonSystem
|
|||||||
private readonly List<DungeonRoomPrototype> _availableRooms = new();
|
private readonly List<DungeonRoomPrototype> _availableRooms = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
public DungeonRoomPrototype? GetRoomPrototype(Vector2i size, Random random, EntityWhitelist? whitelist = null)
|
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.
|
// Can never be true.
|
||||||
if (whitelist is { Tags: null })
|
if (whitelist is { Tags: null })
|
||||||
@@ -31,7 +42,10 @@ public sealed partial class DungeonSystem
|
|||||||
|
|
||||||
foreach (var proto in _prototype.EnumeratePrototypes<DungeonRoomPrototype>())
|
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;
|
continue;
|
||||||
|
|
||||||
if (whitelist == null)
|
if (whitelist == null)
|
||||||
@@ -115,29 +129,6 @@ public sealed partial class DungeonSystem
|
|||||||
|
|
||||||
var finalRoomRotation = roomTransform.Rotation();
|
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 roomCenter = (room.Offset + room.Size / 2f) * grid.TileSize;
|
||||||
var tileOffset = -roomCenter + grid.TileSizeHalfVector;
|
var tileOffset = -roomCenter + grid.TileSizeHalfVector;
|
||||||
_tiles.Clear();
|
_tiles.Clear();
|
||||||
@@ -156,7 +147,22 @@ public sealed partial class DungeonSystem
|
|||||||
if (!clearExisting && reservedTiles?.Contains(rounded) == true)
|
if (!clearExisting && reservedTiles?.Contains(rounded) == true)
|
||||||
continue;
|
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));
|
_tiles.Add((rounded, tileRef.Tile));
|
||||||
|
|
||||||
|
if (clearExisting)
|
||||||
|
{
|
||||||
|
var anchored = _maps.GetAnchoredEntities((gridUid, grid), rounded);
|
||||||
|
foreach (var ent in anchored)
|
||||||
|
{
|
||||||
|
QueueDel(ent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Content.Shared.Procedural;
|
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Server.Procedural;
|
namespace Content.Server.Procedural;
|
||||||
|
|
||||||
@@ -18,20 +16,26 @@ public sealed partial class RoomFillComponent : Component
|
|||||||
public bool Rotation = true;
|
public bool Rotation = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Size of the room to fill.
|
/// Min size of the possible selected room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField(required: true)]
|
[DataField]
|
||||||
public Vector2i Size;
|
public Vector2i MinSize = new (3, 3);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Max size of the possible selected room.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public Vector2i MaxSize = new (10, 10);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rooms allowed for the marker.
|
/// Rooms allowed for the marker.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public EntityWhitelist? RoomWhitelist;
|
public EntityWhitelist? RoomWhitelist;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should any existing entities / decals be bulldozed first.
|
/// Should any existing entities / decals be bulldozed first.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public bool ClearExisting;
|
public bool ClearExisting = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,12 @@ public sealed class RoomFillSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnRoomFillMapInit(EntityUid uid, RoomFillComponent component, MapInitEvent args)
|
private void OnRoomFillMapInit(EntityUid uid, RoomFillComponent component, MapInitEvent args)
|
||||||
{
|
{
|
||||||
// Just test things.
|
|
||||||
if (component.Size == Vector2i.Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var xform = Transform(uid);
|
var xform = Transform(uid);
|
||||||
|
|
||||||
if (xform.GridUid != null)
|
if (xform.GridUid != null)
|
||||||
{
|
{
|
||||||
var random = new Random();
|
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)
|
if (room != null)
|
||||||
{
|
{
|
||||||
@@ -32,7 +28,7 @@ public sealed class RoomFillSystem : EntitySystem
|
|||||||
_dungeon.SpawnRoom(
|
_dungeon.SpawnRoom(
|
||||||
xform.GridUid.Value,
|
xform.GridUid.Value,
|
||||||
mapGrid,
|
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,
|
room,
|
||||||
random,
|
random,
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
using Content.Shared.Maps;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Procedural;
|
namespace Content.Shared.Procedural;
|
||||||
@@ -10,18 +10,28 @@ public sealed partial class DungeonRoomPrototype : IPrototype
|
|||||||
{
|
{
|
||||||
[IdDataField] public string ID { get; } = string.Empty;
|
[IdDataField] public string ID { get; } = string.Empty;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite), DataField("tags", customTypeSerializer:typeof(PrototypeIdListSerializer<TagPrototype>))]
|
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||||
public List<string> Tags = new();
|
public List<ProtoId<TagPrototype>> Tags = new();
|
||||||
|
|
||||||
[DataField("size", required: true)] public Vector2i Size;
|
[DataField(required: true)]
|
||||||
|
public Vector2i Size;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Path to the file to use for the room.
|
/// Path to the file to use for the room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("atlas", required: true)] public ResPath AtlasPath;
|
[DataField("atlas", required: true)]
|
||||||
|
public ResPath AtlasPath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tile offset into the atlas to use for the room.
|
/// Tile offset into the atlas to use for the room.
|
||||||
/// </summary>
|
/// </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;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,9 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: BaseRoomMarker
|
id: BaseRoomMarker
|
||||||
name: Room marker
|
name: room spawner
|
||||||
parent: MarkerBase
|
parent: MarkerBase
|
||||||
suffix: Weh
|
|
||||||
components:
|
components:
|
||||||
- type: RoomFill
|
- type: RoomFill
|
||||||
size: 5,5
|
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
- state: red
|
- state: red
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 0,0
|
offset: 0,0
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 6,0
|
offset: 6,0
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 12,0
|
offset: 12,0
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -27,6 +30,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 18,0
|
offset: 18,0
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -35,6 +39,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 0,6
|
offset: 0,6
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -43,6 +48,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 6,6
|
offset: 6,6
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -51,6 +57,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 12,6
|
offset: 12,6
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -59,6 +66,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 18,6
|
offset: 18,6
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -67,6 +75,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 0,12
|
offset: 0,12
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -75,6 +84,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 6,12
|
offset: 6,12
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -83,6 +93,7 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 12,12
|
offset: 12,12
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
@@ -91,6 +102,25 @@
|
|||||||
size: 5,5
|
size: 5,5
|
||||||
atlas: /Maps/Dungeon/vgroidinterior.yml
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
offset: 18,12
|
offset: 18,12
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
|
tags:
|
||||||
|
- VGRoidInterior
|
||||||
|
|
||||||
|
- type: dungeonRoom
|
||||||
|
id: VGRoidInterior11x5a
|
||||||
|
size: 11,5
|
||||||
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
|
offset: 0,18
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
|
tags:
|
||||||
|
- VGRoidInterior
|
||||||
|
|
||||||
|
- type: dungeonRoom
|
||||||
|
id: VGRoidInterior11x5b
|
||||||
|
size: 11,5
|
||||||
|
atlas: /Maps/Dungeon/vgroidinterior.yml
|
||||||
|
offset: 12,18
|
||||||
|
ignoreTile: FloorShuttleOrange
|
||||||
tags:
|
tags:
|
||||||
- VGRoidInterior
|
- VGRoidInterior
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user