Salvage expeditions (#12745)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
using Content.Shared.Parallax.Biomes.Layers;
|
||||
using Content.Shared.Parallax.Biomes.Markers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Noise;
|
||||
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;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes;
|
||||
|
||||
@@ -13,12 +17,22 @@ public sealed partial class BiomeComponent : Component
|
||||
[AutoNetworkedField]
|
||||
public int Seed;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite),
|
||||
DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer<BiomePrototype>))]
|
||||
/// <summary>
|
||||
/// The underlying entity, decal, and tile layers for the biome.
|
||||
/// </summary>
|
||||
[DataField("layers")]
|
||||
[AutoNetworkedField]
|
||||
public string BiomePrototype = "Grasslands";
|
||||
public List<IBiomeLayer> Layers = new();
|
||||
|
||||
// TODO: Need to flag tiles as not requiring custom data anymore, e.g. if we spawn an ent and don't unspawn it.
|
||||
/// <summary>
|
||||
/// Templates to use for <see cref="Layers"/>. Optional as this can be set elsewhere.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is really just here for prototype reload support.
|
||||
/// </remarks>
|
||||
[ViewVariables(VVAccess.ReadWrite),
|
||||
DataField("template", customTypeSerializer: typeof(PrototypeIdSerializer<BiomeTemplatePrototype>))]
|
||||
public string? Template;
|
||||
|
||||
/// <summary>
|
||||
/// If we've already generated a tile and couldn't deload it then we won't ever reload it in future.
|
||||
@@ -42,9 +56,16 @@ public sealed partial class BiomeComponent : Component
|
||||
[DataField("loadedChunks")]
|
||||
public readonly HashSet<Vector2i> LoadedChunks = new();
|
||||
|
||||
#region Markers
|
||||
|
||||
/// <summary>
|
||||
/// Are we currently in the process of generating?
|
||||
/// Used to flag modified tiles without callers having to deal with it.
|
||||
/// Track what markers we've loaded already to avoid double-loading.
|
||||
/// </summary>
|
||||
public bool Generating = false;
|
||||
[DataField("loadedMarkers", customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<Vector2i>, BiomeMarkerLayerPrototype>))]
|
||||
public readonly Dictionary<string, HashSet<Vector2i>> LoadedMarkers = new();
|
||||
|
||||
[DataField("markerLayers", customTypeSerializer: typeof(PrototypeIdListSerializer<BiomeMarkerLayerPrototype>))]
|
||||
public List<string> MarkerLayers = new();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
using Content.Shared.Decals;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes;
|
||||
|
||||
[Prototype("biome")]
|
||||
public sealed class BiomePrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
[DataField("desc")]
|
||||
public string Description = string.Empty;
|
||||
|
||||
[DataField("layers")]
|
||||
public List<IBiomeLayer> Layers = new();
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public interface IBiomeLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// Seed is used an offset from the relevant BiomeComponent's seed.
|
||||
/// </summary>
|
||||
FastNoiseLite Noise { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for this layer to be present. If set to 0 forces it for every tile.
|
||||
/// </summary>
|
||||
float Threshold { get; }
|
||||
}
|
||||
|
||||
public sealed class BiomeTileLayer : IBiomeLayer
|
||||
{
|
||||
[DataField("noise")] public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Which tile variants to use for this layer. Uses all of the tile's variants if none specified
|
||||
/// </summary>
|
||||
[DataField("variants")]
|
||||
public List<byte>? Variants = null;
|
||||
|
||||
[DataField("tile", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<ContentTileDefinition>))]
|
||||
public string Tile = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles actual objects such as decals and entities.
|
||||
/// </summary>
|
||||
public interface IBiomeWorldLayer : IBiomeLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// What tiles we're allowed to spawn on, real or biome.
|
||||
/// </summary>
|
||||
List<string> AllowedTiles { get; }
|
||||
}
|
||||
|
||||
public sealed class BiomeDecalLayer : IBiomeWorldLayer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer<ContentTileDefinition>))]
|
||||
public List<string> AllowedTiles { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Divide each tile up by this amount.
|
||||
/// </summary>
|
||||
[DataField("divisions")]
|
||||
public float Divisions = 1f;
|
||||
|
||||
[DataField("noise")]
|
||||
public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.8f;
|
||||
|
||||
[DataField("decals", required: true, customTypeSerializer:typeof(PrototypeIdListSerializer<DecalPrototype>))]
|
||||
public List<string> Decals = new();
|
||||
}
|
||||
|
||||
public sealed class BiomeEntityLayer : IBiomeWorldLayer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer<ContentTileDefinition>))]
|
||||
public List<string> AllowedTiles { get; } = new();
|
||||
|
||||
[DataField("noise")] public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.5f;
|
||||
|
||||
[DataField("entities", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
|
||||
public List<string> Entities = new();
|
||||
}
|
||||
17
Content.Shared/Parallax/Biomes/BiomeTemplatePrototype.cs
Normal file
17
Content.Shared/Parallax/Biomes/BiomeTemplatePrototype.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Content.Shared.Parallax.Biomes.Layers;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes;
|
||||
|
||||
/// <summary>
|
||||
/// A preset group of biome layers to be used for a <see cref="BiomeComponent"/>
|
||||
/// </summary>
|
||||
[Prototype("biomeTemplate")]
|
||||
public sealed class BiomeTemplatePrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
[DataField("layers")]
|
||||
public List<IBiomeLayer> Layers = new();
|
||||
}
|
||||
34
Content.Shared/Parallax/Biomes/Layers/BiomeDecalLayer.cs
Normal file
34
Content.Shared/Parallax/Biomes/Layers/BiomeDecalLayer.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Content.Shared.Decals;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BiomeDecalLayer : IBiomeWorldLayer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer<ContentTileDefinition>))]
|
||||
public List<string> AllowedTiles { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Divide each tile up by this amount.
|
||||
/// </summary>
|
||||
[DataField("divisions")]
|
||||
public float Divisions = 1f;
|
||||
|
||||
[DataField("noise")]
|
||||
public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.8f;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("invert")] public bool Invert { get; } = false;
|
||||
|
||||
[DataField("decals", required: true, customTypeSerializer:typeof(PrototypeIdListSerializer<DecalPrototype>))]
|
||||
public List<string> Decals = new();
|
||||
}
|
||||
18
Content.Shared/Parallax/Biomes/Layers/BiomeDummyLayer.cs
Normal file
18
Content.Shared/Parallax/Biomes/Layers/BiomeDummyLayer.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
/// <summary>
|
||||
/// Dummy layer that specifies a marker to be replaced by external code.
|
||||
/// For example if they wish to add their own layers at specific points across different templates.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BiomeDummyLayer : IBiomeLayer
|
||||
{
|
||||
[DataField("id", required: true)] public string ID = string.Empty;
|
||||
|
||||
public FastNoiseLite Noise { get; } = new();
|
||||
public float Threshold { get; }
|
||||
public bool Invert { get; }
|
||||
}
|
||||
27
Content.Shared/Parallax/Biomes/Layers/BiomeEntityLayer.cs
Normal file
27
Content.Shared/Parallax/Biomes/Layers/BiomeEntityLayer.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BiomeEntityLayer : IBiomeWorldLayer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer<ContentTileDefinition>))]
|
||||
public List<string> AllowedTiles { get; } = new();
|
||||
|
||||
[DataField("noise")] public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.5f;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("invert")] public bool Invert { get; } = false;
|
||||
|
||||
[DataField("entities", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
|
||||
public List<string> Entities = new();
|
||||
}
|
||||
28
Content.Shared/Parallax/Biomes/Layers/BiomeTileLayer.cs
Normal file
28
Content.Shared/Parallax/Biomes/Layers/BiomeTileLayer.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BiomeTileLayer : IBiomeLayer
|
||||
{
|
||||
[DataField("noise")] public FastNoiseLite Noise { get; } = new(0);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("threshold")]
|
||||
public float Threshold { get; } = 0.5f;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DataField("invert")] public bool Invert { get; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Which tile variants to use for this layer. Uses all of the tile's variants if none specified
|
||||
/// </summary>
|
||||
[DataField("variants")]
|
||||
public List<byte>? Variants = null;
|
||||
|
||||
[DataField("tile", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<ContentTileDefinition>))]
|
||||
public string Tile = string.Empty;
|
||||
}
|
||||
22
Content.Shared/Parallax/Biomes/Layers/IBiomeLayer.cs
Normal file
22
Content.Shared/Parallax/Biomes/Layers/IBiomeLayer.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Robust.Shared.Noise;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public interface IBiomeLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// Seed is used an offset from the relevant BiomeComponent's seed.
|
||||
/// </summary>
|
||||
FastNoiseLite Noise { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for this layer to be present. If set to 0 forces it for every tile.
|
||||
/// </summary>
|
||||
float Threshold { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the thresold inverted so we need to be lower than it.
|
||||
/// </summary>
|
||||
public bool Invert { get; }
|
||||
}
|
||||
12
Content.Shared/Parallax/Biomes/Layers/IBiomeWorldLayer.cs
Normal file
12
Content.Shared/Parallax/Biomes/Layers/IBiomeWorldLayer.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Content.Shared.Parallax.Biomes.Layers;
|
||||
|
||||
/// <summary>
|
||||
/// Handles actual objects such as decals and entities.
|
||||
/// </summary>
|
||||
public interface IBiomeWorldLayer : IBiomeLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// What tiles we're allowed to spawn on, real or biome.
|
||||
/// </summary>
|
||||
List<string> AllowedTiles { get; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Content.Shared.Parallax.Biomes.Points;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Markers;
|
||||
|
||||
[Prototype("biomeMarkerLayer")]
|
||||
public sealed class BiomeMarkerLayerPrototype : IBiomeMarkerLayer
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
[DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string Prototype = string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
[DataField("radius")]
|
||||
public float Radius { get; } = 12f;
|
||||
|
||||
/// <summary>
|
||||
/// How many mobs to spawn in one group.
|
||||
/// </summary>
|
||||
[DataField("groupCount")]
|
||||
public int GroupCount = 1;
|
||||
|
||||
/// <inheritdoc />
|
||||
[DataField("size")]
|
||||
public int Size { get; } = 64;
|
||||
}
|
||||
22
Content.Shared/Parallax/Biomes/Markers/IBiomeMarkerLayer.cs
Normal file
22
Content.Shared/Parallax/Biomes/Markers/IBiomeMarkerLayer.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes.Points;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies one-off marker points to be used. This could be for dungeon markers, mob markers, etc.
|
||||
/// These are run outside of the tile / decal / entity layers.
|
||||
/// </summary>
|
||||
public interface IBiomeMarkerLayer : IPrototype
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum radius between 2 points
|
||||
/// </summary>
|
||||
[DataField("radius")]
|
||||
public float Radius { get; }
|
||||
|
||||
/// <summary>
|
||||
/// How large the pre-generated points area is.
|
||||
/// </summary>
|
||||
[DataField("size")]
|
||||
public int Size { get; }
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.GameStates;
|
||||
using Content.Shared.Parallax.Biomes.Layers;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Parallax.Biomes;
|
||||
@@ -72,7 +71,7 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
public bool TryGetBiomeTile(EntityUid uid, MapGridComponent grid, FastNoiseLite noise, Vector2i indices, [NotNullWhen(true)] out Tile? tile)
|
||||
public bool TryGetBiomeTile(EntityUid uid, MapGridComponent grid, Vector2i indices, [NotNullWhen(true)] out Tile? tile)
|
||||
{
|
||||
if (grid.TryGetTileRef(indices, out var tileRef) && !tileRef.Tile.IsEmpty)
|
||||
{
|
||||
@@ -86,14 +85,13 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryGetBiomeTile(indices, ProtoManager.Index<BiomePrototype>(biome.BiomePrototype),
|
||||
biome.Noise, grid, out tile);
|
||||
return TryGetBiomeTile(indices, biome.Layers, biome.Noise, grid, out tile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the tile, real or otherwise, for the specified indices.
|
||||
/// </summary>
|
||||
public bool TryGetBiomeTile(Vector2i indices, BiomePrototype prototype, FastNoiseLite noise, MapGridComponent? grid, [NotNullWhen(true)] out Tile? tile)
|
||||
public bool TryGetBiomeTile(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent? grid, [NotNullWhen(true)] out Tile? tile)
|
||||
{
|
||||
if (grid?.TryGetTileRef(indices, out var tileRef) == true && !tileRef.Tile.IsEmpty)
|
||||
{
|
||||
@@ -103,16 +101,16 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
|
||||
var oldSeed = noise.GetSeed();
|
||||
|
||||
for (var i = prototype.Layers.Count - 1; i >= 0; i--)
|
||||
for (var i = layers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var layer = prototype.Layers[i];
|
||||
var layer = layers[i];
|
||||
|
||||
if (layer is not BiomeTileLayer tileLayer)
|
||||
continue;
|
||||
|
||||
SetNoise(noise, oldSeed, layer.Noise);
|
||||
|
||||
if (TryGetTile(indices, noise, tileLayer.Threshold, ProtoManager.Index<ContentTileDefinition>(tileLayer.Tile), tileLayer.Variants, out tile))
|
||||
if (TryGetTile(indices, noise, tileLayer.Invert, tileLayer.Threshold, ProtoManager.Index<ContentTileDefinition>(tileLayer.Tile), tileLayer.Variants, out tile))
|
||||
{
|
||||
noise.SetSeed(oldSeed);
|
||||
return true;
|
||||
@@ -127,9 +125,10 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Gets the underlying biome tile, ignoring any existing tile that may be there.
|
||||
/// </summary>
|
||||
private bool TryGetTile(Vector2i indices, FastNoiseLite seed, float threshold, ContentTileDefinition tileDef, List<byte>? variants, [NotNullWhen(true)] out Tile? tile)
|
||||
private bool TryGetTile(Vector2i indices, FastNoiseLite seed, bool invert, float threshold, ContentTileDefinition tileDef, List<byte>? variants, [NotNullWhen(true)] out Tile? tile)
|
||||
{
|
||||
var found = seed.GetNoise(indices.X, indices.Y);
|
||||
found = invert ? found * -1 : found;
|
||||
|
||||
if (found < threshold)
|
||||
{
|
||||
@@ -159,10 +158,10 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Tries to get the relevant entity for this tile.
|
||||
/// </summary>
|
||||
protected bool TryGetEntity(Vector2i indices, BiomePrototype prototype, FastNoiseLite noise, MapGridComponent grid,
|
||||
protected bool TryGetEntity(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent grid,
|
||||
[NotNullWhen(true)] out string? entity)
|
||||
{
|
||||
if (!TryGetBiomeTile(indices, prototype, noise, grid, out var tileRef))
|
||||
if (!TryGetBiomeTile(indices, layers, noise, grid, out var tileRef))
|
||||
{
|
||||
entity = null;
|
||||
return false;
|
||||
@@ -171,13 +170,15 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
var tileId = TileDefManager[tileRef.Value.TypeId].ID;
|
||||
var oldSeed = noise.GetSeed();
|
||||
|
||||
for (var i = prototype.Layers.Count - 1; i >= 0; i--)
|
||||
for (var i = layers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var layer = prototype.Layers[i];
|
||||
var layer = layers[i];
|
||||
|
||||
// Decals might block entity so need to check if there's one in front of us.
|
||||
switch (layer)
|
||||
{
|
||||
case BiomeDummyLayer:
|
||||
continue;
|
||||
case IBiomeWorldLayer worldLayer:
|
||||
if (!worldLayer.AllowedTiles.Contains(tileId))
|
||||
continue;
|
||||
@@ -188,7 +189,9 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
}
|
||||
|
||||
SetNoise(noise, oldSeed, layer.Noise);
|
||||
var invert = layer.Invert;
|
||||
var value = noise.GetNoise(indices.X, indices.Y);
|
||||
value = invert ? value * -1 : value;
|
||||
|
||||
if (value < layer.Threshold)
|
||||
{
|
||||
@@ -215,10 +218,10 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Tries to get the relevant decals for this tile.
|
||||
/// </summary>
|
||||
public bool TryGetDecals(Vector2i indices, BiomePrototype prototype, FastNoiseLite noise, MapGridComponent grid,
|
||||
public bool TryGetDecals(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent grid,
|
||||
[NotNullWhen(true)] out List<(string ID, Vector2 Position)>? decals)
|
||||
{
|
||||
if (!TryGetBiomeTile(indices, prototype, noise, grid, out var tileRef))
|
||||
if (!TryGetBiomeTile(indices, layers, noise, grid, out var tileRef))
|
||||
{
|
||||
decals = null;
|
||||
return false;
|
||||
@@ -227,13 +230,15 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
var tileId = TileDefManager[tileRef.Value.TypeId].ID;
|
||||
var oldSeed = noise.GetSeed();
|
||||
|
||||
for (var i = prototype.Layers.Count - 1; i >= 0; i--)
|
||||
for (var i = layers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var layer = prototype.Layers[i];
|
||||
var layer = layers[i];
|
||||
|
||||
// Entities might block decal so need to check if there's one in front of us.
|
||||
switch (layer)
|
||||
{
|
||||
case BiomeDummyLayer:
|
||||
continue;
|
||||
case IBiomeWorldLayer worldLayer:
|
||||
if (!worldLayer.AllowedTiles.Contains(tileId))
|
||||
continue;
|
||||
@@ -244,11 +249,15 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
}
|
||||
|
||||
SetNoise(noise, oldSeed, layer.Noise);
|
||||
var invert = layer.Invert;
|
||||
|
||||
// Check if the other layer should even render, if not then keep going.
|
||||
if (layer is not BiomeDecalLayer decalLayer)
|
||||
{
|
||||
if (noise.GetNoise(indices.X, indices.Y) < layer.Threshold)
|
||||
var value = noise.GetNoise(indices.X, indices.Y);
|
||||
value = invert ? value * -1 : value;
|
||||
|
||||
if (value < layer.Threshold)
|
||||
continue;
|
||||
|
||||
decals = null;
|
||||
@@ -264,6 +273,7 @@ public abstract class SharedBiomeSystem : EntitySystem
|
||||
{
|
||||
var index = new Vector2(indices.X + x * 1f / decalLayer.Divisions, indices.Y + y * 1f / decalLayer.Divisions);
|
||||
var decalValue = noise.GetNoise(index.X, index.Y);
|
||||
decalValue = invert ? decalValue * -1 : decalValue;
|
||||
|
||||
if (decalValue < decalLayer.Threshold)
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user