|
@@ -202,6 +202,49 @@ private static readonly Dictionary<(Biome, string, Precipitation), string> _weat
|
|
|
{ (Biome.Jungle, "Winter", Precipitation.Storm), "Storm" },
|
|
{ (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>
|
|
/// <summary>
|
|
|
/// Initializes the system and subscribes to relevant events.
|
|
/// Initializes the system and subscribes to relevant events.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -244,6 +287,7 @@ public override void Update(float frameTime)
|
|
|
nomads.NextSeasonChange = _timing.CurTime + TimeSpan.FromMinutes(GetRandomSeasonDuration(nomads));
|
|
nomads.NextSeasonChange = _timing.CurTime + TimeSpan.FromMinutes(GetRandomSeasonDuration(nomads));
|
|
|
Dirty(uid, nomads);
|
|
Dirty(uid, nomads);
|
|
|
_chat.DispatchGlobalAnnouncement($"Changed season to {nomads.CurrentSeason}", null, false, null, null);
|
|
_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);
|
|
UpdateTileWeathers(uid, nomads);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -257,16 +301,18 @@ public override void Update(float frameTime)
|
|
|
nomads.CurrentPrecipitation = GetNextPrecipitation(nomads.CurrentPrecipitation);
|
|
nomads.CurrentPrecipitation = GetNextPrecipitation(nomads.CurrentPrecipitation);
|
|
|
nomads.NextSwitchTime = _timing.CurTime + TimeSpan.FromMinutes(GetRandomPrecipitationDuration(nomads));
|
|
nomads.NextSwitchTime = _timing.CurTime + TimeSpan.FromMinutes(GetRandomPrecipitationDuration(nomads));
|
|
|
Dirty(uid, nomads);
|
|
Dirty(uid, nomads);
|
|
|
|
|
+ Log.Debug($"Precipitation changed from {oldPrecipitation} to {nomads.CurrentPrecipitation} for entity {uid}, triggering UpdateTileWeathers");
|
|
|
UpdateTileWeathers(uid, nomads);
|
|
UpdateTileWeathers(uid, nomads);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Updates weather effects for each tile based on biome, season, and global precipitation.
|
|
/// 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>
|
|
/// </summary>
|
|
|
private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
|
|
private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
|
|
|
{
|
|
{
|
|
|
|
|
+ Log.Debug($"Starting UpdateTileWeathers for entity {uid}, season: {nomads.CurrentSeason}");
|
|
|
var mapId = Transform(uid).MapID;
|
|
var mapId = Transform(uid).MapID;
|
|
|
var gridUid = GetGridUidForMap(mapId);
|
|
var gridUid = GetGridUidForMap(mapId);
|
|
|
if (gridUid == null)
|
|
if (gridUid == null)
|
|
@@ -274,38 +320,121 @@ private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
|
|
|
Log.Warning($"No grid found for map {mapId}");
|
|
Log.Warning($"No grid found for map {mapId}");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+ Log.Debug($"Grid found for map {mapId}: {gridUid}");
|
|
|
|
|
|
|
|
if (!TryComp<MapGridComponent>(gridUid.Value, out var grid))
|
|
if (!TryComp<MapGridComponent>(gridUid.Value, out var grid))
|
|
|
|
|
+ {
|
|
|
|
|
+ Log.Warning($"No MapGridComponent found for grid {gridUid}");
|
|
|
return;
|
|
return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (!TryComp<GridAtmosphereComponent>(gridUid.Value, out var gridAtmosphere))
|
|
if (!TryComp<GridAtmosphereComponent>(gridUid.Value, out var gridAtmosphere))
|
|
|
|
|
+ {
|
|
|
|
|
+ Log.Warning($"No GridAtmosphereComponent found for grid {gridUid}");
|
|
|
return;
|
|
return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
RoofComponent? roofComp = TryComp<RoofComponent>(gridUid.Value, out var rc) ? rc : null;
|
|
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>
|
|
/// <summary>
|
|
@@ -357,7 +486,57 @@ private void UpdateTileWeathers(EntityUid uid, WeatherNomadsComponent nomads)
|
|
|
air = newAir;
|
|
air = newAir;
|
|
|
}
|
|
}
|
|
|
air.Temperature = temperature;
|
|
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>
|
|
/// <summary>
|