Fix biome marker layer command (#21278)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Parallax.Biomes;
|
||||
@@ -5,6 +6,7 @@ using Content.Shared.Parallax.Biomes.Layers;
|
||||
using Content.Shared.Parallax.Biomes.Markers;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
namespace Content.Server.Parallax;
|
||||
|
||||
@@ -151,14 +153,27 @@ public sealed partial class BiomeSystem
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -44,6 +44,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
|
||||
private readonly HashSet<EntityUid> _handledEntities = new();
|
||||
private const float DefaultLoadRange = 16f;
|
||||
private float _loadRange = DefaultLoadRange;
|
||||
@@ -68,6 +70,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
||||
{
|
||||
base.Initialize();
|
||||
Log.Level = LogLevel.Debug;
|
||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
||||
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
||||
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
||||
@@ -393,6 +396,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
||||
return;
|
||||
|
||||
// Get the set of spawned nodes to avoid overlap.
|
||||
var forced = component.ForcedMarkerLayers.Contains(layer);
|
||||
var spawnSet = _tilePool.Get();
|
||||
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.
|
||||
var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, node);
|
||||
enumerator.MoveNext(out var existing);
|
||||
|
||||
if (enumerator.MoveNext(out _))
|
||||
if (!forced && existing != null)
|
||||
continue;
|
||||
|
||||
// Check if mask matches // anything blocking.
|
||||
@@ -499,6 +504,15 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
||||
layerMarkers.Add(node);
|
||||
groupSize--;
|
||||
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];
|
||||
List<(Vector2i, Tile)>? tiles = null;
|
||||
|
||||
foreach (var chunk in active)
|
||||
{
|
||||
LoadMarkerChunk(component, gridUid, grid, chunk, seed);
|
||||
|
||||
if (!component.LoadedChunks.Add(chunk))
|
||||
continue;
|
||||
|
||||
tiles ??= new List<(Vector2i, Tile)>(ChunkSize * ChunkSize);
|
||||
// Load NOW!
|
||||
LoadChunk(component, gridUid, grid, chunk, seed, tiles, xformQuery);
|
||||
LoadChunk(component, gridUid, grid, chunk, seed, tiles);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a particular queued chunk for a biome.
|
||||
/// </summary>
|
||||
private void LoadChunk(
|
||||
private void LoadMarkerChunk(
|
||||
BiomeComponent component,
|
||||
EntityUid gridUid,
|
||||
MapGridComponent grid,
|
||||
Vector2i chunk,
|
||||
int seed,
|
||||
List<(Vector2i, Tile)> tiles,
|
||||
EntityQuery<TransformComponent> xformQuery)
|
||||
int seed)
|
||||
{
|
||||
// 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);
|
||||
modified ??= _tilePool.Get();
|
||||
|
||||
// Load any pending marker tiles first.
|
||||
if (component.PendingMarkers.TryGetValue(chunk, out var layers))
|
||||
{
|
||||
foreach (var (layer, nodes) in layers)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// <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
|
||||
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));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Parallax.Biomes.Layers;
|
||||
using Content.Shared.Parallax.Biomes.Markers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Prototypes;
|
||||
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.List;
|
||||
@@ -68,8 +69,14 @@ public sealed partial class BiomeComponent : Component
|
||||
[DataField("loadedMarkers", customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<Vector2i>, BiomeMarkerLayerPrototype>))]
|
||||
public Dictionary<string, HashSet<Vector2i>> LoadedMarkers = new();
|
||||
|
||||
[DataField("markerLayers", customTypeSerializer: typeof(PrototypeIdListSerializer<BiomeMarkerLayerPrototype>))]
|
||||
public List<string> MarkerLayers = new();
|
||||
[DataField]
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user