Gateway destinations (#21040)

* Gateway generation

* Gateway stuff

* gatewehs

* mercenaries

* play area

* Range fixes and tweaks

* weh

* Gateway UI polish

* Lots of fixes

* Knock some items off

* Fix dungeon spawning

Realistically we should probably be using a salvage job.

* wahwah

* wehvs

* expression

* weh

* eee

* a

* a

* WEH

* frfr

* Gatwey

* Fix gateway windows

* Fix gateway windows

* a

* a

* Better layer masking

* a

* a

* Noise fixes

* a

* Fix fractal calculations

* a

* More fixes

* Fixes

* Add layers back in

* Fixes

* namespaces and ftl

* Other TODO

* Fix distance

* Cleanup

* Fix test
This commit is contained in:
metalgearsloth
2023-11-15 13:23:40 +11:00
committed by GitHub
parent 67a3c3a6a3
commit 816ee2e1ab
51 changed files with 1562 additions and 959 deletions

View File

@@ -6,6 +6,7 @@ using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Noise;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Utility;
namespace Content.Shared.Parallax.Biomes;
@@ -13,21 +14,11 @@ namespace Content.Shared.Parallax.Biomes;
public abstract class SharedBiomeSystem : EntitySystem
{
[Dependency] protected readonly IPrototypeManager ProtoManager = default!;
[Dependency] private readonly ISerializationManager _serManager = default!;
[Dependency] protected readonly ITileDefinitionManager TileDefManager = default!;
protected const byte ChunkSize = 8;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BiomeComponent, AfterAutoHandleStateEvent>(OnBiomeAfterHandleState);
}
private void OnBiomeAfterHandleState(EntityUid uid, BiomeComponent component, ref AfterAutoHandleStateEvent args)
{
component.Noise.SetSeed(component.Seed);
}
private T Pick<T>(List<T> collection, float value)
{
// Listen I don't need this exact and I'm too lazy to finetune just for random ent picking.
@@ -89,13 +80,13 @@ public abstract class SharedBiomeSystem : EntitySystem
return false;
}
return TryGetBiomeTile(indices, biome.Layers, biome.Noise, grid, out tile);
return TryGetBiomeTile(indices, biome.Layers, biome.Seed, grid, out tile);
}
/// <summary>
/// Tries to get the tile, real or otherwise, for the specified indices.
/// </summary>
public bool TryGetBiomeTile(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent? grid, [NotNullWhen(true)] out Tile? tile)
public bool TryGetBiomeTile(Vector2i indices, List<IBiomeLayer> layers, int seed, MapGridComponent? grid, [NotNullWhen(true)] out Tile? tile)
{
if (grid?.TryGetTileRef(indices, out var tileRef) == true && !tileRef.Tile.IsEmpty)
{
@@ -103,23 +94,23 @@ public abstract class SharedBiomeSystem : EntitySystem
return true;
}
var oldSeed = noise.GetSeed();
for (var i = layers.Count - 1; i >= 0; i--)
{
var layer = layers[i];
var noiseCopy = GetNoise(layer.Noise, seed);
var invert = layer.Invert;
var value = noiseCopy.GetNoise(indices.X, indices.Y);
value = invert ? value * -1 : value;
if (value < layer.Threshold)
continue;
// 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<BiomeTemplatePrototype>(meta.Template).Layers, noise,
grid, out tile))
if (TryGetBiomeTile(indices, ProtoManager.Index<BiomeTemplatePrototype>(meta.Template).Layers, seed, grid, out tile))
{
noise.SetSeed(oldSeed);
return true;
}
@@ -129,16 +120,12 @@ public abstract class SharedBiomeSystem : EntitySystem
if (layer is not BiomeTileLayer tileLayer)
continue;
SetNoise(noise, oldSeed, layer.Noise);
if (TryGetTile(indices, noise, tileLayer.Invert, tileLayer.Threshold, ProtoManager.Index<ContentTileDefinition>(tileLayer.Tile), tileLayer.Variants, out tile))
if (TryGetTile(indices, noiseCopy, tileLayer.Invert, tileLayer.Threshold, ProtoManager.Index<ContentTileDefinition>(tileLayer.Tile), tileLayer.Variants, out tile))
{
noise.SetSeed(oldSeed);
return true;
}
}
noise.SetSeed(oldSeed);
tile = null;
return false;
}
@@ -146,9 +133,9 @@ 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, bool invert, float threshold, ContentTileDefinition tileDef, List<byte>? variants, [NotNullWhen(true)] out Tile? tile)
private bool TryGetTile(Vector2i indices, FastNoiseLite noise, bool invert, float threshold, ContentTileDefinition tileDef, List<byte>? variants, [NotNullWhen(true)] out Tile? tile)
{
var found = seed.GetNoise(indices.X, indices.Y);
var found = noise.GetNoise(indices.X, indices.Y);
found = invert ? found * -1 : found;
if (found < threshold)
@@ -163,7 +150,7 @@ public abstract class SharedBiomeSystem : EntitySystem
// Pick a variant tile if they're available as well
if (variantCount > 1)
{
var variantValue = (seed.GetNoise(indices.X * 8, indices.Y * 8, variantCount) + 1f) / 2f;
var variantValue = (noise.GetNoise(indices.X * 8, indices.Y * 8, variantCount) + 1f) / 2f;
variant = (byte) Pick(variantCount, variantValue);
if (variants != null)
@@ -179,23 +166,28 @@ public abstract class SharedBiomeSystem : EntitySystem
/// <summary>
/// Tries to get the relevant entity for this tile.
/// </summary>
protected bool TryGetEntity(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent grid,
public bool TryGetEntity(Vector2i indices, BiomeComponent component, MapGridComponent grid,
[NotNullWhen(true)] out string? entity)
{
if (!TryGetBiomeTile(indices, layers, noise, grid, out var tileRef))
if (!TryGetBiomeTile(indices, component.Layers, component.Seed, grid, out var tile))
{
entity = null;
return false;
}
var tileId = TileDefManager[tileRef.Value.TypeId].ID;
var oldSeed = noise.GetSeed();
return TryGetEntity(indices, component.Layers, tile.Value, component.Seed, grid, out entity);
}
private bool TryGetEntity(Vector2i indices, List<IBiomeLayer> layers, Tile tileRef, int seed, MapGridComponent grid,
[NotNullWhen(true)] out string? entity)
{
var tileId = TileDefManager[tileRef.TypeId].ID;
for (var i = layers.Count - 1; i >= 0; 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:
@@ -211,9 +203,10 @@ public abstract class SharedBiomeSystem : EntitySystem
continue;
}
SetNoise(noise, oldSeed, layer.Noise);
var noiseCopy = GetNoise(layer.Noise, seed);
var invert = layer.Invert;
var value = noise.GetNoise(indices.X, indices.Y);
var value = noiseCopy.GetNoise(indices.X, indices.Y);
value = invert ? value * -1 : value;
if (value < layer.Threshold)
@@ -221,29 +214,26 @@ public abstract class SharedBiomeSystem : EntitySystem
if (layer is BiomeMetaLayer meta)
{
if (TryGetEntity(indices, ProtoManager.Index<BiomeTemplatePrototype>(meta.Template).Layers, noise, grid, out entity))
if (TryGetEntity(indices, ProtoManager.Index<BiomeTemplatePrototype>(meta.Template).Layers, tileRef, seed, grid, out entity))
{
noise.SetSeed(oldSeed);
return true;
}
continue;
}
// Decals might block entity so need to check if there's one in front of us.
if (layer is not BiomeEntityLayer biomeLayer)
{
entity = null;
noise.SetSeed(oldSeed);
return false;
}
var noiseValue = noise.GetNoise(indices.X, indices.Y, i);
var noiseValue = noiseCopy.GetNoise(indices.X, indices.Y, i);
entity = Pick(biomeLayer.Entities, (noiseValue + 1f) / 2f);
noise.SetSeed(oldSeed);
return true;
}
noise.SetSeed(oldSeed);
entity = null;
return false;
}
@@ -251,17 +241,16 @@ public abstract class SharedBiomeSystem : EntitySystem
/// <summary>
/// Tries to get the relevant decals for this tile.
/// </summary>
public bool TryGetDecals(Vector2i indices, List<IBiomeLayer> layers, FastNoiseLite noise, MapGridComponent grid,
public bool TryGetDecals(Vector2i indices, List<IBiomeLayer> layers, int seed, MapGridComponent grid,
[NotNullWhen(true)] out List<(string ID, Vector2 Position)>? decals)
{
if (!TryGetBiomeTile(indices, layers, noise, grid, out var tileRef))
if (!TryGetBiomeTile(indices, layers, seed, grid, out var tileRef))
{
decals = null;
return false;
}
var tileId = TileDefManager[tileRef.Value.TypeId].ID;
var oldSeed = noise.GetSeed();
for (var i = layers.Count - 1; i >= 0; i--)
{
@@ -283,17 +272,18 @@ public abstract class SharedBiomeSystem : EntitySystem
continue;
}
SetNoise(noise, oldSeed, layer.Noise);
var invert = layer.Invert;
var noiseCopy = GetNoise(layer.Noise, seed);
var value = noiseCopy.GetNoise(indices.X, indices.Y);
value = invert ? value * -1 : value;
if (value < layer.Threshold)
continue;
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<BiomeTemplatePrototype>(meta.Template).Layers, noise, grid, out decals))
if (TryGetDecals(indices, ProtoManager.Index<BiomeTemplatePrototype>(meta.Template).Layers, seed, grid, out decals))
{
noise.SetSeed(oldSeed);
return true;
}
@@ -303,14 +293,7 @@ public abstract class SharedBiomeSystem : EntitySystem
// Check if the other layer should even render, if not then keep going.
if (layer is not BiomeDecalLayer decalLayer)
{
var value = noise.GetNoise(indices.X, indices.Y);
value = invert ? value * -1 : value;
if (value < layer.Threshold)
continue;
decals = null;
noise.SetSeed(oldSeed);
return false;
}
@@ -321,13 +304,13 @@ public abstract class SharedBiomeSystem : EntitySystem
for (var y = 0; y < decalLayer.Divisions; y++)
{
var index = new Vector2(indices.X + x * 1f / decalLayer.Divisions, indices.Y + y * 1f / decalLayer.Divisions);
var decalValue = noise.GetNoise(index.X, index.Y);
var decalValue = noiseCopy.GetNoise(index.X, index.Y);
decalValue = invert ? decalValue * -1 : decalValue;
if (decalValue < decalLayer.Threshold)
continue;
decals.Add((Pick(decalLayer.Decals, (noise.GetNoise(indices.X, indices.Y, x + y * decalLayer.Divisions) + 1f) / 2f), index));
decals.Add((Pick(decalLayer.Decals, (noiseCopy.GetNoise(indices.X, indices.Y, x + y * decalLayer.Divisions) + 1f) / 2f), index));
}
}
@@ -335,34 +318,20 @@ public abstract class SharedBiomeSystem : EntitySystem
if (decals.Count == 0)
continue;
noise.SetSeed(oldSeed);
return true;
}
noise.SetSeed(oldSeed);
decals = null;
return false;
}
private void SetNoise(FastNoiseLite noise, int oldSeed, FastNoiseLite data)
private FastNoiseLite GetNoise(FastNoiseLite seedNoise, int seed)
{
// General
noise.SetSeed(oldSeed + data.GetSeed());
noise.SetFrequency(data.GetFrequency());
noise.SetNoiseType(data.GetNoiseType());
noise.GetRotationType3D();
// Fractal
noise.SetFractalType(data.GetFractalType());
noise.SetFractalOctaves(data.GetFractalOctaves());
noise.SetFractalLacunarity(data.GetFractalLacunarity());
// Cellular
noise.SetCellularDistanceFunction(data.GetCellularDistanceFunction());
noise.SetCellularReturnType(data.GetCellularReturnType());
noise.SetCellularJitter(data.GetCellularJitter());
// Domain warps require separate noise
var noiseCopy = new FastNoiseLite();
_serManager.CopyTo(seedNoise, ref noiseCopy, notNullableOverride: true);
noiseCopy.SetSeed(noiseCopy.GetSeed() + seed);
// Ensure re-calculate is run.
noiseCopy.SetFractalOctaves(noiseCopy.GetFractalOctaves());
return noiseCopy;
}
}