From 9010dd3e1ed740ecc2eaf91336ed0a0e7ebf22bb Mon Sep 17 00:00:00 2001 From: Cheackraze <71046427+Cheackraze@users.noreply.github.com> Date: Wed, 26 Jul 2023 01:21:54 -0400 Subject: [PATCH 1/2] Revert "Revert "Add sub-biomes (#17855)"" This reverts commit eaaa580cc10d3f082d5f8679642b5b3115acb73f. --- .../Parallax/Biomes/Layers/BiomeMetaLayer.cs | 27 ++++++++++++ .../Parallax/Biomes/SharedBiomeSystem.cs | 44 +++++++++++++++++++ .../Prototypes/Procedural/biome_templates.yml | 37 ++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 Content.Shared/Parallax/Biomes/Layers/BiomeMetaLayer.cs diff --git a/Content.Shared/Parallax/Biomes/Layers/BiomeMetaLayer.cs b/Content.Shared/Parallax/Biomes/Layers/BiomeMetaLayer.cs new file mode 100644 index 00000000000..a33d6c522df --- /dev/null +++ b/Content.Shared/Parallax/Biomes/Layers/BiomeMetaLayer.cs @@ -0,0 +1,27 @@ +using Robust.Shared.Noise; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Parallax.Biomes.Layers; + +/// +/// Contains more biome layers recursively via a biome template. +/// Can be used for sub-biomes. +/// +[Serializable, NetSerializable] +public sealed class BiomeMetaLayer : IBiomeLayer +{ + [DataField("noise")] + public FastNoiseLite Noise { get; } = new(0); + + /// + [DataField("threshold")] + public float Threshold { get; } = -1f; + + /// + [DataField("invert")] + public bool Invert { get; } + + [DataField("template", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Template = string.Empty; +} diff --git a/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs index f3ec77b3c57..e22f009760b 100644 --- a/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs +++ b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs @@ -109,6 +109,23 @@ public bool TryGetBiomeTile(Vector2i indices, List layers, FastNois { var layer = layers[i]; + // Check if the tile is from meta layer, otherwise fall back to default layers. + if (layer is BiomeMetaLayer meta) + { + SetNoise(noise, oldSeed, layer.Noise); + var found = noise.GetNoise(indices.X, indices.Y); + found *= layer.Invert ? -1 : 1; + + if (found > layer.Threshold && TryGetBiomeTile(indices, ProtoManager.Index(meta.Template).Layers, noise, + grid, out tile)) + { + noise.SetSeed(oldSeed); + return true; + } + + continue; + } + if (layer is not BiomeTileLayer tileLayer) continue; @@ -187,6 +204,8 @@ protected bool TryGetEntity(Vector2i indices, List layers, FastNois if (!worldLayer.AllowedTiles.Contains(tileId)) continue; + break; + case BiomeMetaLayer: break; default: continue; @@ -198,7 +217,16 @@ protected bool TryGetEntity(Vector2i indices, List layers, FastNois value = invert ? value * -1 : value; if (value < layer.Threshold) + continue; + + if (layer is BiomeMetaLayer meta) { + if (TryGetEntity(indices, ProtoManager.Index(meta.Template).Layers, noise, grid, out entity)) + { + noise.SetSeed(oldSeed); + return true; + } + continue; } @@ -248,6 +276,8 @@ public bool TryGetDecals(Vector2i indices, List layers, FastNoiseLi if (!worldLayer.AllowedTiles.Contains(tileId)) continue; + break; + case BiomeMetaLayer: break; default: continue; @@ -256,6 +286,20 @@ public bool TryGetDecals(Vector2i indices, List layers, FastNoiseLi SetNoise(noise, oldSeed, layer.Noise); var invert = layer.Invert; + if (layer is BiomeMetaLayer meta) + { + var found = noise.GetNoise(indices.X, indices.Y); + found *= layer.Invert ? -1 : 1; + + if (found > layer.Threshold && TryGetDecals(indices, ProtoManager.Index(meta.Template).Layers, noise, grid, out decals)) + { + noise.SetSeed(oldSeed); + return true; + } + + continue; + } + // Check if the other layer should even render, if not then keep going. if (layer is not BiomeDecalLayer decalLayer) { diff --git a/Resources/Prototypes/Procedural/biome_templates.yml b/Resources/Prototypes/Procedural/biome_templates.yml index 51b3a28a46b..1dd0a0aaa47 100644 --- a/Resources/Prototypes/Procedural/biome_templates.yml +++ b/Resources/Prototypes/Procedural/biome_templates.yml @@ -1,3 +1,40 @@ +# Contains several biomes +- type: biomeTemplate + id: Continental + layers: + - !type:BiomeMetaLayer + template: Lava + - !type:BiomeMetaLayer + template: Caves + threshold: -0.5 + noise: + frequency: 0.001 + noiseType: OpenSimplex2 + fractalType: FBm + octaves: 2 + lacunarity: 2 + gain: 0.5 + - !type:BiomeMetaLayer + template: Grasslands + threshold: 0 + noise: + frequency: 0.001 + noiseType: OpenSimplex2 + fractalType: FBm + octaves: 2 + lacunarity: 2 + gain: 0.5 + - !type:BiomeMetaLayer + template: Snow + threshold: 0.5 + noise: + frequency: 0.001 + noiseType: OpenSimplex2 + fractalType: FBm + octaves: 2 + lacunarity: 2 + gain: 0.5 + # Desert # TODO: Water in desert - type: biomeTemplate From 775460afceb72696c2bce47178f2c7b0ca416dea Mon Sep 17 00:00:00 2001 From: Cheackraze <71046427+Cheackraze@users.noreply.github.com> Date: Wed, 26 Jul 2023 01:22:08 -0400 Subject: [PATCH 2/2] Revert "Revert "Fix biome recursion (#17982)"" This reverts commit 62e5cc58a37166a49ad3f245a53ff759ed15a5ac. --- Content.Server/Parallax/BiomeSystem.cs | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs index 9d38df8d5c3..d54293f5683 100644 --- a/Content.Server/Parallax/BiomeSystem.cs +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -417,7 +417,7 @@ private void LoadChunks( var startNodeY = rand.Next(lower, upper + 1); var startNode = new Vector2i(startNodeX, startNodeY); frontier.Clear(); - frontier.Add(startNode); + frontier.Add(startNode + chunk); while (groupCount > 0 && frontier.Count > 0) { @@ -434,40 +434,39 @@ private void LoadChunks( continue; var neighbor = new Vector2i(x + node.X, y + node.Y); + var chunkOffset = neighbor - chunk; // Check if it's inbounds. - if (neighbor.X < lower || - neighbor.Y < lower || - neighbor.X > upper || - neighbor.Y > upper) + if (chunkOffset.X < lower || + chunkOffset.Y < lower || + chunkOffset.X > upper || + chunkOffset.Y > upper) { continue; } + if (!spawnSet.Add(neighbor)) + continue; + frontier.Add(neighbor); } } - var actualNode = node + chunk; - - if (!spawnSet.Add(actualNode)) - continue; - // Check if it's a valid spawn, if so then use it. - var enumerator = grid.GetAnchoredEntitiesEnumerator(actualNode); + var enumerator = grid.GetAnchoredEntitiesEnumerator(node); if (enumerator.MoveNext(out _)) continue; // Check if mask matches. - TryGetEntity(actualNode, component.Layers, noiseCopy, grid, out var proto); + TryGetEntity(node, component.Layers, noiseCopy, grid, out var proto); if (proto != layerProto.EntityMask) { continue; } - var chunkOrigin = SharedMapSystem.GetChunkIndices(actualNode, ChunkSize) * ChunkSize; + var chunkOrigin = SharedMapSystem.GetChunkIndices(node, ChunkSize) * ChunkSize; if (!pending.TryGetValue(chunkOrigin, out var pendingMarkers)) { @@ -482,7 +481,7 @@ private void LoadChunks( } // Log.Info($"Added node at {actualNode} for chunk {chunkOrigin}"); - layerMarkers.Add(actualNode); + layerMarkers.Add(node); groupCount--; } }