1
0
Эх сурвалжийг харах

feat: changing tiles (#132)

Co-authored-by: Alex Sampaio <alexsampaio.contato@gmail.com>
Taislin 7 сар өмнө
parent
commit
ef8b611a29

+ 195 - 16
Content.Server/Weather/WeatherNomadsSystem.cs

@@ -202,6 +202,49 @@ private static readonly Dictionary<(Biome, string, Precipitation), string> _weat
         { (Biome.Jungle, "Winter", Precipitation.Storm), "Storm" },
     };
 
+    /// <summary>
+    /// Dictionary that maps each season to its transformation rules for tiles and entities.
+    /// Each entry contains a tuple with two dictionaries:
+    /// - Tile transformation dictionary: Maps original tile names to their transformed counterparts.
+    /// - Entity transformation dictionary: Maps original entity prototype IDs to their transformed counterparts.
+    /// Seasons without transformations have empty dictionaries.
+    /// </summary>
+    private readonly Dictionary<string, (Dictionary<string, string> TileTransformations, Dictionary<string, string> EntityTransformations)> _seasonBasedTransformationRules = new()
+    {
+        ["Winter"] = (
+            TileTransformations: new Dictionary<string, string>
+            {
+                { "FloorPlanetGrass", "FloorSnowGrass" },
+                { "FloorDirt", "FloorSnow" },
+                { "FloorSand", "FloorSnowSand" },
+            },
+            EntityTransformations: new Dictionary<string, string>
+            {
+                { "TreeTemperate", "TreeTemperateSnow" } // Temperate trees get a snowy variant
+            }
+        ),
+        ["Summer"] = (
+            TileTransformations: new Dictionary<string, string>(),
+            EntityTransformations: new Dictionary<string, string>()
+        ),
+        ["Spring"] = (
+            TileTransformations: new Dictionary<string, string>
+            {
+                { "FloorSnowGrass", "FloorPlanetGrass" },
+                { "FloorSnow", "FloorDirt" },
+                { "FloorSnowSand", "FloorSand" },
+            },
+            EntityTransformations: new Dictionary<string, string>
+            {
+                { "TreeTemperateSnow", "TreeTemperate" }
+            }
+        ),
+        ["Autumn"] = (
+            TileTransformations: new Dictionary<string, string>(),
+            EntityTransformations: new Dictionary<string, string>()
+        )
+    };
+
     /// <summary>
     /// Initializes the system and subscribes to relevant events.
     /// </summary>
@@ -244,6 +287,7 @@ public override void Update(float frameTime)
                 nomads.NextSeasonChange = _timing.CurTime + TimeSpan.FromMinutes(GetRandomSeasonDuration(nomads));
                 Dirty(uid, nomads);
                 _chat.DispatchGlobalAnnouncement($"Changed season to {nomads.CurrentSeason}", null, false, null, null);
+                Log.Debug($"Season changed from {oldSeason} to {nomads.CurrentSeason} for entity {uid}, triggering UpdateTileWeathers");
                 UpdateTileWeathers(uid, nomads);
             }
 
@@ -257,16 +301,18 @@ public override void Update(float frameTime)
             nomads.CurrentPrecipitation = GetNextPrecipitation(nomads.CurrentPrecipitation);
             nomads.NextSwitchTime = _timing.CurTime + TimeSpan.FromMinutes(GetRandomPrecipitationDuration(nomads));
             Dirty(uid, nomads);
+            Log.Debug($"Precipitation changed from {oldPrecipitation} to {nomads.CurrentPrecipitation} for entity {uid}, triggering UpdateTileWeathers");
             UpdateTileWeathers(uid, nomads);
         }
-
     }
 
     /// <summary>
     /// Updates weather effects for each tile based on biome, season, and global precipitation.
+    /// Also applies transformations to tiles and entities based on the current season if transformation rules are defined.
     /// </summary>
     private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
     {
+        Log.Debug($"Starting UpdateTileWeathers for entity {uid}, season: {nomads.CurrentSeason}");
         var mapId = Transform(uid).MapID;
         var gridUid = GetGridUidForMap(mapId);
         if (gridUid == null)
@@ -274,38 +320,121 @@ private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
             Log.Warning($"No grid found for map {mapId}");
             return;
         }
+        Log.Debug($"Grid found for map {mapId}: {gridUid}");
 
         if (!TryComp<MapGridComponent>(gridUid.Value, out var grid))
+        {
+            Log.Warning($"No MapGridComponent found for grid {gridUid}");
             return;
+        }
 
         if (!TryComp<GridAtmosphereComponent>(gridUid.Value, out var gridAtmosphere))
