From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Mon, 29 Jan 2024 02:41:59 +0000 (-0500) Subject: Make procgen use weighted variants (#24669) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=2a6705818bf510aee3026c7f3c3a4ed56f188189;p=space-station-14.git Make procgen use weighted variants (#24669) --- diff --git a/Content.Server/Gateway/Systems/GatewayGeneratorSystem.cs b/Content.Server/Gateway/Systems/GatewayGeneratorSystem.cs index 7d6f133e93..c8b30af620 100644 --- a/Content.Server/Gateway/Systems/GatewayGeneratorSystem.cs +++ b/Content.Server/Gateway/Systems/GatewayGeneratorSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Procedural; using Content.Server.Salvage; using Content.Shared.CCVar; using Content.Shared.Dataset; +using Content.Shared.Maps; using Content.Shared.Movement.Components; using Content.Shared.Parallax.Biomes; using Content.Shared.Physics; @@ -41,6 +42,7 @@ public sealed class GatewayGeneratorSystem : EntitySystem [Dependency] private readonly MetaDataSystem _metadata = default!; [Dependency] private readonly RestrictedRangeSystem _restricted = default!; [Dependency] private readonly SharedMapSystem _maps = default!; + [Dependency] private readonly TileSystem _tile = default!; [ValidatePrototypeId] private const string PlanetNames = "names_borer"; @@ -132,7 +134,7 @@ public sealed class GatewayGeneratorSystem : EntitySystem { for (var y = -2; y <= 2; y++) { - tiles.Add((new Vector2i(x, y) + origin, new Tile(tileDef.TileId, variant: random.NextByte(tileDef.Variants)))); + tiles.Add((new Vector2i(x, y) + origin, new Tile(tileDef.TileId, variant: _tile.PickVariant((ContentTileDefinition) tileDef, random)))); } } diff --git a/Content.Server/Procedural/DungeonJob.NoiseDunGen.cs b/Content.Server/Procedural/DungeonJob.NoiseDunGen.cs index 7393ce72fd..73c3386ead 100644 --- a/Content.Server/Procedural/DungeonJob.NoiseDunGen.cs +++ b/Content.Server/Procedural/DungeonJob.NoiseDunGen.cs @@ -84,7 +84,7 @@ public sealed partial class DungeonJob foundNoise = true; noiseFill = true; var tileDef = _tileDefManager[layer.Tile]; - var variant = rand.NextByte(tileDef.Variants); + var variant = _tile.PickVariant((ContentTileDefinition) tileDef, rand); tiles.Add((node, new Tile(tileDef.TileId, variant: variant))); roomTiles.Add(node); diff --git a/Content.Server/Procedural/DungeonJob.PostGen.cs b/Content.Server/Procedural/DungeonJob.PostGen.cs index 559d5fedb9..ffbb9454dc 100644 --- a/Content.Server/Procedural/DungeonJob.PostGen.cs +++ b/Content.Server/Procedural/DungeonJob.PostGen.cs @@ -3,6 +3,7 @@ using System.Numerics; using System.Threading.Tasks; using Content.Server.NodeContainer; using Content.Shared.Doors.Components; +using Content.Shared.Maps; using Content.Shared.Physics; using Content.Shared.Procedural; using Content.Shared.Procedural.PostGeneration; @@ -191,7 +192,7 @@ public sealed partial class DungeonJob if (!_anchorable.TileFree(grid, neighbor, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask)) continue; - tiles.Add((neighbor, _tileDefManager.GetVariantTile(tileDef, random))); + tiles.Add((neighbor, _tile.GetVariantTile((ContentTileDefinition) tileDef, random))); } foreach (var index in dungeon.CorridorExteriorTiles) @@ -202,7 +203,7 @@ public sealed partial class DungeonJob if (!_anchorable.TileFree(grid, index, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask)) continue; - tiles.Add((index, _tileDefManager.GetVariantTile(tileDef, random))); + tiles.Add((index, _tile.GetVariantTile((ContentTileDefinition)tileDef, random))); } grid.SetTiles(tiles); @@ -478,7 +479,7 @@ public sealed partial class DungeonJob isValid = true; // Entrance wew - grid.SetTile(tile, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(tile, _tile.GetVariantTile((ContentTileDefinition) tileDef, random)); ClearDoor(dungeon, grid, tile); var gridCoords = grid.GridTileToLocal(tile); // Need to offset the spawn to avoid spawning in the room. @@ -496,7 +497,7 @@ public sealed partial class DungeonJob continue; } - grid.SetTile(nearTile.GridIndices, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(nearTile.GridIndices, _tile.GetVariantTile((ContentTileDefinition) tileDef, random));; } break; @@ -589,7 +590,7 @@ public sealed partial class DungeonJob { var neighbor = tile + dirVec * j; - tiles.Add((neighbor, _tileDefManager.GetVariantTile(tileDef, random))); + tiles.Add((neighbor, _tile.GetVariantTile((ContentTileDefinition) tileDef, random))); index++; takenTiles.Add(neighbor); } @@ -690,7 +691,7 @@ public sealed partial class DungeonJob { var tile = validTiles[j]; var gridPos = grid.GridTileToLocal(tile); - grid.SetTile(tile, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(tile, _tile.GetVariantTile((ContentTileDefinition) tileDef, random)); _entManager.SpawnEntities(gridPos, gen.Entities); } @@ -721,7 +722,7 @@ public sealed partial class DungeonJob { foreach (var entrance in room.Entrances) { - setTiles.Add((entrance, _tileDefManager.GetVariantTile(tileDef, random))); + setTiles.Add((entrance, _tile.GetVariantTile((ContentTileDefinition) tileDef, random))); } } @@ -857,7 +858,7 @@ public sealed partial class DungeonJob foreach (var tile in corridorTiles) { - setTiles.Add((tile, _tileDefManager.GetVariantTile(tileDef, random))); + setTiles.Add((tile, _tile.GetVariantTile((ContentTileDefinition) tileDef, random))); } grid.SetTiles(setTiles); @@ -902,7 +903,7 @@ public sealed partial class DungeonJob if (!dungeon.RoomExteriorTiles.Contains(neighbor)) continue; - tiles.Add((neighbor, _tileDefManager.GetVariantTile(tileDef, random))); + tiles.Add((neighbor, _tile.GetVariantTile((ContentTileDefinition) tileDef, random))); spawnPositions.Add(neighbor); } } @@ -1013,7 +1014,7 @@ public sealed partial class DungeonJob for (var x = -width + 1; x < width; x++) { var weh = tile + neighborDir.ToIntVec() * x; - grid.SetTile(weh, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(weh, _tile.GetVariantTile((ContentTileDefinition) tileDef, random)); var coords = grid.GridTileToLocal(weh); _entManager.SpawnEntities(coords, gen.Entities); @@ -1131,7 +1132,7 @@ public sealed partial class DungeonJob continue; width--; - grid.SetTile(node, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(node, _tile.GetVariantTile((ContentTileDefinition) tileDef, random)); if (gen.EdgeEntities != null && nodeDistances.Count - i <= 2) { @@ -1217,7 +1218,7 @@ public sealed partial class DungeonJob if (!random.Prob(gen.Prob) || !checkedTiles.Add(neighbor)) continue; - grid.SetTile(neighbor, _tileDefManager.GetVariantTile(tileDef, random)); + grid.SetTile(neighbor, _tile.GetVariantTile((ContentTileDefinition) tileDef, random)); var gridPos = grid.GridTileToLocal(neighbor); var protoNames = EntitySpawnCollection.GetSpawns(gen.Spawns, random); diff --git a/Content.Server/Procedural/DungeonJob.cs b/Content.Server/Procedural/DungeonJob.cs index 55c4474d31..c8a69808d3 100644 --- a/Content.Server/Procedural/DungeonJob.cs +++ b/Content.Server/Procedural/DungeonJob.cs @@ -4,6 +4,7 @@ using Content.Server.Construction; using Robust.Shared.CPUJob.JobQueues; using Content.Server.Decals; using Content.Shared.Construction.EntitySystems; +using Content.Shared.Maps; using Content.Shared.Procedural; using Content.Shared.Procedural.DungeonGenerators; using Content.Shared.Procedural.PostGeneration; @@ -27,6 +28,7 @@ public sealed partial class DungeonJob : Job private readonly DecalSystem _decals; private readonly DungeonSystem _dungeon; private readonly EntityLookupSystem _lookup; + private readonly TileSystem _tile; private readonly SharedMapSystem _maps; private readonly SharedTransformSystem _transform; private EntityQuery _tagQuery; @@ -51,6 +53,7 @@ public sealed partial class DungeonJob : Job DecalSystem decals, DungeonSystem dungeon, EntityLookupSystem lookup, + TileSystem tile, SharedTransformSystem transform, DungeonConfigPrototype gen, MapGridComponent grid, @@ -69,6 +72,7 @@ public sealed partial class DungeonJob : Job _decals = decals; _dungeon = dungeon; _lookup = lookup; + _tile = tile; _maps = _entManager.System(); _transform = transform; _tagQuery = _entManager.GetEntityQuery(); diff --git a/Content.Server/Procedural/DungeonSystem.Rooms.cs b/Content.Server/Procedural/DungeonSystem.Rooms.cs index d299048f51..03bcc2b4b1 100644 --- a/Content.Server/Procedural/DungeonSystem.Rooms.cs +++ b/Content.Server/Procedural/DungeonSystem.Rooms.cs @@ -1,5 +1,6 @@ using System.Numerics; using Content.Shared.Decals; +using Content.Shared.Maps; using Content.Shared.Procedural; using Content.Shared.Random.Helpers; using Content.Shared.Whitelist; @@ -230,7 +231,7 @@ public sealed partial class DungeonSystem // but place 1 nanometre off grid and fail the add. if (!_maps.TryGetTileRef(gridUid, grid, tilePos, out var tileRef) || tileRef.Tile.IsEmpty) { - _maps.SetTile(gridUid, grid, tilePos, _tileDefManager.GetVariantTile(FallbackTileId, _random)); + _maps.SetTile(gridUid, grid, tilePos, _tile.GetVariantTile((ContentTileDefinition) _tileDefManager[FallbackTileId], _random.GetRandom())); } var result = _decals.TryAddDecal( diff --git a/Content.Server/Procedural/DungeonSystem.cs b/Content.Server/Procedural/DungeonSystem.cs index bdd194caa4..069508bcbb 100644 --- a/Content.Server/Procedural/DungeonSystem.cs +++ b/Content.Server/Procedural/DungeonSystem.cs @@ -31,6 +31,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem [Dependency] private readonly AnchorableSystem _anchorable = default!; [Dependency] private readonly DecalSystem _decals = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly MapLoaderSystem _loader = default!; [Dependency] private readonly SharedMapSystem _maps = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; @@ -198,6 +199,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem _decals, this, _lookup, + _tile, _transform, gen, grid, @@ -229,6 +231,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem _decals, this, _lookup, + _tile, _transform, gen, grid, diff --git a/Content.Shared/Maps/ContentTileDefinition.cs b/Content.Shared/Maps/ContentTileDefinition.cs index 40f337b129..6588735802 100644 --- a/Content.Shared/Maps/ContentTileDefinition.cs +++ b/Content.Shared/Maps/ContentTileDefinition.cs @@ -67,7 +67,7 @@ namespace Content.Shared.Maps /// /// This controls what variants the `variantize` command is allowed to use. /// - [DataField("placementVariants")] public float[] PlacementVariants { get; set; } = new [] { 1f }; + [DataField("placementVariants")] public float[] PlacementVariants { get; set; } = { 1f }; [DataField("thermalConductivity")] public float ThermalConductivity = 0.04f; diff --git a/Content.Shared/Maps/TileSystem.cs b/Content.Shared/Maps/TileSystem.cs index 51a5d4b85a..d87b3ca50d 100644 --- a/Content.Shared/Maps/TileSystem.cs +++ b/Content.Shared/Maps/TileSystem.cs @@ -25,12 +25,29 @@ public sealed class TileSystem : EntitySystem /// Returns a weighted pick of a tile variant. /// public byte PickVariant(ContentTileDefinition tile) + { + return PickVariant(tile, _robustRandom.GetRandom()); + } + + /// + /// Returns a weighted pick of a tile variant. + /// + public byte PickVariant(ContentTileDefinition tile, int seed) + { + var rand = new System.Random(seed); + return PickVariant(tile, rand); + } + + /// + /// Returns a weighted pick of a tile variant. + /// + public byte PickVariant(ContentTileDefinition tile, System.Random random) { var variants = tile.PlacementVariants; var sum = variants.Sum(); var accumulated = 0f; - var rand = _robustRandom.NextFloat() * sum; + var rand = random.NextFloat() * sum; for (byte i = 0; i < variants.Length; ++i) { @@ -44,6 +61,23 @@ public sealed class TileSystem : EntitySystem throw new InvalidOperationException($"Invalid weighted variantize tile pick for {tile.ID}!"); } + /// + /// Returns a tile with a weighted random variant. + /// + public Tile GetVariantTile(ContentTileDefinition tile, System.Random random) + { + return new Tile(tile.TileId, variant: PickVariant(tile, random)); + } + + /// + /// Returns a tile with a weighted random variant. + /// + public Tile GetVariantTile(ContentTileDefinition tile, int seed) + { + var rand = new System.Random(seed); + return new Tile(tile.TileId, variant: PickVariant(tile, rand)); + } + public bool PryTile(Vector2i indices, EntityUid gridId) { var grid = Comp(gridId); diff --git a/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs index db590135f0..b14baba981 100644 --- a/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs +++ b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs @@ -16,6 +16,7 @@ public abstract class SharedBiomeSystem : EntitySystem [Dependency] protected readonly IPrototypeManager ProtoManager = default!; [Dependency] private readonly ISerializationManager _serManager = default!; [Dependency] protected readonly ITileDefinitionManager TileDefManager = default!; + [Dependency] private readonly TileSystem _tile = default!; protected const byte ChunkSize = 8; @@ -158,13 +159,8 @@ public abstract class SharedBiomeSystem : EntitySystem // Pick a variant tile if they're available as well if (variantCount > 1) { - var variantValue = (noise.GetNoise(indices.X * 8, indices.Y * 8, variantCount) + 1f) / 2f; - variant = (byte) Pick(variantCount, variantValue); - - if (variants != null) - { - variant = variants[variant]; - } + var variantValue = (noise.GetNoise(indices.X * 8, indices.Y * 8, variantCount) + 1f) * 100; + variant = _tile.PickVariant(tileDef, (int) variantValue); } tile = new Tile(tileDef.TileId, 0, variant); diff --git a/Content.Shared/Tiles/FloorTileSystem.cs b/Content.Shared/Tiles/FloorTileSystem.cs index 21e21fa9e9..04aa100cd1 100644 --- a/Content.Shared/Tiles/FloorTileSystem.cs +++ b/Content.Shared/Tiles/FloorTileSystem.cs @@ -35,6 +35,7 @@ public sealed class FloorTileSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedStackSystem _stackSystem = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; private static readonly Vector2 CheckRange = new(1f, 1f); @@ -175,8 +176,8 @@ public sealed class FloorTileSystem : EntitySystem { _adminLogger.Add(LogType.Tile, LogImpact.Low, $"{ToPrettyString(user):actor} placed tile {_tileDefinitionManager[tileId].Name} at {ToPrettyString(gridUid)} {location}"); - // TODO: Proper predicted RNG. - var variant = (byte) (_timing.CurTick.Value % ((ContentTileDefinition) _tileDefinitionManager[tileId]).Variants); + var random = new System.Random((int) _timing.CurTick.Value); + var variant = _tile.PickVariant((ContentTileDefinition) _tileDefinitionManager[tileId], random); mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant)); _audio.PlayPredicted(placeSound, location, user); diff --git a/Resources/Prototypes/Procedural/biome_templates.yml b/Resources/Prototypes/Procedural/biome_templates.yml index 997ae33aa5..8897931644 100644 --- a/Resources/Prototypes/Procedural/biome_templates.yml +++ b/Resources/Prototypes/Procedural/biome_templates.yml @@ -70,15 +70,6 @@ # Fill layer - !type:BiomeTileLayer threshold: -1 - variants: - - 0 - tile: FloorAsteroidSand - - !type:BiomeTileLayer - threshold: 0.80 - noise: - seed: 1 - noiseType: OpenSimplex2 - frequency: 2 tile: FloorAsteroidSand # Grass @@ -307,8 +298,6 @@ # Fill basalt - !type:BiomeTileLayer threshold: -1 - variants: - - 0 tile: FloorBasalt # Snow @@ -530,15 +519,6 @@ # Fill chromite - !type:BiomeTileLayer threshold: -1 - variants: - - 0 - tile: FloorChromite - - !type:BiomeTileLayer - threshold: 0.25 - noise: - seed: 1 - noiseType: OpenSimplex2 - frequency: 2 tile: FloorChromite # Caves @@ -593,15 +573,6 @@ - !type:BiomeTileLayer threshold: -1.0 tile: FloorAsteroidSand - variants: - - 0 - - !type:BiomeTileLayer - threshold: 0.5 - noise: - seed: 1 - noiseType: OpenSimplex2 - frequency: 2 - tile: FloorAsteroidSand # Asteroid - type: biomeTemplate @@ -653,12 +624,3 @@ - !type:BiomeTileLayer threshold: -1.0 tile: FloorAsteroidSand - variants: - - 0 - - !type:BiomeTileLayer - threshold: 0.5 - noise: - seed: 1 - noiseType: OpenSimplex2 - frequency: 2 - tile: FloorAsteroidSand