rain_manager.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "rain_manager.h"
  2. #include <algorithm>
  3. namespace Game::Systems {
  4. RainManager::RainManager() = default;
  5. void RainManager::configure(const Game::Map::RainSettings &settings,
  6. std::uint32_t map_seed) {
  7. m_settings = settings;
  8. m_seed = map_seed;
  9. reset();
  10. }
  11. void RainManager::reset() {
  12. m_state = RainState::Clear;
  13. m_current_intensity = 0.0F;
  14. m_state_time = 0.0F;
  15. if (m_settings.enabled && m_seed != 0 && m_settings.cycle_duration >= 1.0F) {
  16. const auto cycle_ms = static_cast<std::uint32_t>(
  17. std::max(1.0F, m_settings.cycle_duration) * 1000.0F);
  18. m_cycle_time = static_cast<float>(m_seed % cycle_ms) / 1000.0F;
  19. } else {
  20. m_cycle_time = 0.0F;
  21. }
  22. }
  23. void RainManager::update(float delta_time) {
  24. if (!m_settings.enabled) {
  25. return;
  26. }
  27. m_cycle_time += delta_time;
  28. if (m_cycle_time >= m_settings.cycle_duration) {
  29. m_cycle_time -= m_settings.cycle_duration;
  30. }
  31. const float rain_start = 0.0F;
  32. const float rain_end = m_settings.active_duration;
  33. const float effective_fade =
  34. std::min(m_settings.fade_duration, m_settings.active_duration / 2.0F);
  35. const float fade_in_end = rain_start + effective_fade;
  36. const float fade_out_start = std::max(fade_in_end, rain_end - effective_fade);
  37. RainState target_state = RainState::Clear;
  38. if (m_cycle_time >= rain_start && m_cycle_time < rain_end) {
  39. if (m_cycle_time < fade_in_end) {
  40. target_state = RainState::FadingIn;
  41. } else if (m_cycle_time >= fade_out_start) {
  42. target_state = RainState::FadingOut;
  43. } else {
  44. target_state = RainState::Active;
  45. }
  46. } else {
  47. target_state = RainState::Clear;
  48. }
  49. if (target_state != m_state) {
  50. transition_to(target_state);
  51. if (target_state == RainState::FadingIn) {
  52. m_state_time = m_cycle_time - rain_start;
  53. } else if (target_state == RainState::FadingOut) {
  54. m_state_time = m_cycle_time - fade_out_start;
  55. } else if (target_state == RainState::Active) {
  56. m_state_time = m_cycle_time - fade_in_end;
  57. }
  58. } else {
  59. m_state_time += delta_time;
  60. }
  61. update_intensity(delta_time);
  62. }
  63. void RainManager::transition_to(RainState new_state) {
  64. m_state = new_state;
  65. m_state_time = 0.0F;
  66. if (m_state_callback) {
  67. m_state_callback(new_state);
  68. }
  69. }
  70. void RainManager::update_intensity(float) {
  71. switch (m_state) {
  72. case RainState::Clear:
  73. m_current_intensity = 0.0F;
  74. break;
  75. case RainState::FadingIn: {
  76. const float progress = std::min(
  77. 1.0F, m_state_time / std::max(0.001F, m_settings.fade_duration));
  78. m_current_intensity = progress * m_settings.intensity;
  79. break;
  80. }
  81. case RainState::Active:
  82. m_current_intensity = m_settings.intensity;
  83. break;
  84. case RainState::FadingOut: {
  85. const float progress = std::min(
  86. 1.0F, m_state_time / std::max(0.001F, m_settings.fade_duration));
  87. m_current_intensity = (1.0F - progress) * m_settings.intensity;
  88. break;
  89. }
  90. }
  91. }
  92. } // namespace Game::Systems