From 37f432ca58db3d220b6b0fd46fd7a16f61e97f82 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 12 Feb 2023 13:15:09 +1100 Subject: [PATCH] Procgen biomes (#13487) * Planetmap tiles Biomes etc etc * a * oop * Chunk-based rendering * funny * Less allocations * Fix overdraw * Content tile edge support Also updated grass to use it as a POC. * Kindly revert * Update for variant edges * fixes * Use fastnoise * Remove redundant group * a * refactor a fair bit * Prototype data instead * tweaks * a * fix maths * working * a * Slightly better empty support * a * flowers * sounds * lewd * Networking * more fixes * better * colours * Some chunk loading * Proper loading and unloading * Better loading * Fix parallax and movement sounds * Anchoring support + decal setup * Most of the way to load and unload * Decal loading kinda werkin * large trees * started diffing * a * Variant support and deserts * a * snow * agony, even * working again * todo * a * laba tiles * aeiou * a # Conflicts: # Resources/Prototypes/Entities/Tiles/planet.yml # Resources/Prototypes/Tiles/planet.yml # Resources/Textures/Tiles/Planet/Lava/lava.rsi/meta.json * laba * Add lava * Initial ignition * triggers * a * a * y * Add basalt tiles Did some unconventional things for the animation + rocks. * fixies * mergies * promotion * lava biome * Lava planet start * cleanup and more lava * laba * maccas * biome stuf * weh * bongflicts * aeaeae * More fixes * a * these too --- .../IconSmoothing/IconSmoothComponent.cs | 2 + Content.Client/Parallax/BiomeSystem.cs | 8 + Content.Client/Parallax/ParallaxOverlay.cs | 12 +- Content.MapRenderer/Painters/TilePainter.cs | 1 - Content.Server/Maps/PlanetCommand.cs | 58 ++- Content.Server/Parallax/BiomeSystem.cs | 301 ++++++++++++++++ Content.Shared/Maps/ContentTileDefinition.cs | 4 + .../Movement/Systems/SharedMoverController.cs | 34 +- .../Parallax/Biomes/BiomeComponent.cs | 39 ++ .../Parallax/Biomes/BiomePrototype.cs | 123 +++++++ .../Parallax/Biomes/SharedBiomeSystem.cs | 333 ++++++++++++++++++ Resources/Locale/en-US/maps/planet.ftl | 2 +- Resources/Locale/en-US/tiles/tiles.ftl | 1 + Resources/Prototypes/Decals/planet.yml | 73 ++++ .../Entities/{Tile => Tiles}/basalt.yml | 0 Resources/Prototypes/Parallaxes/default.yml | 3 + Resources/Prototypes/Parallaxes/planet.yml | 2 +- Resources/Prototypes/Tiles/floors.yml | 18 +- Resources/Prototypes/Tiles/planet.yml | 89 +++++ Resources/Prototypes/biomes.yml | 240 +++++++++++++ .../Textures/Tiles/Asteroid/asteroid_dug.png | Bin 0 -> 1683 bytes .../Textures/Tiles/Planet/Desert/desert.png | Bin 0 -> 13500 bytes .../Tiles/Planet/Desert/desert_dug.png | Bin 0 -> 3022 bytes .../Tiles/Planet/Desert/low_desert.png | Bin 0 -> 9224 bytes .../Tiles/Planet/Desert/low_desert_dug.png | Bin 0 -> 1206 bytes .../Textures/Tiles/Planet/Desert/meta.json | 53 +++ .../Tiles/Planet/Grass/attributions.yml | 7 + .../Tiles/Planet/Grass/double_edge.png | Bin 0 -> 5719 bytes .../Textures/Tiles/Planet/Grass/grass.png | Bin 0 -> 10610 bytes .../Tiles/Planet/Grass/single_edge.png | Bin 0 -> 5140 bytes .../Tiles/Planet/Grass/triple_edge.png | Bin 0 -> 6741 bytes .../Textures/Tiles/Planet/Snow/edge0.png | Bin 0 -> 483 bytes .../Textures/Tiles/Planet/Snow/edge1.png | Bin 0 -> 637 bytes .../Textures/Tiles/Planet/Snow/edge2.png | Bin 0 -> 487 bytes .../Textures/Tiles/Planet/Snow/gravsnow.png | Bin 0 -> 2095 bytes .../Tiles/Planet/Snow/gravsnow_corner.png | Bin 0 -> 3370 bytes .../Tiles/Planet/Snow/gravsnow_surround.png | Bin 0 -> 2972 bytes Resources/Textures/Tiles/Planet/Snow/ice.png | Bin 0 -> 293 bytes .../Textures/Tiles/Planet/Snow/meta.json | 101 ++++++ .../Textures/Tiles/Planet/Snow/permafrost.png | Bin 0 -> 2109 bytes .../Textures/Tiles/Planet/Snow/plating.png | Bin 0 -> 1660 bytes .../Tiles/Planet/Snow/platingdrift.png | Bin 0 -> 2433 bytes Resources/Textures/Tiles/Planet/Snow/snow.png | Bin 0 -> 9764 bytes .../Tiles/Planet/Snow/snow_corner.png | Bin 0 -> 4134 bytes .../Textures/Tiles/Planet/Snow/snow_piss.png | Bin 0 -> 2098 bytes .../Tiles/Planet/Snow/snow_surround.png | Bin 0 -> 3129 bytes .../Tiles/Planet/Snow/snowplating.png | Bin 0 -> 1231 bytes .../Textures/Tiles/Planet/Snow/snowwhite.png | Bin 0 -> 1113 bytes .../Tiles/Planet/grass.rsi/grass0.png | Bin 695 -> 0 bytes .../Tiles/Planet/grass.rsi/grass1.png | Bin 706 -> 0 bytes .../Tiles/Planet/grass.rsi/grass2.png | Bin 692 -> 0 bytes .../Tiles/Planet/grass.rsi/grass3.png | Bin 749 -> 0 bytes .../Tiles/Planet/grass.rsi/grass_corners.png | Bin 608 -> 0 bytes .../Planet/grass.rsi/grass_edge_corner.png | Bin 2620 -> 0 bytes .../Tiles/Planet/grass.rsi/grass_edges.png | Bin 1424 -> 0 bytes .../Planet/grass.rsi/grass_edges_old.png | Bin 1401 -> 0 bytes .../Textures/Tiles/Planet/grass.rsi/meta.json | 39 -- 57 files changed, 1456 insertions(+), 87 deletions(-) create mode 100644 Content.Client/Parallax/BiomeSystem.cs create mode 100644 Content.Server/Parallax/BiomeSystem.cs create mode 100644 Content.Shared/Parallax/Biomes/BiomeComponent.cs create mode 100644 Content.Shared/Parallax/Biomes/BiomePrototype.cs create mode 100644 Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs create mode 100644 Resources/Prototypes/Decals/planet.yml rename Resources/Prototypes/Entities/{Tile => Tiles}/basalt.yml (100%) create mode 100644 Resources/Prototypes/Tiles/planet.yml create mode 100644 Resources/Prototypes/biomes.yml create mode 100644 Resources/Textures/Tiles/Asteroid/asteroid_dug.png create mode 100644 Resources/Textures/Tiles/Planet/Desert/desert.png create mode 100644 Resources/Textures/Tiles/Planet/Desert/desert_dug.png create mode 100644 Resources/Textures/Tiles/Planet/Desert/low_desert.png create mode 100644 Resources/Textures/Tiles/Planet/Desert/low_desert_dug.png create mode 100644 Resources/Textures/Tiles/Planet/Desert/meta.json create mode 100644 Resources/Textures/Tiles/Planet/Grass/attributions.yml create mode 100644 Resources/Textures/Tiles/Planet/Grass/double_edge.png create mode 100644 Resources/Textures/Tiles/Planet/Grass/grass.png create mode 100644 Resources/Textures/Tiles/Planet/Grass/single_edge.png create mode 100644 Resources/Textures/Tiles/Planet/Grass/triple_edge.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/edge0.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/edge1.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/edge2.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/gravsnow.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/gravsnow_corner.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/gravsnow_surround.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/ice.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/meta.json create mode 100644 Resources/Textures/Tiles/Planet/Snow/permafrost.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/plating.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/platingdrift.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snow.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snow_corner.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snow_piss.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snow_surround.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snowplating.png create mode 100644 Resources/Textures/Tiles/Planet/Snow/snowwhite.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass0.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass1.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass2.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass3.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass_corners.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass_edge_corner.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass_edges.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/grass_edges_old.png delete mode 100644 Resources/Textures/Tiles/Planet/grass.rsi/meta.json diff --git a/Content.Client/IconSmoothing/IconSmoothComponent.cs b/Content.Client/IconSmoothing/IconSmoothComponent.cs index bc7667d222..75c3637a3a 100644 --- a/Content.Client/IconSmoothing/IconSmoothComponent.cs +++ b/Content.Client/IconSmoothing/IconSmoothComponent.cs @@ -1,4 +1,6 @@ using JetBrains.Annotations; +using Robust.Client.Graphics; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Client.IconSmoothing { diff --git a/Content.Client/Parallax/BiomeSystem.cs b/Content.Client/Parallax/BiomeSystem.cs new file mode 100644 index 0000000000..dc326e1fa7 --- /dev/null +++ b/Content.Client/Parallax/BiomeSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Parallax.Biomes; + +namespace Content.Client.Parallax; + +public sealed class BiomeSystem : SharedBiomeSystem +{ + +} diff --git a/Content.Client/Parallax/ParallaxOverlay.cs b/Content.Client/Parallax/ParallaxOverlay.cs index 5e63bfca0a..642cdec896 100644 --- a/Content.Client/Parallax/ParallaxOverlay.cs +++ b/Content.Client/Parallax/ParallaxOverlay.cs @@ -1,5 +1,6 @@ using Content.Client.Parallax.Managers; using Content.Shared.CCVar; +using Content.Shared.Parallax.Biomes; using Robust.Client.Graphics; using Robust.Shared.Configuration; using Robust.Shared.Enums; @@ -11,9 +12,11 @@ namespace Content.Client.Parallax; public sealed class ParallaxOverlay : Overlay { + [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IParallaxManager _manager = default!; private readonly ParallaxSystem _parallax; @@ -23,8 +26,15 @@ public sealed class ParallaxOverlay : Overlay { ZIndex = ParallaxSystem.ParallaxZIndex; IoCManager.InjectDependencies(this); - _parallax = IoCManager.Resolve().GetEntitySystem(); + _parallax = _entManager.System(); + } + + protected override bool BeforeDraw(in OverlayDrawArgs args) + { + if (args.MapId == MapId.Nullspace || _entManager.HasComponent(_mapManager.GetMapEntityId(args.MapId))) + return false; + return true; } protected override void Draw(in OverlayDrawArgs args) diff --git a/Content.MapRenderer/Painters/TilePainter.cs b/Content.MapRenderer/Painters/TilePainter.cs index 805792b2a3..a19e56def1 100644 --- a/Content.MapRenderer/Painters/TilePainter.cs +++ b/Content.MapRenderer/Painters/TilePainter.cs @@ -15,7 +15,6 @@ namespace Content.MapRenderer.Painters { public sealed class TilePainter { - private const string TilesPath = "/Textures/Tiles/"; public const int TileImageSize = EyeManager.PixelsPerMeter; private readonly ITileDefinitionManager _sTileDefinitionManager; diff --git a/Content.Server/Maps/PlanetCommand.cs b/Content.Server/Maps/PlanetCommand.cs index e248bd55a8..558469c4a2 100644 --- a/Content.Server/Maps/PlanetCommand.cs +++ b/Content.Server/Maps/PlanetCommand.cs @@ -6,11 +6,13 @@ using Content.Shared.Administration; using Content.Shared.Atmos; using Content.Shared.Gravity; using Content.Shared.Movement.Components; -using Content.Shared.Parallax; +using Content.Shared.Parallax.Biomes; using Robust.Shared.Audio; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; namespace Content.Server.Maps; @@ -22,13 +24,15 @@ public sealed class PlanetCommand : IConsoleCommand { [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly IRobustRandom _random = default!; public string Command => $"planet"; public string Description => Loc.GetString("cmd-planet-desc"); public string Help => Loc.GetString("cmd-planet-help", ("command", Command)); public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (args.Length != 1) + if (args.Length != 2) { shell.WriteError(Loc.GetString($"cmd-planet-args")); return; @@ -48,16 +52,35 @@ public sealed class PlanetCommand : IConsoleCommand return; } + if (!_protoManager.HasIndex(args[1])) + { + shell.WriteError(Loc.GetString("cmd-planet-map-prototype", ("prototype", args[1]))); + return; + } + var mapUid = _mapManager.GetMapEntityId(mapId); MetaDataComponent? metadata = null; - var parallax = _entManager.EnsureComponent(mapUid); - parallax.Parallax = "Grass"; - _entManager.Dirty(parallax, metadata); + var biome = _entManager.EnsureComponent(mapUid); + biome.BiomePrototype = args[1]; + biome.Seed = _random.Next(); + _entManager.Dirty(biome); + var gravity = _entManager.EnsureComponent(mapUid); gravity.Enabled = true; - _entManager.Dirty(gravity); - _entManager.EnsureComponent(mapUid); + _entManager.Dirty(gravity, metadata); + + // Day lighting + // Daylight: #D8B059 + // Midday: #E6CB8B + // Moonlight: #2b3143 + // Lava: #A34931 + + var light = _entManager.EnsureComponent(mapUid); + light.AmbientLightColor = Color.FromHex("#D8B059"); + _entManager.Dirty(light, metadata); + + // Atmos var atmos = _entManager.EnsureComponent(mapUid); atmos.Space = false; @@ -71,24 +94,27 @@ public sealed class PlanetCommand : IConsoleCommand Moles = moles, }; - var footstep = _entManager.EnsureComponent(mapUid); - footstep.Sound = new SoundCollectionSpecifier("FootstepGrass"); - _entManager.Dirty(footstep); - _entManager.EnsureComponent(mapUid); shell.WriteLine(Loc.GetString("cmd-planet-success", ("mapId", mapId))); } public CompletionResult GetCompletion(IConsoleShell shell, string[] args) { - if (args.Length != 1) + if (args.Length == 1) { - return CompletionResult.Empty; + var options = _entManager.EntityQuery(true) + .Select(o => new CompletionOption(o.WorldMap.ToString(), "MapId")); + + return CompletionResult.FromOptions(options); } - var options = _entManager.EntityQuery(true) - .Select(o => new CompletionOption(o.WorldMap.ToString(), "MapId")); + if (args.Length == 2) + { + var options = _protoManager.EnumeratePrototypes() + .Select(o => new CompletionOption(o.ID, "Biome")); + return CompletionResult.FromOptions(options); + } - return CompletionResult.FromOptions(options); + return CompletionResult.Empty; } } diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs new file mode 100644 index 0000000000..9f8c9c1c4c --- /dev/null +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -0,0 +1,301 @@ +using Content.Server.Decals; +using Content.Shared.Decals; +using Content.Shared.Parallax.Biomes; +using Robust.Server.Player; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Noise; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Serialization.Manager; + +namespace Content.Server.Parallax; + +public sealed class BiomeSystem : SharedBiomeSystem +{ + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly DecalSystem _decals = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + + private readonly HashSet _handledEntities = new(); + private const float LoadRange = ChunkSize * 2f; + private readonly Box2 _loadArea = new(-LoadRange, -LoadRange, LoadRange, LoadRange); + + private readonly Dictionary> _activeChunks = new(); + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnBiomeMapInit); + } + + private void OnBiomeMapInit(EntityUid uid, BiomeComponent component, MapInitEvent args) + { + component.Seed = _random.Next(); + Dirty(component); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var biomeQuery = GetEntityQuery(); + var xformQuery = GetEntityQuery(); + var biomes = AllEntityQuery(); + + while (biomes.MoveNext(out var biome)) + { + _activeChunks.Add(biome, new HashSet()); + } + + // Get chunks in range + foreach (var client in Filter.GetAllPlayers(_playerManager)) + { + var pSession = (IPlayerSession) client; + + if (xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) && + _handledEntities.Add(pSession.AttachedEntity.Value) && + biomeQuery.TryGetComponent(xform.MapUid, out var biome)) + { + AddChunksInRange(biome, _transform.GetWorldPosition(xform, xformQuery)); + } + + foreach (var viewer in pSession.ViewSubscriptions) + { + if (!_handledEntities.Add(viewer) || + !xformQuery.TryGetComponent(viewer, out xform) || + !biomeQuery.TryGetComponent(xform.MapUid, out biome)) + { + continue; + } + + AddChunksInRange(biome, _transform.GetWorldPosition(xform, xformQuery)); + } + } + + var loadBiomes = AllEntityQuery(); + + while (loadBiomes.MoveNext(out var biome, out var grid)) + { + var noise = new FastNoise(biome.Seed); + var gridUid = grid.Owner; + + // Load new chunks + LoadChunks(biome, gridUid, grid, noise); + // Unload old chunks + UnloadChunks(biome, gridUid, grid, noise); + } + + _handledEntities.Clear(); + _activeChunks.Clear(); + } + + private void AddChunksInRange(BiomeComponent biome, Vector2 worldPos) + { + var enumerator = new ChunkIndicesEnumerator(_loadArea.Translated(worldPos), ChunkSize); + + while (enumerator.MoveNext(out var chunkOrigin)) + { + _activeChunks[biome].Add(chunkOrigin.Value); + } + } + + private void LoadChunks(BiomeComponent component, EntityUid gridUid, MapGridComponent grid, FastNoise noise) + { + var active = _activeChunks[component]; + var prototype = ProtoManager.Index(component.BiomePrototype); + List<(Vector2i, Tile)>? tiles = null; + + foreach (var chunk in active) + { + if (!component.LoadedChunks.Add(chunk)) + continue; + + tiles ??= new List<(Vector2i, Tile)>(ChunkSize * ChunkSize); + // Load NOW! + LoadChunk(component, gridUid, grid, chunk * ChunkSize, noise, prototype, tiles); + } + } + + private void LoadChunk(BiomeComponent component, EntityUid gridUid, MapGridComponent grid, Vector2i chunk, FastNoise noise, BiomePrototype prototype, List<(Vector2i, Tile)> tiles) + { + component.ModifiedTiles.TryGetValue(chunk, out var modified); + modified ??= new HashSet(); + + // Set tiles first + for (var x = 0; x < ChunkSize; x++) + { + for (var y = 0; y < ChunkSize; y++) + { + var indices = new Vector2i(x + chunk.X, y + chunk.Y); + + if (modified.Contains(indices)) + continue; + + // If there's existing data then don't overwrite it. + if (grid.TryGetTileRef(indices, out var tileRef) && !tileRef.Tile.IsEmpty) + continue; + + // Pass in null so we don't try to get the tileref. + if (!TryGetBiomeTile(indices, prototype, noise, null, out var biomeTile) || biomeTile.Value == tileRef.Tile) + continue; + + tiles.Add((indices, biomeTile.Value)); + } + } + + grid.SetTiles(tiles); + tiles.Clear(); + + // Now do entities + var loadedEntities = new List(); + component.LoadedEntities.Add(chunk, loadedEntities); + + for (var x = 0; x < ChunkSize; x++) + { + for (var y = 0; y < ChunkSize; y++) + { + var indices = new Vector2i(x + chunk.X, y + chunk.Y); + + if (modified.Contains(indices)) + continue; + + // Don't mess with anything that's potentially anchored. + var anchored = grid.GetAnchoredEntitiesEnumerator(indices); + + if (anchored.MoveNext(out _) || !TryGetEntity(indices, prototype, noise, grid, out var entPrototype)) + continue; + + // TODO: Fix non-anchored ents spawning. + // Just track loaded chunks for now. + var ent = Spawn(entPrototype, grid.GridTileToLocal(indices)); + loadedEntities.Add(ent); + } + } + + // Decals + var loadedDecals = new Dictionary(); + component.LoadedDecals.Add(chunk, loadedDecals); + + for (var x = 0; x < ChunkSize; x++) + { + for (var y = 0; y < ChunkSize; y++) + { + var indices = new Vector2i(x + chunk.X, y + chunk.Y); + + if (modified.Contains(indices)) + continue; + + // Don't mess with anything that's potentially anchored. + var anchored = grid.GetAnchoredEntitiesEnumerator(indices); + + if (anchored.MoveNext(out _) || !TryGetDecals(indices, prototype, noise, grid, out var decals)) + continue; + + foreach (var decal in decals) + { + if (!_decals.TryAddDecal(decal.ID, new EntityCoordinates(gridUid, decal.Position), out var dec)) + continue; + + loadedDecals.Add(dec, indices); + } + } + } + + if (modified.Count == 0) + { + component.ModifiedTiles.Remove(chunk); + } + else + { + component.ModifiedTiles[chunk] = modified; + } + } + + private void UnloadChunks(BiomeComponent component, EntityUid gridUid, MapGridComponent grid, FastNoise noise) + { + var active = _activeChunks[component]; + List<(Vector2i, Tile)>? tiles = null; + + foreach (var chunk in component.LoadedChunks) + { + if (active.Contains(chunk) || !component.LoadedChunks.Remove(chunk)) + continue; + + // Unload NOW! + tiles ??= new List<(Vector2i, Tile)>(ChunkSize * ChunkSize); + UnloadChunk(component, gridUid, grid, chunk * ChunkSize, noise, tiles); + } + } + + private void UnloadChunk(BiomeComponent component, EntityUid gridUid, MapGridComponent grid, Vector2i chunk, FastNoise noise, List<(Vector2i, Tile)> tiles) + { + // Reverse order to loading + var prototype = ProtoManager.Index(component.BiomePrototype); + component.ModifiedTiles.TryGetValue(chunk, out var modified); + modified ??= new HashSet(); + + // Delete decals + foreach (var (dec, indices) in component.LoadedDecals[chunk]) + { + // If we couldn't remove it then flag the tile to never be touched. + if (!_decals.RemoveDecal(gridUid, dec)) + { + modified.Add(indices); + } + } + + component.LoadedDecals.Remove(chunk); + + // Delete entities + // This is a TODO + // Ideally any entities that aren't modified just get deleted and re-generated later + // This is because if we want to save the map (e.g. persistent server) it makes the file much smaller + // and also if the map is enormous will make stuff like physics broadphase much faster + // For now we'll just leave them because no entity diffs. + + component.LoadedEntities.Remove(chunk); + + // Unset tiles (if the data is custom) + + for (var x = 0; x < ChunkSize; x++) + { + for (var y = 0; y < ChunkSize; y++) + { + var indices = new Vector2i(x + chunk.X, y + chunk.Y); + + if (modified.Contains(indices)) + continue; + + // Don't mess with anything that's potentially anchored. + var anchored = grid.GetAnchoredEntitiesEnumerator(indices); + + if (anchored.MoveNext(out _)) + { + modified.Add(indices); + continue; + } + + // If it's default data unload the tile. + if (!TryGetBiomeTile(indices, prototype, noise, null, out var biomeTile) || + grid.TryGetTileRef(indices, out var tileRef) && tileRef.Tile != biomeTile.Value) + { + modified.Add(indices); + continue; + } + + tiles.Add((indices, Tile.Empty)); + } + } + + grid.SetTiles(tiles); + tiles.Clear(); + component.LoadedChunks.Remove(chunk); + + if (modified.Count == 0) + { + component.ModifiedTiles.Remove(chunk); + } + } +} diff --git a/Content.Shared/Maps/ContentTileDefinition.cs b/Content.Shared/Maps/ContentTileDefinition.cs index 53909006cc..8676d63e6e 100644 --- a/Content.Shared/Maps/ContentTileDefinition.cs +++ b/Content.Shared/Maps/ContentTileDefinition.cs @@ -31,6 +31,10 @@ namespace Content.Shared.Maps public string Name { get; private set; } = ""; [DataField("sprite")] public ResourcePath? Sprite { get; } + [DataField("cornerSprites")] public List CornerSprites { get; } = new(); + + [DataField("cardinalSprites")] public List CardinalSprites { get; } = new(); + [DataField("isSubfloor")] public bool IsSubFloor { get; private set; } [DataField("baseTurfs")] public List BaseTurfs { get; } = new(); diff --git a/Content.Shared/Movement/Systems/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs index 1239e45b33..55829dd8d4 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -17,6 +17,10 @@ using Robust.Shared.Timing; using Robust.Shared.Utility; using System.Diagnostics.CodeAnalysis; using Content.Shared.Mobs.Systems; +using Content.Shared.Mech.Components; +using Content.Shared.Parallax.Biomes; +using Robust.Shared.Map.Components; +using Robust.Shared.Noise; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -32,6 +36,7 @@ namespace Content.Shared.Movement.Systems [Dependency] protected readonly IGameTiming Timing = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; + [Dependency] private readonly SharedBiomeSystem _biome = default!; [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; @@ -449,7 +454,7 @@ namespace Content.Shared.Movement.Systems } if (_inventory.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) && - EntityManager.TryGetComponent(shoes, out var modifier)) + TryComp(shoes, out var modifier)) { sound = modifier.Sound; return true; @@ -461,10 +466,10 @@ namespace Content.Shared.Movement.Systems private bool TryGetFootstepSound(TransformComponent xform, bool haveShoes, [NotNullWhen(true)] out SoundSpecifier? sound) { sound = null; + MapGridComponent? grid; - // Fallback to the map - if (xform.MapUid == xform.GridUid || - xform.GridUid == null) + // Fallback to the map? + if (xform.GridUid == null) { if (TryComp(xform.MapUid, out var modifier)) { @@ -475,25 +480,30 @@ namespace Content.Shared.Movement.Systems return false; } - var grid = _mapManager.GetGrid(xform.GridUid.Value); - var tile = grid.GetTileRef(xform.Coordinates); - - if (tile.IsSpace(_tileDefinitionManager)) - return false; + grid = _mapManager.GetGrid(xform.GridUid.Value); + var position = grid.LocalToTile(xform.Coordinates); // If the coordinates have a FootstepModifier component // i.e. component that emit sound on footsteps emit that sound - foreach (var maybeFootstep in grid.GetAnchoredEntities(tile.GridIndices)) + var anchored = grid.GetAnchoredEntitiesEnumerator(position); + + while (anchored.MoveNext(out var maybeFootstep)) { - if (EntityManager.TryGetComponent(maybeFootstep, out FootstepModifierComponent? footstep)) + if (TryComp(maybeFootstep, out var footstep)) { sound = footstep.Sound; return true; } } + if (!grid.TryGetTileRef(position, out var tileRef)) + { + sound = null; + return false; + } + // Walking on a tile. - var def = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId]; + var def = (ContentTileDefinition) _tileDefinitionManager[tileRef.Tile.TypeId]; sound = haveShoes ? def.FootstepSounds : def.BarestepSounds; return sound != null; } diff --git a/Content.Shared/Parallax/Biomes/BiomeComponent.cs b/Content.Shared/Parallax/Biomes/BiomeComponent.cs new file mode 100644 index 0000000000..1331cfa6a7 --- /dev/null +++ b/Content.Shared/Parallax/Biomes/BiomeComponent.cs @@ -0,0 +1,39 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Parallax.Biomes; + +[RegisterComponent, NetworkedComponent] +public sealed class BiomeComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("seed")] + public int Seed; + + [ViewVariables(VVAccess.ReadWrite), + DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string BiomePrototype = "Grasslands"; + + // TODO: Need to flag tiles as not requiring custom data anymore, e.g. if we spawn an ent and don't unspawn it. + + /// + /// If we've already generated a tile and couldn't deload it then we won't ever reload it in future. + /// Stored by [Chunkorigin, Tiles] + /// + [DataField("modifiedTiles")] + public Dictionary> ModifiedTiles = new(); + + /// + /// Decals that have been loaded as a part of this biome. + /// + [DataField("decals")] + public Dictionary> LoadedDecals = new(); + + [DataField("entities")] + public Dictionary> LoadedEntities = new(); + + /// + /// Currently active chunks + /// + [ViewVariables] + public readonly HashSet LoadedChunks = new(); +} diff --git a/Content.Shared/Parallax/Biomes/BiomePrototype.cs b/Content.Shared/Parallax/Biomes/BiomePrototype.cs new file mode 100644 index 0000000000..731efbc1f1 --- /dev/null +++ b/Content.Shared/Parallax/Biomes/BiomePrototype.cs @@ -0,0 +1,123 @@ +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; +using Robust.Shared.Utility; + +namespace Content.Shared.Parallax.Biomes; + +[Prototype("biome")] +public sealed class BiomePrototype : IPrototype +{ + [IdDataField] public string ID { get; } = default!; + + [DataField("layers")] + public List Layers = new(); +} + +[ImplicitDataDefinitionForInheritors] +public interface IBiomeLayer +{ + /// + /// Threshold for this layer to be present. If set to 0 forces it for every tile. + /// + float Threshold { get; } + + /// + /// Offset the seed by the specified amount for this layer. + /// Useful if you have 2 similar layers but don't want them to match exactly. + /// + int SeedOffset { get; } + + /// + /// Frequency for noise: lower values create larger blobs. + /// + float Frequency { get; } +} + +public sealed class BiomeTileLayer : IBiomeLayer +{ + /// + [DataField("threshold")] + public float Threshold { get; } = 0.5f; + + /// + [DataField("seedOffset")] + public int SeedOffset { get; } = 0; + + /// + [DataField("frequency")] + public float Frequency { get; } = 0.1f; + + /// + /// Which tile variants to use for this layer. Uses all of the tile's variants if none specified + /// + [DataField("variants")] + public List? Variants = null; + + [DataField("tile", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Tile = string.Empty; +} + +/// +/// Handles actual objects such as decals and entities. +/// +public interface IBiomeWorldLayer : IBiomeLayer +{ + /// + /// What tiles we're allowed to spawn on, real or biome. + /// + List AllowedTiles { get; } +} + +public sealed class BiomeDecalLayer : IBiomeWorldLayer +{ + /// + [DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List AllowedTiles { get; } = new(); + + /// + /// Divide each tile up by this amount. + /// + [DataField("divisions")] + public float Divisions = 1f; + + /// + [DataField("seedOffset")] + public int SeedOffset { get; } = 0; + + /// + [DataField("frequency")] + public float Frequency { get; } = 0.25f; + + /// + [DataField("threshold")] + public float Threshold { get; } = 0.8f; + + [DataField("decals", required: true, customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List Decals = new(); +} + +public sealed class BiomeEntityLayer : IBiomeWorldLayer +{ + /// + [DataField("allowedTiles", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List AllowedTiles { get; } = new(); + + /// + [DataField("threshold")] + public float Threshold { get; } = 0.5f; + + /// + [DataField("seedOffset")] + public int SeedOffset { get; } = 0; + + /// + [DataField("frequency")] + public float Frequency { get; } = 0.1f; + + [DataField("entities", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List Entities = new(); +} diff --git a/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs new file mode 100644 index 0000000000..eefc772c17 --- /dev/null +++ b/Content.Shared/Parallax/Biomes/SharedBiomeSystem.cs @@ -0,0 +1,333 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Content.Shared.Decals; +using Content.Shared.Maps; +using Robust.Shared.Console; +using Robust.Shared.GameStates; +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; + +public abstract class SharedBiomeSystem : EntitySystem +{ + [Dependency] protected readonly IPrototypeManager ProtoManager = default!; + [Dependency] protected readonly ITileDefinitionManager TileDefManager = default!; + + protected const byte ChunkSize = 4; + + // TODO: After I wrote all of this FastNoiseLite got ported so this needs updating for that don't @ me + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnBiomeGetState); + SubscribeLocalEvent(OnBiomeHandleState); + } + + private void OnBiomeHandleState(EntityUid uid, BiomeComponent component, ref ComponentHandleState args) + { + if (args.Current is not BiomeComponentState state) + return; + + component.Seed = state.Seed; + } + + private void OnBiomeGetState(EntityUid uid, BiomeComponent component, ref ComponentGetState args) + { + args.State = new BiomeComponentState(component.Seed, component.BiomePrototype); + } + + protected T Pick(List collection, float value) + { + DebugTools.Assert(value is >= 0f and <= 1f); + + if (collection.Count == 1) + return collection[0]; + + value *= collection.Count; + + foreach (var item in collection) + { + value -= 1f; + + if (value <= 0f) + { + return item; + } + } + + throw new ArgumentOutOfRangeException(); + } + + protected int Pick(int count, float value) + { + DebugTools.Assert(value is >= 0f and <= 1f); + + if (count == 1) + return 0; + + value *= count; + + for (var i = 0; i < count; i++) + { + value -= 1f; + + if (value <= 0f) + { + return i; + } + } + + throw new ArgumentOutOfRangeException(); + } + + public bool TryGetBiomeTile(EntityUid uid, MapGridComponent grid, Vector2i indices, [NotNullWhen(true)] out Tile? tile) + { + if (grid.TryGetTileRef(indices, out var tileRef)) + { + tile = tileRef.Tile; + return true; + } + + if (!TryComp(uid, out var biome)) + { + tile = null; + return false; + } + + return TryGetBiomeTile(indices, ProtoManager.Index(biome.BiomePrototype), + new FastNoise(biome.Seed), grid, out tile); + } + + /// + /// Tries to get the tile, real or otherwise, for the specified indices. + /// + public bool TryGetBiomeTile(Vector2i indices, BiomePrototype prototype, FastNoise seed, MapGridComponent? grid, [NotNullWhen(true)] out Tile? tile) + { + if (grid?.TryGetTileRef(indices, out var tileRef) == true && !tileRef.Tile.IsEmpty) + { + tile = tileRef.Tile; + return true; + } + + var oldFrequency = seed.GetFrequency(); + + for (var i = prototype.Layers.Count - 1; i >= 0; i--) + { + var layer = prototype.Layers[i]; + + if (layer is not BiomeTileLayer tileLayer) + continue; + + seed.SetFrequency(tileLayer.Frequency); + + if (TryGetTile(indices, seed, tileLayer.Threshold, ProtoManager.Index(tileLayer.Tile), tileLayer.Variants, out tile)) + { + seed.SetFrequency(oldFrequency); + return true; + } + } + + seed.SetFrequency(oldFrequency); + tile = null; + return false; + } + + /// + /// Tries to get the relevant entity for this tile. + /// + protected bool TryGetEntity(Vector2i indices, BiomePrototype prototype, FastNoise noise, MapGridComponent grid, + [NotNullWhen(true)] out string? entity) + { + if (!TryGetBiomeTile(indices, prototype, noise, grid, out var tileRef)) + { + entity = null; + return false; + } + + var tileId = TileDefManager[tileRef.Value.TypeId].ID; + var oldFrequency = noise.GetFrequency(); + var seed = noise.GetSeed(); + + for (var i = prototype.Layers.Count - 1; i >= 0; i--) + { + var layer = prototype.Layers[i]; + var offset = 0; + + // Decals might block entity so need to check if there's one in front of us. + switch (layer) + { + case IBiomeWorldLayer worldLayer: + if (!worldLayer.AllowedTiles.Contains(tileId)) + continue; + + offset = worldLayer.SeedOffset; + noise.SetSeed(seed + offset); + noise.SetFrequency(worldLayer.Frequency); + break; + default: + continue; + } + + var value = (noise.GetCellular(indices.X, indices.Y) + 1f) / 2f; + + if (value < layer.Threshold) + { + DebugTools.Assert(value is <= 1f and >= 0f); + continue; + } + + if (layer is not BiomeEntityLayer biomeLayer) + { + entity = null; + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + return false; + } + + entity = Pick(biomeLayer.Entities, (noise.GetSimplex(indices.X, indices.Y) + 1f) / 2f); + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + return true; + } + + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + entity = null; + return false; + } + + /// + /// Tries to get the relevant decals for this tile. + /// + public bool TryGetDecals(Vector2i indices, BiomePrototype prototype, FastNoise noise, MapGridComponent grid, + [NotNullWhen(true)] out List<(string ID, Vector2 Position)>? decals) + { + if (!TryGetBiomeTile(indices, prototype, noise, grid, out var tileRef)) + { + decals = null; + return false; + } + + var tileId = TileDefManager[tileRef.Value.TypeId].ID; + var oldFrequency = noise.GetFrequency(); + var seed = noise.GetSeed(); + + for (var i = prototype.Layers.Count - 1; i >= 0; i--) + { + var layer = prototype.Layers[i]; + var offset = 0; + + // Entities might block decal so need to check if there's one in front of us. + switch (layer) + { + case IBiomeWorldLayer worldLayer: + if (!worldLayer.AllowedTiles.Contains(tileId)) + continue; + + offset = worldLayer.SeedOffset; + noise.SetSeed(seed + offset); + noise.SetFrequency(worldLayer.Frequency); + break; + default: + continue; + } + + // Check if the other layer should even render, if not then keep going. + if (layer is not BiomeDecalLayer decalLayer) + { + if ((noise.GetCellular(indices.X, indices.Y) + 1f) / 2f < layer.Threshold) + continue; + + decals = null; + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + return false; + } + + decals = new List<(string ID, Vector2 Position)>(); + + for (var x = 0; x < decalLayer.Divisions; x++) + { + 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.GetCellular(index.X, index.Y) + 1f) / 2f; + + if (decalValue < decalLayer.Threshold) + continue; + + DebugTools.Assert(decalValue is <= 1f and >= 0f); + decals.Add((Pick(decalLayer.Decals, (noise.GetSimplex(index.X, index.Y) + 1f) / 2f), index)); + } + } + + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + + // Check other layers + if (decals.Count == 0) + continue; + + return true; + } + + noise.SetFrequency(oldFrequency); + noise.SetSeed(seed); + decals = null; + return false; + } + + /// + /// Gets the underlying biome tile, ignoring any existing tile that may be there. + /// + public bool TryGetTile(Vector2i indices, FastNoise seed, float threshold, ContentTileDefinition tileDef, List? variants, [NotNullWhen(true)] out Tile? tile) + { + if (threshold > 0f) + { + var found = (seed.GetSimplexFractal(indices.X, indices.Y) + 1f) / 2f; + + if (found < threshold) + { + tile = null; + return false; + } + } + + byte variant = 0; + var variantCount = variants?.Count ?? tileDef.Variants; + + // Pick a variant tile if they're available as well + if (variantCount > 1) + { + var variantValue = (seed.GetSimplex(indices.X * 2f, indices.Y * 2f) + 1f) / 2f; + variant = (byte) Pick(variantCount, variantValue); + + if (variants != null) + { + variant = variants[variant]; + } + } + + tile = new Tile(tileDef.TileId, 0, variant); + return true; + } + + [Serializable, NetSerializable] + private sealed class BiomeComponentState : ComponentState + { + public int Seed; + public string Prototype; + + public BiomeComponentState(int seed, string prototype) + { + Seed = seed; + Prototype = prototype; + } + } +} diff --git a/Resources/Locale/en-US/maps/planet.ftl b/Resources/Locale/en-US/maps/planet.ftl index 0d51694500..75da034fd7 100644 --- a/Resources/Locale/en-US/maps/planet.ftl +++ b/Resources/Locale/en-US/maps/planet.ftl @@ -1,5 +1,5 @@ cmd-planet-desc = Converts the supplied map into a planet with sensible defaults. cmd-planet-help = {$command} . -cmd-planet-args = Require 1 arg only. +cmd-planet-args = Requires 2 args only. cmd-planet-map = Unable to parse {$map} as an existing map. cmd-planet-success = Set map {$mapId} to Planet. NOTE! You will need to load the map (either onto a new map or by restarting the game) for atmospherics to work. diff --git a/Resources/Locale/en-US/tiles/tiles.ftl b/Resources/Locale/en-US/tiles/tiles.ftl index 974db2ab6e..cc64145d3f 100644 --- a/Resources/Locale/en-US/tiles/tiles.ftl +++ b/Resources/Locale/en-US/tiles/tiles.ftl @@ -69,6 +69,7 @@ tiles-green-circuit-floor = green circuit floor tiles-blue-circuit-floor = blue circuit floor tiles-snow = snow tiles-grass-floor = grass floor +tiles-planet-grass-floor = grass floor tiles-jungle-grass-floor = jungle grass floor tiles-dark-grass-floor = dark grass floor tiles-light-grass-floor = light grass floor diff --git a/Resources/Prototypes/Decals/planet.yml b/Resources/Prototypes/Decals/planet.yml new file mode 100644 index 0000000000..91b3c3ccc6 --- /dev/null +++ b/Resources/Prototypes/Decals/planet.yml @@ -0,0 +1,73 @@ +# Flowers +- type: decal + id: FlowersBROne + sprite: + sprite: /Textures/Decals/Flora/flora_flowers.rsi + state: flowersbr1 + +- type: decal + id: FlowersBRTwo + sprite: + sprite: /Textures/Decals/Flora/flora_flowers.rsi + state: flowersbr2 + +- type: decal + id: FlowersBRThree + sprite: + sprite: /Textures/Decals/Flora/flora_flowers.rsi + state: flowersbr3 + +# Grass +- type: decal + id: BushAOne + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: busha1 + +- type: decal + id: BushATwo + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: busha2 + +- type: decal + id: BushAThree + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: busha3 + +- type: decal + id: BushCOne + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushc1 + +- type: decal + id: BushCTwo + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushc2 + +- type: decal + id: BushCThree + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushc3 + +- type: decal + id: BushDOne + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushd1 + +- type: decal + id: BushDTwo + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushd2 + +- type: decal + id: BushDThree + sprite: + sprite: /Textures/Decals/Flora/flora_bushes.rsi + state: bushd3 diff --git a/Resources/Prototypes/Entities/Tile/basalt.yml b/Resources/Prototypes/Entities/Tiles/basalt.yml similarity index 100% rename from Resources/Prototypes/Entities/Tile/basalt.yml rename to Resources/Prototypes/Entities/Tiles/basalt.yml diff --git a/Resources/Prototypes/Parallaxes/default.yml b/Resources/Prototypes/Parallaxes/default.yml index 26a0fe0b39..4a84b4618b 100644 --- a/Resources/Prototypes/Parallaxes/default.yml +++ b/Resources/Prototypes/Parallaxes/default.yml @@ -1,3 +1,6 @@ +- type: parallax + id: Blank + - type: parallax id: Default layers: diff --git a/Resources/Prototypes/Parallaxes/planet.yml b/Resources/Prototypes/Parallaxes/planet.yml index d18d32b063..3371dfd746 100644 --- a/Resources/Prototypes/Parallaxes/planet.yml +++ b/Resources/Prototypes/Parallaxes/planet.yml @@ -18,7 +18,7 @@ layers: - texture: !type:ImageParallaxTextureSource - path: "/Textures/Tiles/Planet/grass.rsi/grass0.png" + path: "/Textures/Tiles/Planet/Grass/grass.png" slowness: 0 scale: "1, 1" shader: "" diff --git a/Resources/Prototypes/Tiles/floors.yml b/Resources/Prototypes/Tiles/floors.yml index a23e9493a4..3aa770d10e 100644 --- a/Resources/Prototypes/Tiles/floors.yml +++ b/Resources/Prototypes/Tiles/floors.yml @@ -1103,26 +1103,12 @@ friction: 0.30 thermalConductivity: 0.04 heatCapacity: 10000 - -- type: tile - id: FloorSnow - name: tiles-snow - sprite: /Textures/Tiles/snow.png - baseTurfs: - - FloorDirt - isSubfloor: true - canCrowbar: false - footstepSounds: - collection: FootstepSnow - friction: 0.20 - itemDrop: FloorTileItemSnow - thermalConductivity: 0.04 - heatCapacity: 10000 weather: true + - type: tile id: FloorGrass - name: tiles-grass-floor + name: tiles-planet-grass-floor sprite: /Textures/Tiles/grass.png baseTurfs: - FloorDirt diff --git a/Resources/Prototypes/Tiles/planet.yml b/Resources/Prototypes/Tiles/planet.yml new file mode 100644 index 0000000000..c67c7994d4 --- /dev/null +++ b/Resources/Prototypes/Tiles/planet.yml @@ -0,0 +1,89 @@ +# Desert +- type: tile + id: FloorDesert + name: tiles-desert-floor + sprite: /Textures/Tiles/Planet/Desert/desert.png + variants: 6 + placementVariants: [0, 1, 2, 3, 4, 5] + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepAsteroid + friction: 0.30 + thermalConductivity: 0.04 + heatCapacity: 10000 + weather: true + +- type: tile + id: FloorLowDesert + name: tiles-low-desert-floor + sprite: /Textures/Tiles/Planet/Desert/low_desert.png + variants: 6 + placementVariants: [0, 1, 2, 3, 4, 5] + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepAsteroid + friction: 0.30 + thermalConductivity: 0.04 + heatCapacity: 10000 + weather: true + +# Grass +- type: tile + id: FloorPlanetGrass + name: tiles-grass-planet-floor + sprite: /Textures/Tiles/Planet/Grass/grass.png + variants: 4 + placementVariants: [0, 1, 2, 3] + cornerSprites: + - /Textures/Tiles/Planet/Grass/single_edge.png + cardinalSprites: + - /Textures/Tiles/Planet/Grass/double_edge.png + baseTurfs: + - FloorDirt + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepGrass + friction: 0.30 + itemDrop: FloorTileItemGrass + thermalConductivity: 0.04 + heatCapacity: 10000 + weather: true + +# Lava +- type: tile + id: FloorBasalt + name: tiles-basalt-floor + sprite: /Textures/Tiles/Planet/basalt.png + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepAsteroid + friction: 0.30 + thermalConductivity: 0.04 + heatCapacity: 10000 + weather: true + +# Snow +- type: tile + id: FloorSnow + name: tiles-snow-floor + sprite: /Textures/Tiles/Planet/Snow/snow.png + variants: 13 + placementVariants: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + #cornerSprites: + # - /Textures/Tiles/Planet/Snow/single_edge.png + #cardinalSprites: + # - /Textures/Tiles/Planet/Snow/double_edge.png + isSubfloor: true + canCrowbar: false + footstepSounds: + collection: FootstepSnow + friction: 0.20 + thermalConductivity: 0.04 + heatCapacity: 10000 + weather: true + +# Wasteland diff --git a/Resources/Prototypes/biomes.yml b/Resources/Prototypes/biomes.yml new file mode 100644 index 0000000000..59b1c3acae --- /dev/null +++ b/Resources/Prototypes/biomes.yml @@ -0,0 +1,240 @@ +# Desert +# TODO: Water in grasslands +# TODO: Water in desert / grass? +- type: biome + id: LowDesert + layers: + - !type:BiomeEntityLayer + threshold: 0.99 + frequency: 1 + seedOffset: 1 + allowedTiles: + - FloorLowDesert + entities: + - FloraRockSolid01 + - FloraRockSolid02 + - FloraRockSolid03 + - !type:BiomeEntityLayer + threshold: 0.9 + frequency: 0.2 + allowedTiles: + - FloorLowDesert + entities: + - AsteroidRock + - !type:BiomeTileLayer + threshold: 0 + variants: + - 0 + tile: FloorLowDesert + - !type:BiomeTileLayer + threshold: 0.6 + tile: FloorLowDesert + frequency: 0.1 + +# Grass +- type: biome + id: Grasslands + layers: + - !type:BiomeDecalLayer + allowedTiles: + - FloorPlanetGrass + seedOffset: 3 + threshold: 0.98 + divisions: 1 + frequency: 1 + decals: + - FlowersBROne + - FlowersBRTwo + - FlowersBRThree + - !type:BiomeDecalLayer + allowedTiles: + - FloorPlanetGrass + seedOffset: 2 + threshold: 0.95 + divisions: 2 + frequency: 1 + decals: + - BushDOne + - BushDTwo + - BushDThree + - !type:BiomeDecalLayer + allowedTiles: + - FloorPlanetGrass + seedOffset: 1 + threshold: 0.8 + divisions: 1 + frequency: 0.05 + decals: + - BushCOne + - BushCTwo + - BushCThree + - !type:BiomeDecalLayer + allowedTiles: + - FloorPlanetGrass + divisions: 1 + decals: + - BushAOne + - BushATwo + - BushAThree + - !type:BiomeEntityLayer + threshold: 0.9 + frequency: 1 + allowedTiles: + - FloorPlanetGrass + entities: + - FloraTree01 + - FloraTree02 + - FloraTree03 + - FloraTree04 + - FloraTree05 + - FloraTree06 + - FloraTreeLarge01 + - FloraTreeLarge02 + - FloraTreeLarge03 + - FloraTreeLarge04 + - FloraTreeLarge05 + - FloraTreeLarge06 + # Fill remainder with sand. + - !type:BiomeTileLayer + threshold: 0 + tile: FloorAsteroidSand + - !type:BiomeTileLayer + threshold: 0.5 + tile: FloorPlanetGrass + +# Lava +- type: biome + id: Lava + layers: + - !type:BiomeEntityLayer + threshold: 0.9 + frequency: 1 + seedOffset: 3 + allowedTiles: + - FloorBasalt + entities: + - BasaltOne + - BasaltTwo + - BasaltThree + - BasaltFour + - BasaltFive + - !type:BiomeDecalLayer + allowedTiles: + - FloorBasalt + seedOffset: 2 + threshold: 0.9 + divisions: 1 + frequency: 1 + decals: + - Basalt1 + - Basalt2 + - Basalt3 + - Basalt4 + - Basalt5 + - Basalt6 + - Basalt7 + - Basalt8 + - Basalt9 + - !type:BiomeEntityLayer + threshold: 0.99 + frequency: 1 + seedOffset: 1 + allowedTiles: + - FloorBasalt + entities: + - FloraRockSolid01 + - FloraRockSolid02 + - FloraRockSolid03 + - !type:BiomeEntityLayer + threshold: 0.7 + frequency: 0.2 + allowedTiles: + - FloorBasalt + entities: + - FloorLavaEntity + - !type:BiomeTileLayer + threshold: 0 + variants: + - 0 + tile: FloorBasalt + +# Snow +- type: biome + id: Snow + layers: + - !type:BiomeDecalLayer + allowedTiles: + - FloorSnow + seedOffset: 4 + threshold: 0.95 + divisions: 1 + frequency: 1 + decals: + - grasssnowa1 + - grasssnowa2 + - grasssnowa3 + - grasssnowb1 + - grasssnowb2 + - grasssnowb3 + - grasssnowc1 + - grasssnowc2 + - grasssnowc3 + # The main grass texture, this one blends in very well + - !type:BiomeDecalLayer + allowedTiles: + - FloorSnow + divisions: 1 + seedOffset: 3 + threshold: 0.8 + frequency: 0.05 + decals: + - grasssnow + - grasssnow01 + - grasssnow02 + - grasssnow03 + - grasssnow04 + - grasssnow05 + - grasssnow06 + - grasssnow07 + - grasssnow08 + - grasssnow09 + - grasssnow10 + - grasssnow11 + - grasssnow12 + - grasssnow13 + - !type:BiomeDecalLayer + allowedTiles: + - FloorSnow + seedOffset: 2 + threshold: 0.99 + divisions: 1 + frequency: 1 + decals: + - bushsnowa1 + - bushsnowa2 + - bushsnowa3 + - bushsnowb1 + - bushsnowb2 + - bushsnowb3 + - !type:BiomeEntityLayer + seedOffset: 1 + threshold: 0.95 + frequency: 1 + allowedTiles: + - FloorSnow + entities: + - FloraTreeSnow01 + - FloraTreeSnow02 + - FloraTreeSnow03 + - FloraTreeSnow04 + - FloraTreeSnow05 + - FloraTreeSnow06 + - !type:BiomeTileLayer + threshold: 0 + variants: + - 0 + tile: FloorSnow + - !type:BiomeTileLayer + threshold: 0.6 + tile: FloorSnow + frequency: 0.1 diff --git a/Resources/Textures/Tiles/Asteroid/asteroid_dug.png b/Resources/Textures/Tiles/Asteroid/asteroid_dug.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e392f08218170d9b8daec353efc49008476ae6 GIT binary patch literal 1683 zcmV;E25k9>P))&~%QClGtZi%5V_p*le@e6pq+;i^#6^`+a2w z+wFGl^XJd*%a%~JPft&}5b!Wc%)l`s46gwWd!!KOUtV6^ z?d`4JkK?#VD<5?Lu=#whx#d53gLXb<20ocB^?#?^aih^lqE1}9UirWp;2}$_B`_Qy zsPEsu>pgE20*={#s7sPW8Bwal>)GNIwR#^(B(e^t_6HGaDHmqsGNn3XiM;a+`gnbP z)!@MRkOIWP!_bbW*mARnU$;JPm`G&%{Xw0BEoD)_(?#kU^@fX*x;oWvBwArq7T}~K zG}2l)04TYu=;nI`2Vgp1xox&}yKGln!_s4_HYi?b#Q=wi%{q7VJ(aSPXo=Ky zwFI%SwEubf;kvDy0qZH2I!yr&y}iBZg=VX%Q6ivnIdX5))NMCg*Jw7}UtdSA-f9c5 zbMrJUXk80q@bNUt%dykQb6pY#562!skcjy*73u)=1IW#PpI^@eh^G~)hVgsquKHJQ zzFh0IjyQtoTJqmZRCD>Bt~Tlf>G?G1$ewFW9XctOYd_V2H!%R}qTJg%X&Mu0nR(7K zw^(Pz14i9Ogc*xqSL+kid-mCs-D;DmqrW{2B}KbJq@mFhXi%Pf08Y&t4&Z4zm&2*4 zX%H7r9?S1cHvO5EkK$qtY>-MzM`-PKTXhDeCnA~;%3P0U#UjAF;^l1dasn5s)BVQn zM39k))6NDq3e6n+`)TAJ?)p+8*HYej<4Hw3>g@3}^)v@kz~|B|4Q56^;P(3xJhZry zQ$L^0UD9o;16FnDj_)32h64wbS*^zkw06UO&%KPs(vUJ2OZ(l5F02GYqX+b^dik^E z!`Z+BxUzFRBbYtF^>#F>2wi^Y9HLlrPwltriKJoSnzclQRfz@oa1IU&sYJ<%M@crS z`Qfy`aL_C~BfM3BEv7$X#sb!?#X@%;&2*MZ$16)sQ?_+2wMryon}Eim*SMA+VDt|1 zZx%M6(7a7O(DiVCBUDcd>NtFY3UtHko@}%ig>RLiozj`8^W?iGLenbn!a(h$4H^<1 z(1L`i=jZ3#0h{qKF7kaclWUSArMGfoV<~HI2iMY+Xj~t~2emeek-8%KY z49+yG(n5va#j$RCt;Vq_?QbV#%kR+O=a8Ot!i zK+2vUhEl+7G9r3&1})Gw!_9l`x>Ul-)ssl(zPV1vNi{hGW^MQeWfPKBO7V_h3lNH_ zHEflpg)lPML8xqMn!svtt$2Y6!8J+2L~PEHYHx49_5iftnN@~OF;I7XeXZY(smn3@ zMg~z{IG~*O0N$*^H6}t%LVM})_Tpj3DmQT8@>SZvjTOdto`E%^7jWHFN{!To;INA5 dNN4!Q^&bOz7<9_+o0$Lr002ovPDHLkV1m~3M#=yH literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Desert/desert.png b/Resources/Textures/Tiles/Planet/Desert/desert.png new file mode 100644 index 0000000000000000000000000000000000000000..274ceca95d92f9709b2faa0a72562cd63785a496 GIT binary patch literal 13500 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Desert/desert_dug.png b/Resources/Textures/Tiles/Planet/Desert/desert_dug.png new file mode 100644 index 0000000000000000000000000000000000000000..55bf6904c9a3fc01f9151f24c0a8cf6a51c46a6a GIT binary patch literal 3022 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Desert/low_desert_dug.png b/Resources/Textures/Tiles/Planet/Desert/low_desert_dug.png new file mode 100644 index 0000000000000000000000000000000000000000..e82207e688c0bc5ff42c17cdac594e5016f60cff GIT binary patch literal 1206 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Grass/single_edge.png b/Resources/Textures/Tiles/Planet/Grass/single_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..437c0907709db10afd936c0d3652225d4282ea66 GIT binary patch literal 5140 zcmeHKYgiNK5)L;}w3fp`)OuSYM{0Gm+0A`R1SDLdMi5XyOL3Fkgq7S#76Pb8BVxr% zwTM_MLT!&l6fbze3s@8c1q%wOtx&CK;drP*wJ20AbQ4hFIsN1F)PL?io9xav^UlmW z^G&kpA@c*@aeB{*!C<^24U&Y?-+<*BK8*e}rlfQ+7yve z(?Okcf?Oe|<`V?v*>xAO8&Nr(bGX1|_4cFkzR1M;yF=;=_xa1B_Xm8Iu`w&O@cvwQ z-b~N18OpXr;7491De=bc_64V$Sh53q7C&AbXRjWXX&2)-O~TbS7#gq6Iofuh_}&k* z#HI&(mUMr-eAHw_ziJbr?%6wanoPYXJHHOmJT2t76*pxZd(^Nn3yevq+}5=DasG1~ z-syse(q+NNJb7JTh&^IsJWprajLV+~XeZe4xjN-1VRfa|8f9SRX3rXZsNksY&T+%r zq=g$N-*<_T2u}TUCu`=ama4KjEDbd!<5_m|hszXw@3ngt{o>m3<>WPu5gQ!^g~k>o zs{CwU(ym!o_dju6w*J!vdB?aAx&K5t4{t9wHS*jx6&I~>RaTX|thl|j)?lyGu)Uqt z-1w5J&g*?lkLGO!Nl~ZHqjMUM*w%li=^{nW<;4{L?6H~(=H_dc%BR1p4yxHO<&yA* zDz4AA?@+?iuGEt2+gk!-nx~rmGN+xaTAy1Kw!AMPui?KNd)%JBI{Tb%l;p*FWR7thxdFxZ&Ucge+m9`f z|6^um@$CJhr|tN+@3wUwm6Z$hps=SXGC?1I{o1*O&i39u6L;mfM*ru0-@nq_;K>ua z@7_Ff;pT@vdv|0nOWb6)PdUCiGWD3%ql-x zdif7gN@h+qBQMD70#(7h1?1j3M%6t#@4hJ0^^WlloXQG%elg)jtDw%|6NlXKNJDk< z9p|FRSjDN$QS~9|`Rgk->|5~d*7&HF(#j|>BI>u?=V|A1iZkw@wb=Q?YlSY(?q6?k zsX6Std*RedNyd|}C-?eZ$OCrFJLob_%(QW}H@6yE11MgKS^+`!J!FV*(^DW=8O2Y?%y=OUjC80EchM+JYNu$;p(Ihd`ii^_s7BR#GtSVHTm>DSx z0sM3Z0^qW^EH>z$L?$B4Sx$hL0av1-l7ImS`bo@;r6@fLK_-)lW#X`O1{DO0L?Vcd zKnMcT8lW**OJPZ%);QGy(T^b^j0yv(r%0U^uwY_xT>>R$GU;{TMSL2)O!g99YaC#K z<^xK?^bpKqLmCY<*uqHpC(EH^8P!k$j)ku4Vhqw%s%0gaRSSV1D8okwuCVPk`MJivBH6%96iZz|VfzakJaffKX z$la<;YsqA&M5jowgeR4VnHK*ju2YaWYP}VTI2g_+V303RA|Mxsg`ix)5rQyZA%uA% zLc!%J2SG`-Mhep^2n!Sq&LU|XguvM_Ay9&H0j31Gn1Brm5kvqA6&!&O!3Z|a<_>}g zHjs2zV(P(BS)gzlN}&|NY@tv9as+H1$Q3AI5X0mcC?~i=IS%6rzMvlpSD*npg9f9^ zNop_^0qM0Ws}Bp|sBef=%tTo1SCSAlMk#3ndJm9VTxT-AS_&sML>Prx_=NcaSRml? z*&>bzhB?S9rA36nNcW-z6=t&#p>@Sl7?e(jrWUhwDh*(j)7hYY1_GmWhH#xuEoNGR z0xXu+1_!+Q%MwHyX^mt{&kuBc7!lw9)V~STq;&}Ztc{Ceihd_XERn#ij%d67B}FWz zRT13Knxk@cdOUeN!QyI*0@jH7Akm(jD6 z9>vhhSvuciF9yWZ0ES`56F^4sqE+vsw7 z^)^Rn=|6ZT`d!TzFDatm^M=Xi21*!xmh;Oq`P*p82z^kLk-->!-g4P&pD}s@Ep()$ zGJnUmQDYsD5m{S%r_rKMq!Qoo$chIIMen5gj7n?C8y;|x!FI3OP%Py?dd$ln8_tLzR5h{^T`-Jg%Rob`d>$i;$ zYu$55zgn+rN;$kWOSAIy*+1;&-JQK?MO203FUDuPZuFj2w=UF=NLb&0s8+eX&jg4G S(GVRHL+U?Ya&Y$2HGcw?E~}>i literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Grass/triple_edge.png b/Resources/Textures/Tiles/Planet/Grass/triple_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd2a39a8f5ccd6922c8c5b475e6a192263a2512 GIT binary patch literal 6741 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 a@^0gW#u}=zYlSJ$WFRxV6|UIOBl17mjRyt* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/edge0.png b/Resources/Textures/Tiles/Planet/Snow/edge0.png new file mode 100644 index 0000000000000000000000000000000000000000..a998a7287328541a985cbba715c069a8003dcd56 GIT binary patch literal 483 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|Vn! zPZ!6KiaBp*-R){N5NP#x>{jR!;okf8Z~W=kL07ozC+KW;EpWc|HgCFZ!xRiD z&$h&ZpsBS>#h!;p)q7treOIvK|C#zL4D%;?e7I~FSQHL8*=LzxMwk(oS@6SNhi6KIdBbA=B!I< zPOBJZHf+Dzz#7`H#_sv&nY($6^7pONz7fD0qbHvCPkEB(hqB!}SFI|sW9L}&fOS^G zg>`;xSJ)L@97LQOIyn={8+I~rlrZK1o$oCAA^g3>{YI??9S{vq9GnujEaC`uH z(6=do?`!Xcj}=SO8BLj&M4f3YkkuywP4Yigzx91;t#H=B^WO>xQt8;;| O#^CAd=d#Wzp$P!2rpfsL literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/edge1.png b/Resources/Textures/Tiles/Planet/Snow/edge1.png new file mode 100644 index 0000000000000000000000000000000000000000..04f6f7222a901997f520f1a2ad930c58156513d0 GIT binary patch literal 637 zcmV-@0)qXCP)gHseYvM~Ptr@6x&7{wv|yd-7X7LEE0 zm!$e628Tvcho%RrNrlYmbaI=`M)Eut=bR)-a`!tv&*$^IFUzuYS(e=w3_uxuf8Ae> z$7Ayfp$j-14o&c2I-N>U6tZ5gUk3Loc$MRqsq5N}Mx#amghI4J7XT)cNh4x7947Js zdY1iQ+vJSL<3!6>RVB;iQuh0OBcm4r!oc6D;^3V!&&s1#phnOIv<2~LVBes%f-Znf z6d=Zl0>n5`fEXtV5aUDvVw@;Ij1vWjaiRb*P81-_yrUJ2vqa)KzjrRv~j>-Ft}S2#Oe-d0#FNzqHw7G%wB;y61-e4&DLME z)HPHAtJNxDj6{7X0@y+O&?iG|5flN>g2t$@>#+c}285S_nSqd!^`IS~3V1ek?h>j1 zOu-q~y$`(?UzoDJS!wgbJG z44G{NGwYKfV7eO&(_{>&0yJA}vJphkZ4Wbd4ZRJ}hncIYa=%!g@F}$0;`-iSpTOV` X*&`0+?{p^E00000NkvXXu0mjfjv*AP literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/edge2.png b/Resources/Textures/Tiles/Planet/Snow/edge2.png new file mode 100644 index 0000000000000000000000000000000000000000..579cecc73fd5b5e0f5de0b9d2879d502ef682775 GIT binary patch literal 487 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|Vns zPZ!6KiaBp*9qej05NLA`u*o>kY}fGqf7HE4ju)C2&A2NVSGY<<5GC&z0SMz^qHM?O~Ar^NMc~{boFyt=akR{0P38{ A?*IS* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/gravsnow.png b/Resources/Textures/Tiles/Planet/Snow/gravsnow.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d077ef6a531d6eeb714ef96ddde71aa5ed9d9e GIT binary patch literal 2095 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 AJ^%m! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/gravsnow_surround.png b/Resources/Textures/Tiles/Planet/Snow/gravsnow_surround.png new file mode 100644 index 0000000000000000000000000000000000000000..0745067fe1cad6b4c06f6e2f57239681f5ddd723 GIT binary patch literal 2972 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/plating.png b/Resources/Textures/Tiles/Planet/Snow/plating.png new file mode 100644 index 0000000000000000000000000000000000000000..3713f8be78a3084485aae6a0c8e5c12545539b7e GIT binary patch literal 1660 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/snow.png b/Resources/Textures/Tiles/Planet/Snow/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..0078b0dbd7a8ce9bebf51947693f45522b28d7c1 GIT binary patch literal 9764 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/snow_piss.png b/Resources/Textures/Tiles/Planet/Snow/snow_piss.png new file mode 100644 index 0000000000000000000000000000000000000000..7c57e327ca9b3f20cc7742a58de6d319ce1bc2e8 GIT binary patch literal 2098 zcmV-22+jA2P)SGiPVk0kCUPJ>^1Ds?^o`o7cOX1$OgjKx!5unimeaVL)VdA^r) zFlpU-&p{xl{ICH=RpwJnx2{H^{}R}M^#-)Hku;f9-Qvw zaM;K&JD0j1i=zV?*=`>7<1p%ra}j+@fWLkm$YH-02PC*Sj1nozBX$)a7VP4#_KR}#jF{$JNMg6xS4 zi1R~z=DR?SFdX$$?5a`({2;{hQ2zMsfAZqhdx`r)Z01Sf-U4=RsOGmc0Nc1Z1)t}o zrGR;!UcAxhsqXm1F^SJhOyj=?%0Xe3kk6E&dt_mnPjM6Ma&alb+2p{$m7k^w0iCPK_T^H~%K zHW^3{geyTXzY2^?Eh(8Ea;*Z9eeferGg-|)V?&{_oPjJJ{*wN1VoW76*lm8;%kH?4 zemYiz>KrH~FrYbwVLA_x3g$hGVsna(kp1KjIYGpderB7)2aDTl_2CF3ukHHLoU=p_ zDRW2yvDBEy62yzJLq_lSoa{DBNpODzv^06xtxkEjlD1Tlg z48S=$Z_5`prdRL8kzl+j3hxvp36qU4wGzm3l7{JEZj~!=#_zsV+l%=%Hj-#ieF#?# z9nc($mG*k|pahJO5=Y`J=eK~juf*zht~o^6t+A7{^O=%R+ES!*8v0Ugk0&orde%sN zQr07skAcwsVtymz=}cT%6f(JZWwHq=CET6hY?0@)$xPEg>1D7L2*)7()P1qG`HVXx z0b}1+k`gtNlGpXepJev>Ka%eu#mptyPY$qzRzM>eo+*sk_^RDC7skr+G#$xy^=Lie z3$-oIQ}H3u4!eya)Uf=39!dGHH~-a?@wwY>p8&~3OUw7Mh$;s`p>r-KDYvV+?6KhL z<=2`TR?9!tHtqSb(|6Ppa*1dW0iwhW_0d;$@a@=@zx}i(u&_2(oEj)Juf=v z!k&jRKuIz%4;?aQ)6u3_%je&J0qL@~l{LC!(}Y~+cORvxY8e4(22So!WnBt^86(fq z=9s(Iyt1~LLp)1I=g$fWcv(s`?t^ez1t>FqJHD7{(3E6X2KGH3kRRt4ud%_!bDPHc zx~d>VEvwm-8jy*3S=|4nA94|mX@dfk41$h47~TOb)^#VrHcMEQbiAoR@De?N{ev)# zQBB&!U~j)&83za@;p>{l^~ax8NS^MDnA8S+uL!_!FV+5Tjyw&3mEnh>mg;W1km2ak z8WsX&_3S~;1mq-X**SGcL4ZuT>js84Z8E)lEB80Q%gcA~RdUH@4i|`9Sh5a|85C!N zfW`)A;6+b6XGFEbhPu8$_=7l>$4{TMM-(b#=%SIYHi?{L4*lAf#p8`O8s_O@_HS7& zZnYA$`(+m=$z?yFvRSVRDd1*{I?N_U<`x}}0Iq8krrp+Xn5XRQO4(hvvmc4tv^k|w z5{e{bS#eev0cMI8MTU-PoHlhxh3e%<<6$3K&p;3)v5sVfiXKP`?kvb6g;+}~2u`JQ z()qSpc(DX|4Tk5|MNtvmnShRz525j3di7Qv>&)3+^y!|5Mw47Zo}_`69EF6DG9YG! z&!SIs0wIP+K7S44fJX^cdGao-ir{ai3 zV>|^BiHF-iW%lO%>5R8tJ!%jg2eiGGr8=WwI%jZ0wKKN?hN$5e>40PB!{y`cX$aC@ zz!%xsh3xlM&m~{+^ommoz45(^;4S;I|Z|BnI<}7YFSCW3ZwkMo!ap; zr?64>a>7E`JI7>d*Iv!ZLXGJ;5#KP!DKwwmjMby<7^SM*$!&7x=w(OtR*-P>Hq)$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/snow_surround.png b/Resources/Textures/Tiles/Planet/Snow/snow_surround.png new file mode 100644 index 0000000000000000000000000000000000000000..52289ed92f6044b8e731a60f81216d83accb4fbd GIT binary patch literal 3129 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/Snow/snowwhite.png b/Resources/Textures/Tiles/Planet/Snow/snowwhite.png new file mode 100644 index 0000000000000000000000000000000000000000..1a44d006f7df5970b6d9dd80e2ca5f9d11c76c28 GIT binary patch literal 1113 zcmV-f1g86mP)hOifLd1mBE{g@uLk_4QR=UtfQ$U0GQv4-XGz49vZ~ zy|t%DeR+9l%E98|VmUuQFT1e*3Pf!0ajB$+c`|rgy5H`m_1LshR3 z%(J?>+TH-=zTJc%=fU#w@(=G>_wn&jW@l%I@B91vGCx1xzFD`uy&a%O!8Vc~~g=9AnVk-Q6Ip2g)-_H#awBZEdanW)EqB$W^aV z4wjadhDacQHw*dQS4eUriAn_EMn-9Kb8|?cWc>X6{G9?Kz-HMFBoK!9Z3tD$Tg50t z3GN`a!L!P{m zqzU@S<>h6mEI?Q;Lb*}sYd@Pyk1?Y5`vG!2A1Vv*L}uoqzWu7)kfO}KkwUz)+1c4};^C>vfN#$T z%fH(7Bp?S2N!=Q4_dQXMPp1U#uW zl=K`TQVprxH8!EFjIFJ$W<++$zDh)vFLG*cC4&gd`=GrY1!KTi)=-L`kVF>Qj7z${ zjkiWLCNT2{+++^`88wvj9nnh+kUJPEPpq`TfV3_-!8pgNk#d~F1aEES{V|?!FP9ZA zI~Z(K2LrrBVwsbGGv9`j6$9XdmC%=8c30qU&kr$E_HF{@+#_ zsBtXm=^CHc=vm}c8IsNU7Q4fiP!DtC>S75JgIwpSeB fcPb}cW0#zNI`h`NsuNew00000NkvXXu0mjf$TAq* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Tiles/Planet/grass.rsi/grass0.png b/Resources/Textures/Tiles/Planet/grass.rsi/grass0.png deleted file mode 100644 index 8868223f7f7997b35f689f825d57a7acaf22926e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 695 zcmV;o0!aOdP)9W7bj&K>u z{qZzhq<-ea1)ra33xVJV&p40o&&P|pJ8lQN!4WRbjOXVnQ0kQJfq@*1bK(rDRC>PK zLAHAV#s1hMqmjx{KFfyPJNn#yKVDMMg1FWIQ0E+0l+RFR2Y7#G13CbP0DM%1wUtYE zr#jc)Of@8U(N%sW_pqdCazVmZbj6qoMVRTWoN3Q17{^X*q1mEYgCmouSNy0gcj4IGye6YiG+Xu3;B!4H=g^C(43rKeZ8RxL0%A z5zN0sUj^=*R>6f+LRe(1bhm(1l$|PdSwGAH{ktI_+f36k8&a;8Rz>KjnHjFy(xGck{{uR=KJfv#f`|YB002ovPDHLkV1i&ALK*-7 diff --git a/Resources/Textures/Tiles/Planet/grass.rsi/grass1.png b/Resources/Textures/Tiles/Planet/grass.rsi/grass1.png deleted file mode 100644 index 9598fcb9a4b9896fbc397a52e60821796bd34b69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706 zcmV;z0zLhSP)5?#8NG6fPh;0D}^%Wx8Izzyh9LYFQT z#BVikXD4GPmJoSfufJn^+xy4!-`D4U7j!&6?M|o5PAT{xJ;xdIo&4+DdE>FY#>zrC zn1`3&Nf3NB65rrC=lL7D!jbrk?>KKi-^-Of4EKY5YRD<)h@GP>ui2h5z|N?VOkwrg z-5o)8xfYDW%kT_JGAD56Qm%LOyZ>LVCFoA97>KC3#;&#+9XnV#mtiIX4vOI0y;|Ng zR$)W+fKck71|f%hr0fS%?6*RdMQSvPPAF?y@^UNfNRL>-;+iU%Ne9cP;b z)iGfJ3^#@yxgpc<4nR9uy_e1bXABoLLUr`fNxC}VqVXfNqZ>$f^FPB!=EPP4WoBt- zKmlZ&3G_aASwKw9MWRMPQ0$DuL4YyvP(4f#%rpn|H@9SuF2?mjXCCDYWbk<0PrD!k zkn*6E$E_o`EAWlcd^`^M#*ynna@oPGfShZwjN&egPcNbYzWwxOQ-vd0y@;4PTC-W7y#;}bxT{Yzm7N^WDD-gxQq=Q3Zef)2 z-UDWJzyZTutds_E_Y5cfLgG?1T*3}_%6WuVh<4e@w&K=?NLd9Qj)*U_+@o!H^CCiI oUEuZ&knIL`#BIHdSXTu84-U~%S0ma5&j0`b07*qoM6N<$g3vxfH2?qr diff --git a/Resources/Textures/Tiles/Planet/grass.rsi/grass2.png b/Resources/Textures/Tiles/Planet/grass.rsi/grass2.png deleted file mode 100644 index 1d21d0234f94bbc8a3952ed6357011e0164f0576..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 zcmV;l0!#ggP)=kpX}S)QiLVvbqw9d9=GsF6$| zLd((0M(<>mE3t4oHw93VfxsT8Dg&;;cT3% z=dV*an#&O8+JNWFGIho{dKv}jM8wtxDwD6`uDMwO2-=+`EeEZQZ+BJ(+_k4|wE_#Q;cI)EQMhOjgASj}C*ylpS3} z_CTx=a7?8KxZ!}s)Hp{3dq?QJWclY22SYjfIDl#=#2#uzQ|jn^!vijC$Uo@XdBn0X z((CYaZf}7r#%&SKHe#;gxz8w_7xr8ml19gQ=M1VdNMWyAx*?SFo9zebA0000^``lB0I{)(ev+-13(Z_HY z%;V|O9V9;qrGNxp*L({=@P{?_%lFrOV>iKA^Kg3Xk;V?h&%3od3qZJQLDQ)<{wsVLa+X%r3l!CCn0V<-7k93HS@!?RLz{rsu^QpbWeFHkh?m-lmuy7wlX?z zCI!#a@{!i=p49?gE_ndCO3jo{0hPB0&R|O>_jMNoexRDSY1MpR^Pk|f$*3zv>FvN` z9Z+gP+G;ps04`C%1pLSXnn@)ccEoBWg3;!cz$b0fUU6YwWc09BG!WtdvBK}Y)!I9r zs?i0b>ZZP?aHb)f6?=S|8%VsP)YSpKG)8~j*7#PJaGez58N>-&@(Lhjfg?{*bLKoCOnM zpUue!6%SUKh?Lr_r$QZsTS+a*Kz)?L-8_(TSkW>&(s@v-ie5!snXVU%qMpKC`;q^( zb@wjlEw~1u&v+?v^#{nklC2~mSkaP>ob z|KE>??P^>32W&h4a?`|B>lZ(|?J9@AkRZrz>~u+$&eU?p)bR58IHy$oSbg#0@Bg(s^AE9i{J6}sr}%3A`ael+@`=kAeA7RF zt#|v1hwdT{h0Xs~E~;bybCjh)n8A<1g7E=KjC+h%u66%5m@K^)m}D3{UHx3vIVCg! E03}BCu>b%7 diff --git a/Resources/Textures/Tiles/Planet/grass.rsi/grass_edge_corner.png b/Resources/Textures/Tiles/Planet/grass.rsi/grass_edge_corner.png deleted file mode 100644 index 7f6508e0e471379153feda44da4bc393729b778e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2620 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 H!qWc(Hwm9d diff --git a/Resources/Textures/Tiles/Planet/grass.rsi/grass_edges_old.png b/Resources/Textures/Tiles/Planet/grass.rsi/grass_edges_old.png deleted file mode 100644 index af73ea013eeff92bac6c7b646b0fd45fe8cc0ec2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1401 zcmb`H`#aMM0LH(Y+a}gBIqp_6TNaZ~UDHSB!Mf<7H~!`y%Q@_865oj)u(m=7LSi9+(@7yD zGQX&GwYosk`3*(mJsr*#FBXl={d8YaJwS3J9AI;uH=8#>FnW4cd4#lleo+Z65^1a} z2Q`|qJ{?s1MG*@6c5r6Gz}c9v;czP_;*h+RS?9c>Kz0PO8&d_yhIfPCD<8_pS_2wr z9wg>IlAy0TX-XQjqN7CpRaq9vV^p1BS2!;^P^q9}15lSg7b_pgN^JonE09xQehyEw zjm*!`ydmk$j}?s)_SRe-y*QFHgwZVEaN@p}MqC~b9j_SBpqC_k=%PHGb#^oGY}XyR z%05%)X!jd$At-)LvbpE2p*rw1&YTrj#}peHZr%b{WMywI;h~h}9X@XAF`M(P1_Ez0 z?Y&2L3cA(j8CX+H%cL5H24iQXC1t|V>W5SfmXXl5uMf~slO!7qSEoG!>*yv|3l~W! z*o65hLm?au=<5A?Ci6ocAVCdtLR^XPjPFaZw#!`n8w2`|a?Q3=wR2Ti3X<$WZvh*s zwnk4tcj;SoX|>%ZdxXF&ni`4G4eYKE0>U9I$n1r`*P?-_fOS5Af$SWD3S|60R2UOM(JA*6-J-K(N9ncSw*rQIu48gDm#6Hxyboy!7zTyimNe zeD%v}A!CD+28+2e{5&RZGZ@&=x4h$SEBCGr;HTupLlp1r?!9zk=~*=8nX{H|Qu2zI zgRDCpOS0kigjAFOd8V_Mdgu5^p~Go&MBd^B+!{o#6^=`I>yX;xMH*9!zVK1|J*?5;Rqf%Y0a zc*q0Q+OqHi1V~(G;|`Y80N#FkfZL^zb2UT>nAUyTdgw?V1(wd6Oz}a6wg}5|b1t1- zwj|mcNM-U+9ojg*(&)wG!(%>pEY81eAr|^)ef)&4_G{lRDDL4N=Eg=2yt(C_XQi0Y z#efYl$h64FH zz@iG=qn>pXoyMRZ9mN+Wp;a$4vFaPQnzLv