Fix biome marker layer command (#21278)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Server.Administration;
|
using Content.Server.Administration;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.Parallax.Biomes;
|
using Content.Shared.Parallax.Biomes;
|
||||||
@@ -5,6 +6,7 @@ using Content.Shared.Parallax.Biomes.Layers;
|
|||||||
using Content.Shared.Parallax.Biomes.Markers;
|
using Content.Shared.Parallax.Biomes.Markers;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Map.Components;
|
||||||
|
|
||||||
namespace Content.Server.Parallax;
|
namespace Content.Server.Parallax;
|
||||||
|
|
||||||
@@ -151,14 +153,27 @@ public sealed partial class BiomeSystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
biome.MarkerLayers.Add(args[1]);
|
if (!biome.MarkerLayers.Add(args[1]))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
biome.ForcedMarkerLayers.Add(args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletionResult AddMarkerLayerCallbackHelper(IConsoleShell shell, string[] args)
|
private CompletionResult AddMarkerLayerCallbackHelper(IConsoleShell shell, string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length == 1)
|
if (args.Length == 1)
|
||||||
{
|
{
|
||||||
return CompletionResult.FromHintOptions(CompletionHelper.Components<BiomeComponent>(args[0], EntityManager), "Biome");
|
var allQuery = AllEntityQuery<MapComponent, BiomeComponent>();
|
||||||
|
var options = new List<CompletionOption>();
|
||||||
|
|
||||||
|
while (allQuery.MoveNext(out var mapComp, out _))
|
||||||
|
{
|
||||||
|
options.Add(new CompletionOption(mapComp.MapId.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompletionResult.FromHintOptions(options, "Biome");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.Length == 2)
|
if (args.Length == 2)
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
|
private EntityQuery<TransformComponent> _xformQuery;
|
||||||
|
|
||||||
private readonly HashSet<EntityUid> _handledEntities = new();
|
private readonly HashSet<EntityUid> _handledEntities = new();
|
||||||
private const float DefaultLoadRange = 16f;
|
private const float DefaultLoadRange = 16f;
|
||||||
private float _loadRange = DefaultLoadRange;
|
private float _loadRange = DefaultLoadRange;
|
||||||
@@ -68,6 +70,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Log.Level = LogLevel.Debug;
|
Log.Level = LogLevel.Debug;
|
||||||
|
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
||||||
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
||||||
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
||||||
@@ -393,6 +396,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the set of spawned nodes to avoid overlap.
|
// Get the set of spawned nodes to avoid overlap.
|
||||||
|
var forced = component.ForcedMarkerLayers.Contains(layer);
|
||||||
var spawnSet = _tilePool.Get();
|
var spawnSet = _tilePool.Get();
|
||||||
var frontier = new ValueList<Vector2i>(32);
|
var frontier = new ValueList<Vector2i>(32);
|
||||||
|
|
||||||
@@ -460,8 +464,9 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
|
|
||||||
// Check if it's a valid spawn, if so then use it.
|
// Check if it's a valid spawn, if so then use it.
|
||||||
var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, node);
|
var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, node);
|
||||||
|
enumerator.MoveNext(out var existing);
|
||||||
|
|
||||||
if (enumerator.MoveNext(out _))
|
if (!forced && existing != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if mask matches // anything blocking.
|
// Check if mask matches // anything blocking.
|
||||||
@@ -499,6 +504,15 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
layerMarkers.Add(node);
|
layerMarkers.Add(node);
|
||||||
groupSize--;
|
groupSize--;
|
||||||
spawnSet.Add(node);
|
spawnSet.Add(node);
|
||||||
|
|
||||||
|
if (forced && existing != null)
|
||||||
|
{
|
||||||
|
// Just lock anything so we can dump this
|
||||||
|
lock (component.PendingMarkers)
|
||||||
|
{
|
||||||
|
Del(existing.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,38 +545,39 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component.ForcedMarkerLayers.Clear();
|
||||||
var active = _activeChunks[component];
|
var active = _activeChunks[component];
|
||||||
List<(Vector2i, Tile)>? tiles = null;
|
List<(Vector2i, Tile)>? tiles = null;
|
||||||
|
|
||||||
foreach (var chunk in active)
|
foreach (var chunk in active)
|
||||||
{
|
{
|
||||||
|
LoadMarkerChunk(component, gridUid, grid, chunk, seed);
|
||||||
|
|
||||||
if (!component.LoadedChunks.Add(chunk))
|
if (!component.LoadedChunks.Add(chunk))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tiles ??= new List<(Vector2i, Tile)>(ChunkSize * ChunkSize);
|
tiles ??= new List<(Vector2i, Tile)>(ChunkSize * ChunkSize);
|
||||||
// Load NOW!
|
// Load NOW!
|
||||||
LoadChunk(component, gridUid, grid, chunk, seed, tiles, xformQuery);
|
LoadChunk(component, gridUid, grid, chunk, seed, tiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void LoadMarkerChunk(
|
||||||
/// Loads a particular queued chunk for a biome.
|
|
||||||
/// </summary>
|
|
||||||
private void LoadChunk(
|
|
||||||
BiomeComponent component,
|
BiomeComponent component,
|
||||||
EntityUid gridUid,
|
EntityUid gridUid,
|
||||||
MapGridComponent grid,
|
MapGridComponent grid,
|
||||||
Vector2i chunk,
|
Vector2i chunk,
|
||||||
int seed,
|
int seed)
|
||||||
List<(Vector2i, Tile)> tiles,
|
|
||||||
EntityQuery<TransformComponent> xformQuery)
|
|
||||||
{
|
{
|
||||||
|
// Load any pending marker tiles first.
|
||||||
|
if (!component.PendingMarkers.TryGetValue(chunk, out var layers))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// This needs to be done separately in case we try to add a marker layer and want to force it on existing
|
||||||
|
// loaded chunks.
|
||||||
component.ModifiedTiles.TryGetValue(chunk, out var modified);
|
component.ModifiedTiles.TryGetValue(chunk, out var modified);
|
||||||
modified ??= _tilePool.Get();
|
modified ??= _tilePool.Get();
|
||||||
|
|
||||||
// Load any pending marker tiles first.
|
|
||||||
if (component.PendingMarkers.TryGetValue(chunk, out var layers))
|
|
||||||
{
|
|
||||||
foreach (var (layer, nodes) in layers)
|
foreach (var (layer, nodes) in layers)
|
||||||
{
|
{
|
||||||
var layerProto = ProtoManager.Index<BiomeMarkerLayerPrototype>(layer);
|
var layerProto = ProtoManager.Index<BiomeMarkerLayerPrototype>(layer);
|
||||||
@@ -601,9 +616,26 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modified.Count == 0)
|
||||||
|
_tilePool.Return(modified);
|
||||||
|
|
||||||
component.PendingMarkers.Remove(chunk);
|
component.PendingMarkers.Remove(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a particular queued chunk for a biome.
|
||||||
|
/// </summary>
|
||||||
|
private void LoadChunk(
|
||||||
|
BiomeComponent component,
|
||||||
|
EntityUid gridUid,
|
||||||
|
MapGridComponent grid,
|
||||||
|
Vector2i chunk,
|
||||||
|
int seed,
|
||||||
|
List<(Vector2i, Tile)> tiles)
|
||||||
|
{
|
||||||
|
component.ModifiedTiles.TryGetValue(chunk, out var modified);
|
||||||
|
modified ??= _tilePool.Get();
|
||||||
|
|
||||||
// Set tiles first
|
// Set tiles first
|
||||||
for (var x = 0; x < ChunkSize; x++)
|
for (var x = 0; x < ChunkSize; x++)
|
||||||
{
|
{
|
||||||
@@ -653,7 +685,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
var ent = Spawn(entPrototype, _mapSystem.GridTileToLocal(gridUid, grid, indices));
|
var ent = Spawn(entPrototype, _mapSystem.GridTileToLocal(gridUid, grid, indices));
|
||||||
|
|
||||||
// At least for now unless we do lookups or smth, only work with anchoring.
|
// At least for now unless we do lookups or smth, only work with anchoring.
|
||||||
if (xformQuery.TryGetComponent(ent, out var xform) && !xform.Anchored)
|
if (_xformQuery.TryGetComponent(ent, out var xform) && !xform.Anchored)
|
||||||
{
|
{
|
||||||
_transform.AnchorEntity(ent, xform, gridUid, grid, indices);
|
_transform.AnchorEntity(ent, xform, gridUid, grid, indices);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Content.Shared.Parallax.Biomes.Layers;
|
|||||||
using Content.Shared.Parallax.Biomes.Markers;
|
using Content.Shared.Parallax.Biomes.Markers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Noise;
|
using Robust.Shared.Noise;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||||
@@ -68,8 +69,14 @@ public sealed partial class BiomeComponent : Component
|
|||||||
[DataField("loadedMarkers", customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<Vector2i>, BiomeMarkerLayerPrototype>))]
|
[DataField("loadedMarkers", customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<Vector2i>, BiomeMarkerLayerPrototype>))]
|
||||||
public Dictionary<string, HashSet<Vector2i>> LoadedMarkers = new();
|
public Dictionary<string, HashSet<Vector2i>> LoadedMarkers = new();
|
||||||
|
|
||||||
[DataField("markerLayers", customTypeSerializer: typeof(PrototypeIdListSerializer<BiomeMarkerLayerPrototype>))]
|
[DataField]
|
||||||
public List<string> MarkerLayers = new();
|
public HashSet<ProtoId<BiomeMarkerLayerPrototype>> MarkerLayers = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// One-tick forcing of marker layers to bulldoze any entities in the way.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public HashSet<ProtoId<BiomeMarkerLayerPrototype>> ForcedMarkerLayers = new();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user