WeatherNomadsSystem.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using Content.Shared.Weather;
  4. using Robust.Shared.Map;
  5. using Robust.Shared.Prototypes;
  6. using Robust.Shared.Timing;
  7. using Robust.Shared.GameObjects;
  8. using Content.Server.Atmos.Components;
  9. using Content.Server.Atmos.EntitySystems;
  10. using Content.Shared.Atmos;
  11. using Content.Shared.Light.Components;
  12. using Content.Shared.Maps;
  13. using Robust.Shared.Map.Components;
  14. using Content.Shared.Light.EntitySystems;
  15. using Content.Server.Chat.Systems;
  16. namespace Content.Server.Weather;
  17. /// <summary>
  18. /// System responsible for managing dynamic weather changes and temperature adjustments for exposed tiles in a grid.
  19. /// </summary>
  20. public sealed class WeatherNomadsSystem : EntitySystem
  21. {
  22. // Dependencies injected via IoC
  23. [Dependency] private readonly IGameTiming _timing = default!;
  24. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  25. [Dependency] private readonly SharedWeatherSystem _weatherSystem = default!;
  26. [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
  27. [Dependency] private readonly IMapManager _mapManager = default!;
  28. [Dependency] private readonly SharedRoofSystem _roofSystem = default!;
  29. [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
  30. [Dependency] private readonly SharedMapSystem _mapSystem = default!;
  31. [Dependency] private readonly ChatSystem _chat = default!;
  32. /// <summary>
  33. /// Structure representing properties of a weather type.
  34. /// </summary>
  35. private class WeatherType
  36. {
  37. public string? PrototypeId { get; set; } // ID of the weather prototype, null for "None"
  38. public int Weight { get; set; } // Weight for weather transition order
  39. public float MinTemperature { get; set; } // Minimum temperature in Kelvin
  40. public float MaxTemperature { get; set; } // Maximum temperature in Kelvin
  41. }
  42. /// <summary>
  43. /// Dictionary defining available weather types and their properties.
  44. /// </summary>
  45. private readonly Dictionary<string, WeatherType> _weatherTypes = new()
  46. {
  47. { "None", new WeatherType { PrototypeId = "", Weight = 0, MinTemperature = 293.15f, MaxTemperature = 293.15f } },
  48. { "Rain", new WeatherType { PrototypeId = "Rain", Weight = 1, MinTemperature = 278.15f, MaxTemperature = 288.15f } },
  49. { "Storm", new WeatherType { PrototypeId = "Storm", Weight = 3, MinTemperature = 273.15f, MaxTemperature = 278.15f } },
  50. { "SnowfallLight", new WeatherType { PrototypeId = "SnowfallLight", Weight = 4, MinTemperature = 268.15f, MaxTemperature = 273.15f } },
  51. { "SnowfallMedium", new WeatherType { PrototypeId = "SnowfallMedium", Weight = 5, MinTemperature = 258.15f, MaxTemperature = 268.15f } },
  52. { "SnowfallHeavy", new WeatherType { PrototypeId = "SnowfallHeavy", Weight = 6, MinTemperature = 243.15f, MaxTemperature = 258.15f } },
  53. { "Hail", new WeatherType { PrototypeId = "Hail", Weight = 7, MinTemperature = 273.15f, MaxTemperature = 278.15f } },
  54. { "Sandstorm", new WeatherType { PrototypeId = "Sandstorm", Weight = 9, MinTemperature = 293.15f, MaxTemperature = 313.15f } },
  55. { "SandstormHeavy", new WeatherType { PrototypeId = "SandstormHeavy", Weight = 10, MinTemperature = 293.15f, MaxTemperature = 313.15f } },
  56. };
  57. public enum Biome
  58. {
  59. Tundra,
  60. Taiga,
  61. Temperate,
  62. Sea,
  63. SemiArid,
  64. Desert,
  65. Savanna,
  66. Jungle
  67. }
  68. public enum Precipitation
  69. {
  70. Dry,
  71. LightWet,
  72. HeavyWet,
  73. Storm
  74. }
  75. public class WeatherTransition
  76. {
  77. public Biome Biome { get; set; }
  78. public Precipitation Precipitation { get; set; }
  79. public string Season { get; set; } = "Spring";
  80. public string WeatherType { get; set; } = "None";
  81. }
  82. private readonly List<WeatherTransition> _weatherTransitions = new()
  83. {
  84. // Summer
  85. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  86. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "SnowfallLight" },
  87. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "SnowfallMedium" },
  88. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "SnowfallHeavy" },
  89. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  90. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Rain" },
  91. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Rain" },
  92. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Hail" },
  93. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  94. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Rain" },
  95. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Rain" },
  96. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Storm" },
  97. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  98. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Rain" },
  99. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Rain" },
  100. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Storm" },
  101. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  102. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Clear" },
  103. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Rain" },
  104. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Rain" },
  105. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  106. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Clear" },
  107. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Sandstorm" },
  108. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "SandstormHeavy" },
  109. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  110. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Clear" },
  111. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Rain" },
  112. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Storm" },
  113. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Dry, Season = "Summer", WeatherType = "Clear" },
  114. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.LightWet, Season = "Summer", WeatherType = "Rain" },
  115. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.HeavyWet, Season = "Summer", WeatherType = "Storm" },
  116. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Storm, Season = "Summer", WeatherType = "Storm" },
  117. // Spring
  118. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  119. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "SnowfallLight" },
  120. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "SnowfallMedium" },
  121. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "SnowfallHeavy" },
  122. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  123. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Rain" },
  124. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "SnowfallLight" },
  125. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "SnowfallHeavy" },
  126. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  127. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Rain" },
  128. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Storm" },
  129. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "SnowfallMedium" },
  130. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  131. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Rain" },
  132. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Rain" },
  133. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "Storm" },
  134. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  135. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Clear" },
  136. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Rain" },
  137. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "Rain" },
  138. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  139. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Clear" },
  140. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Rain" },
  141. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "Sandstorm" },
  142. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  143. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Clear" },
  144. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Rain" },
  145. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "Storm" },
  146. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Dry, Season = "Spring", WeatherType = "Clear" },
  147. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.LightWet, Season = "Spring", WeatherType = "Rain" },
  148. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.HeavyWet, Season = "Spring", WeatherType = "Rain" },
  149. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Storm, Season = "Spring", WeatherType = "Storm" },
  150. // Autumn
  151. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  152. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "SnowfallLight" },
  153. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "SnowfallMedium" },
  154. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "SnowfallHeavy" },
  155. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  156. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Rain" },
  157. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "SnowfallLight" },
  158. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "SnowfallHeavy" },
  159. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  160. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Rain" },
  161. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Storm" },
  162. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "SnowfallMedium" },
  163. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  164. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Rain" },
  165. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Rain" },
  166. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "Storm" },
  167. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  168. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Clear" },
  169. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Rain" },
  170. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "Rain" },
  171. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  172. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Clear" },
  173. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Rain" },
  174. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "Sandstorm" },
  175. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  176. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Clear" },
  177. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Rain" },
  178. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "Storm" },
  179. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Dry, Season = "Autumn", WeatherType = "Clear" },
  180. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.LightWet, Season = "Autumn", WeatherType = "Rain" },
  181. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.HeavyWet, Season = "Autumn", WeatherType = "Rain" },
  182. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Storm, Season = "Autumn", WeatherType = "Storm" },
  183. // Winter
  184. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  185. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "SnowfallMedium" },
  186. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "SnowfallHeavy" },
  187. new WeatherTransition { Biome = Biome.Tundra, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "SnowfallHeavy" },
  188. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  189. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "SnowfallLight" },
  190. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "SnowfallHeavy" },
  191. new WeatherTransition { Biome = Biome.Taiga, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "SnowfallHeavy" },
  192. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  193. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "SnowfallLight" },
  194. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "SnowfallMedium" },
  195. new WeatherTransition { Biome = Biome.Temperate, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "SnowfallHeavy" },
  196. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  197. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "Rain" },
  198. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "Storm" },
  199. new WeatherTransition { Biome = Biome.Sea, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "Storm" },
  200. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  201. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "Rain" },
  202. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "Rain" },
  203. new WeatherTransition { Biome = Biome.SemiArid, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "Storm" },
  204. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  205. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "Clear" },
  206. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "Rain" },
  207. new WeatherTransition { Biome = Biome.Desert, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "Rain" },
  208. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  209. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "Rain" },
  210. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "Storm" },
  211. new WeatherTransition { Biome = Biome.Savanna, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "Storm" },
  212. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Dry, Season = "Winter", WeatherType = "Clear" },
  213. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.LightWet, Season = "Winter", WeatherType = "Rain" },
  214. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.HeavyWet, Season = "Winter", WeatherType = "Storm" },
  215. new WeatherTransition { Biome = Biome.Jungle, Precipitation = Precipitation.Storm, Season = "Winter", WeatherType = "Storm" },
  216. };
  217. /// <summary>
  218. /// Initializes the system and subscribes to relevant events.
  219. /// </summary>
  220. public override void Initialize()
  221. {
  222. base.Initialize();
  223. SubscribeLocalEvent<WeatherNomadsComponent, MapInitEvent>(OnMapInit);
  224. Log.Debug("WeatherNomadsSystem initialized successfully");
  225. }
  226. /// <summary>
  227. /// Handles the initialization of weather for a map when it is first created.
  228. /// </summary>
  229. private void OnMapInit(EntityUid uid, WeatherNomadsComponent component, MapInitEvent args)
  230. {
  231. var enabledTypes = _weatherTypes.Values
  232. .Where(w => component.EnabledWeathers.Contains(w.PrototypeId ?? string.Empty) || w.PrototypeId == "")
  233. .OrderBy(w => w.Weight)
  234. .ToList();
  235. if (enabledTypes.Any())
  236. {
  237. component.CurrentWeather = enabledTypes.First().PrototypeId ?? "";
  238. SetWeatherAndTemperature(uid, component);
  239. component.NextSwitchTime = _timing.CurTime + TimeSpan.FromMinutes(GetRandomSeasonDuration(component));
  240. component.NextSeasonChange = _timing.CurTime + TimeSpan.FromMinutes(45); // Initialize season change time
  241. Dirty(uid, component);
  242. Log.Debug($"Weather started for entity {uid} with {component.CurrentWeather}");
  243. Log.Debug($"Seasons started for entity {uid} with {component.CurrentSeason}");
  244. _chat.DispatchGlobalAnnouncement($"Current season: {component.CurrentSeason}", "World",
  245. false,
  246. null,
  247. null);
  248. }
  249. else
  250. {
  251. Log.Warning($"No valid weather types enabled for entity {uid}");
  252. }
  253. }
  254. /// <summary>
  255. /// Updates the weather system periodically, switching weather states as needed.
  256. /// </summary>
  257. public override void Update(float frameTime)
  258. {
  259. base.Update(frameTime);
  260. var query = EntityQueryEnumerator<WeatherNomadsComponent>();
  261. while (query.MoveNext(out var uid, out var nomads))
  262. {
  263. if (_timing.CurTime >= nomads.NextSeasonChange)
  264. {
  265. // Change the season
  266. nomads.CurrentSeason = GetNextSeason(nomads.CurrentSeason);
  267. nomads.NextSeasonChange = _timing.CurTime + TimeSpan.FromMinutes(45);
  268. Dirty(uid, nomads);
  269. Log.Debug($"Changed season to {nomads.CurrentSeason}");
  270. _chat.DispatchGlobalAnnouncement($"Changed season to {nomads.CurrentSeason}",
  271. null,
  272. false,
  273. null,
  274. null);
  275. }
  276. if (_timing.CurTime < nomads.NextSwitchTime)
  277. continue;
  278. //This is where we would determine the biome, precipitation and season.
  279. //For now, we will just use a random weather type.
  280. var enabledTypes = _weatherTypes.Values
  281. .Where(w => nomads.EnabledWeathers.Contains(w.PrototypeId ?? string.Empty) || w.PrototypeId == "")
  282. .OrderBy(w => w.Weight)
  283. .ToList();
  284. if (!enabledTypes.Any())
  285. continue;
  286. var currentWeatherType = _weatherTypes.Values.FirstOrDefault(w => w.PrototypeId == nomads.CurrentWeather);
  287. if (currentWeatherType == null)
  288. {
  289. Log.Warning($"Current weather {nomads.CurrentWeather} not found in weather types");
  290. continue;
  291. }
  292. var currentIndex = enabledTypes.IndexOf(currentWeatherType);
  293. if (currentIndex == -1)
  294. {
  295. Log.Warning($"Current weather {nomads.CurrentWeather} not found in enabled types");
  296. continue;
  297. }
  298. var nextIndex = (currentIndex + 1) % enabledTypes.Count;
  299. nomads.CurrentWeather = enabledTypes[nextIndex].PrototypeId ?? "";
  300. SetWeatherAndTemperature(uid, nomads);
  301. nomads.NextSwitchTime = _timing.CurTime + TimeSpan.FromMinutes(GetRandomSeasonDuration(nomads));
  302. Dirty(uid, nomads);
  303. Log.Debug($"Switched weather for entity {uid} to {nomads.CurrentWeather}");
  304. }
  305. }
  306. /// <summary>
  307. /// Sets the weather for a map and adjusts the temperature for exposed tiles in the grid.
  308. /// </summary>
  309. private void SetWeatherAndTemperature(EntityUid uid, WeatherNomadsComponent component)
  310. {
  311. var weatherType = _weatherTypes.Values.FirstOrDefault(w => w.PrototypeId == component.CurrentWeather);
  312. if (weatherType == null)
  313. {
  314. Log.Warning($"Weather type for {component.CurrentWeather} not found");
  315. return;
  316. }
  317. var mapId = Transform(uid).MapID;
  318. var gridUid = GetGridUidForMap(mapId); // Get the grid for the map
  319. if (gridUid == null)
  320. {
  321. Log.Warning($"No grid found for map {mapId}");
  322. return;
  323. }
  324. // Apply the weather to the map
  325. if (!string.IsNullOrEmpty(weatherType.PrototypeId) && _prototypeManager.TryIndex<WeatherPrototype>(weatherType.PrototypeId, out var proto))
  326. {
  327. _weatherSystem.SetWeather(mapId, proto, null);
  328. Log.Debug($"Set weather {weatherType.PrototypeId} for map {mapId}");
  329. }
  330. else
  331. {
  332. _weatherSystem.SetWeather(mapId, null, null);
  333. Log.Debug($"Set no weather for map {mapId}");
  334. }
  335. // Randomize and apply temperature only to exposed tiles
  336. var temperature = (float)(weatherType.MinTemperature + (weatherType.MaxTemperature - weatherType.MinTemperature) * Random.Shared.NextDouble());
  337. SetGridTemperature(gridUid.Value, temperature);
  338. }
  339. /// <summary>
  340. /// Generates a random duration for a weather season based on component settings.
  341. /// </summary>
  342. private double GetRandomSeasonDuration(WeatherNomadsComponent component)
  343. {
  344. return Random.Shared.Next(component.MinSeasonMinutes, component.MaxSeasonMinutes + 1);
  345. }
  346. /// <summary>
  347. /// Adjusts the temperature of exposed tiles in a grid based on weather conditions.
  348. /// </summary>
  349. private void SetGridTemperature(EntityUid gridUid, float temperature)
  350. {
  351. // Verifica se o grid tem um GridAtmosphereComponent
  352. if (!TryComp<GridAtmosphereComponent>(gridUid, out var gridAtmosphere))
  353. {
  354. Log.Warning($"Grid {gridUid} does not have a GridAtmosphereComponent");
  355. return;
  356. }
  357. // Obtém o componente MapGridComponent
  358. var grid = Comp<MapGridComponent>(gridUid);
  359. // Tenta obter o RoofComponent, se existir
  360. RoofComponent? roofComp = null;
  361. if (TryComp<RoofComponent>(gridUid, out var roofComponent))
  362. {
  363. roofComp = roofComponent;
  364. }
  365. // Itera sobre os tiles do grid
  366. foreach (var tile in gridAtmosphere.Tiles.Values)
  367. {
  368. var index = tile.GridIndices;
  369. var tileRef = grid.GetTileRef(index);
  370. // Verifica se o clima pode afetar este tile
  371. if (CanWeatherAffect(gridUid, grid, tileRef, roofComp))
  372. {
  373. if (tile.Air != null)
  374. {
  375. var air = tile.Air;
  376. // Se a mistura de gás é imutável, cria uma cópia mutável
  377. if (air.Immutable)
  378. {
  379. var newAir = new GasMixture();
  380. newAir.CopyFrom(air);
  381. air = newAir;
  382. }
  383. air.Temperature = temperature;
  384. // Atualiza a atmosfera do tile, se necessário
  385. //_atmosphere.UpdateTile(gridUid, gridAtmosphere, tile);
  386. }
  387. }
  388. }
  389. Log.Debug($"Adjusted temperature for exposed tiles in grid {gridUid} to {temperature} K");
  390. }
  391. /// <summary>
  392. /// Determines if weather can affect a specific tile, based on roof coverage, tile type, and blocking entities.
  393. /// </summary>
  394. private bool CanWeatherAffect(EntityUid gridUid, MapGridComponent grid, TileRef tileRef, RoofComponent? roofComp)
  395. {
  396. // Se o tile está vazio, o clima pode afetá-lo
  397. if (tileRef.Tile.IsEmpty)
  398. return true;
  399. // Se há um RoofComponent e o tile está coberto, o clima não pode afetá-lo
  400. if (roofComp != null && _roofSystem.IsRooved((gridUid, grid, roofComp), tileRef.GridIndices))
  401. return false;
  402. // Verifica se o tipo de tile permite clima
  403. var tileDef = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
  404. if (!tileDef.Weather)
  405. return false;
  406. // Verifica se há entidades ancoradas que bloqueiam o clima
  407. var anchoredEntities = _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, tileRef.GridIndices);
  408. while (anchoredEntities.MoveNext(out var ent))
  409. {
  410. if (HasComp<BlockWeatherComponent>(ent.Value))
  411. return false;
  412. }
  413. return true;
  414. }
  415. /// <summary>
  416. /// Retrieves the EntityUid of the grid associated with a given map ID.
  417. /// Assumes one grid per map for simplicity.
  418. /// </summary>
  419. private EntityUid? GetGridUidForMap(MapId mapId)
  420. {
  421. var grids = _mapManager.GetAllMapGrids(mapId);
  422. if (grids.Any())
  423. {
  424. return grids.First().Owner;
  425. }
  426. return null;
  427. }
  428. /// <summary>
  429. /// Gets the next season in the cycle.
  430. /// </summary>
  431. private string GetNextSeason(string current)
  432. {
  433. return current switch
  434. {
  435. "Spring" => "Summer",
  436. "Summer" => "Autumn",
  437. "Autumn" => "Winter",
  438. "Winter" => "Spring",
  439. _ => "Spring", // Default to Spring if something goes wrong
  440. };
  441. }
  442. }