+        {
+            Log.Warning($"No GridAtmosphereComponent found for grid {gridUid}");
             return;
+        }
 
         RoofComponent? roofComp = TryComp<RoofComponent>(gridUid.Value, out var rc) ? rc : null;
 
-        foreach (var tile in gridAtmosphere.Tiles.Values)
+        // Retrieve transformation rules for the current season, defaulting to empty dictionaries if not found
+        if (!_seasonBasedTransformationRules.TryGetValue(nomads.CurrentSeason, out var transformationRules))
         {
-            var tileRef = grid.GetTileRef(tile.GridIndices);
-            if (tileRef.Tile.IsEmpty)
-                continue; // Skip empty tiles
+            Log.Warning($"No transformation rules defined for season {nomads.CurrentSeason}");
+            transformationRules = (TileTransformations: new Dictionary<string, string>(), EntityTransformations: new Dictionary<string, string>());
+        }
+        Log.Debug($"Transformation rules retrieved for season {nomads.CurrentSeason}: {transformationRules.TileTransformations.Count} tile rules, {transformationRules.EntityTransformations.Count} entity rules");
 
-            // Get biome from tile definition
-            var tileDef = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
-            if (!Enum.TryParse<Biome>(tileDef.Biome, true, out var biome))
-            {
-                biome = Biome.Temperate; // Fallback to Temperate if biome string is invalid
-                Log.Warning($"Invalid biome '{tileDef.Biome}' for tile at {tileRef.GridIndices}, defaulting to Temperate");
-            }
+        var tileTransformationDictionary = transformationRules.TileTransformations;
+        var entityTransformationDictionary = transformationRules.EntityTransformations;
 
-            if (_weatherTransitionMap.TryGetValue((biome, nomads.CurrentSeason, nomads.CurrentPrecipitation), out var weatherType))
+        // Apply tile transformations only if there are rules defined
+        if (tileTransformationDictionary.Count > 0)
+        {
+            Log.Debug($"Processing {gridAtmosphere.Tiles.Count} tiles for transformation in season {nomads.CurrentSeason}");
+            foreach (var tile in gridAtmosphere.Tiles.Values)
             {
-                ApplyWeatherToTile(uid, nomads, gridUid.Value, tileRef, weatherType, grid, gridAtmosphere, roofComp);
+                var tileRef = grid.GetTileRef(tile.GridIndices);
+                if (tileRef.Tile.IsEmpty)
+                {
+                    continue; // Skip empty tiles
+                }
+
+                var tileDef = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
+                if (tileTransformationDictionary.TryGetValue(tileDef.ID, out var transformedTileName))
+                {
+                    if (tileDef.ID == transformedTileName)
+                    {
+                        continue;
+                    }
+                    var newTileDefinition = _tileDefManager[transformedTileName];
+                    var newTile = new Tile(newTileDefinition.TileId);
+                    grid.SetTile(tileRef.GridIndices, newTile);
+                    Log.Debug($"Transformed tile at {tileRef.GridIndices} from {tileDef.ID} to {transformedTileName} for season {nomads.CurrentSeason}");
+                }
+                else
+                {
+                    Log.Debug($"No transformation rule found for tile {tileDef.ID} at {tileRef.GridIndices}");
+                }
+
+                // Get biome from tile definition
+                if (!Enum.TryParse<Biome>(tileDef.Biome, true, out var biome))
+                {
+                    biome = Biome.Temperate; // Fallback to Temperate if biome string is invalid
+                    Log.Warning($"Invalid biome '{tileDef.Biome}' for tile at {tileRef.GridIndices}, defaulting to Temperate");
+                }
+
+                if (_weatherTransitionMap.TryGetValue((biome, nomads.CurrentSeason, nomads.CurrentPrecipitation), out var weatherType))
+                {
+                    ApplyWeatherToTile(uid, nomads, gridUid.Value, tileRef, weatherType, grid, gridAtmosphere, roofComp);
+                }
+                else
+                {
+                    Log.Warning($"No weather mapping found for Biome: {biome}, Season: {nomads.CurrentSeason}, Precipitation: {nomads.CurrentPrecipitation}");
+                }
             }
-            else
+        }
+        else
+        {
+            Log.Debug($"No tile transformations defined for season {nomads.CurrentSeason}, processing {gridAtmosphere.Tiles.Count} tiles for weather effects only");
+            // If no tile transformations, just apply weather effects
+            foreach (var tile in gridAtmosphere.Tiles.Values)
             {
-                Log.Warning($"No weather mapping found for Biome: {biome}, Season: {nomads.CurrentSeason}, Precipitation: {nomads.CurrentPrecipitation}");
+                var tileRef = grid.GetTileRef(tile.GridIndices);
+                if (tileRef.Tile.IsEmpty)
+                {
+                    Log.Debug($"Skipping empty tile at {tileRef.GridIndices}");
+                    continue; // Skip empty tiles
+                }
+
+                // Get biome from tile definition
+                var tileDef = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
+                if (!Enum.TryParse<Biome>(tileDef.Biome, true, out var biome))
+                {
+                    biome = Biome.Temperate; // Fallback to Temperate if biome string is invalid
+                    Log.Warning($"Invalid biome '{tileDef.Biome}' for tile at {tileRef.GridIndices}, defaulting to Temperate");
+                }
+
+                if (_weatherTransitionMap.TryGetValue((biome, nomads.CurrentSeason, nomads.CurrentPrecipitation), out var weatherType))
+                {
+                    ApplyWeatherToTile(uid, nomads, gridUid.Value, tileRef, weatherType, grid, gridAtmosphere, roofComp);
+                }
+                else
+                {
+                    Log.Warning($"No weather mapping found for Biome: {biome}, Season: {nomads.CurrentSeason}, Precipitation: {nomads.CurrentPrecipitation}");
+                }
             }
         }
+
+        // Apply entity transformations only if there are rules defined
+        if (entityTransformationDictionary.Count > 0)
+        {
+            Log.Debug($"Calling TransformEntitiesOnGrid for {entityTransformationDictionary.Count} entity transformation rules in season {nomads.CurrentSeason}");
+            TransformEntitiesOnGrid(gridUid.Value, nomads, entityTransformationDictionary);
+        }
+        else
+        {
+            Log.Debug($"No entity transformations defined for season {nomads.CurrentSeason}, skipping TransformEntitiesOnGrid");
+        }
     }
 
     /// <summary>
@@ -357,7 +486,57 @@ private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
             air = newAir;
         }
         air.Temperature = temperature;
+    }
 
+    /// <summary>
+    /// Transforms entities on the grid based on the transformation rules defined for the current season.
+    /// </summary>
+    private void TransformEntitiesOnGrid(EntityUid gridUid, WeatherNomadsComponent nomads, Dictionary<string, string> entityTransformationDictionary)
+    {
+        if (TryComp<MapGridComponent>(gridUid, out var gridComp))
+        {
+            Log.Debug($"TransformEntitiesOnGrid: MapGridComponent found for grid {gridUid}");
+            var anchoredEntities = EntityQuery<TransformComponent>()
+                .Where(t => t.GridUid == gridUid && t.Anchored)
+                .Select(t => t.Owner)
+                .ToList();
+            Log.Debug($"Found {anchoredEntities.Count} anchored entities on grid {gridUid}");
+
+            foreach (var entity in anchoredEntities)
+            {
+                if (!TryComp<MetaDataComponent>(entity, out var metaData))
+                {
+                    Log.Debug($"Entity {entity} has no MetaDataComponent");
+                    continue;
+                }
+                if (metaData.EntityPrototype == null)
+                {
+                    Log.Debug($"Entity {entity} has no EntityPrototype");
+                    continue;
+                }
+                if (!entityTransformationDictionary.TryGetValue(metaData.EntityPrototype.ID, out var transformedEntityPrototypeId))
+                {
+                    Log.Debug($"No transformation rule for entity {entity} with prototype ID {metaData.EntityPrototype.ID}");
+                    continue;
+                }
+
+                if (metaData.EntityPrototype.ID == transformedEntityPrototypeId)
+                {
+                    continue;
+                }
+
+                var transformComponent = Transform(entity);
+                var entityCoordinates = transformComponent.Coordinates;
+
+                QueueDel(entity);
+                var newEntity = Spawn(transformedEntityPrototypeId, entityCoordinates);
+                Log.Debug($"Transformed entity {entity} to {newEntity} at {entityCoordinates} for season {nomads.CurrentSeason}");
+            }
+        }
+        else
+        {
+            Log.Warning($"Could not get MapGridComponent for grid {gridUid}");
+        }
     }
 
     /// <summary>

+ 5 - 0
Resources/Prototypes/Tiles/planet.yml

@@ -218,6 +218,11 @@
   biome: Tundra
   suffix: Tundra
 
+- type: tile
+  id: FloorSnowSand
+  parent: FloorSnow
+  name: tiles-snow
+
 # Snow
 - type: tile
   id: FloorSnowGrass