minimap_manager.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "minimap_manager.h"
  2. #include <QPainter>
  3. namespace Game::Map::Minimap {
  4. MinimapManager::MinimapManager(const MapDefinition &map_def,
  5. const MinimapManagerConfig &config)
  6. : m_config(config), m_grid(map_def.grid) {
  7. m_generator = std::make_unique<MinimapGenerator>(config.generator_config);
  8. m_base_image = m_generator->generate(map_def);
  9. if (config.fog_enabled) {
  10. m_fog_mask = std::make_unique<FogOfWarMask>(
  11. map_def.grid.width, map_def.grid.height, map_def.grid.tile_size,
  12. config.fog_config);
  13. }
  14. m_composite_dirty = true;
  15. }
  16. MinimapManager::~MinimapManager() = default;
  17. MinimapManager::MinimapManager(MinimapManager &&) noexcept = default;
  18. auto MinimapManager::operator=(MinimapManager &&) noexcept -> MinimapManager & =
  19. default;
  20. void MinimapManager::tick(const std::vector<VisionSource> &vision_sources,
  21. int player_id) {
  22. if (m_fog_mask && m_config.fog_enabled) {
  23. if (m_fog_mask->tick(vision_sources, player_id)) {
  24. m_composite_dirty = true;
  25. }
  26. }
  27. }
  28. void MinimapManager::force_fog_update(
  29. const std::vector<VisionSource> &vision_sources, int player_id) {
  30. if (m_fog_mask && m_config.fog_enabled) {
  31. m_fog_mask->update_vision(vision_sources, player_id);
  32. m_composite_dirty = true;
  33. }
  34. }
  35. auto MinimapManager::get_base_image() const -> const QImage & {
  36. return m_base_image;
  37. }
  38. auto MinimapManager::get_fog_mask() const -> QImage {
  39. if (!m_fog_mask || !m_config.fog_enabled) {
  40. QImage empty(m_base_image.size(), QImage::Format_RGBA8888);
  41. empty.fill(Qt::transparent);
  42. return empty;
  43. }
  44. return m_fog_mask->generate_mask(m_base_image.width(), m_base_image.height());
  45. }
  46. auto MinimapManager::get_composite_image() const -> QImage {
  47. if (m_composite_dirty) {
  48. regenerate_composite();
  49. }
  50. return m_composite_image;
  51. }
  52. auto MinimapManager::get_composite_image(int width,
  53. int height) const -> QImage {
  54. QImage composite = get_composite_image();
  55. if (composite.width() != width || composite.height() != height) {
  56. return composite.scaled(width, height, Qt::KeepAspectRatio,
  57. Qt::SmoothTransformation);
  58. }
  59. return composite;
  60. }
  61. void MinimapManager::regenerate_composite() const {
  62. m_composite_image = m_base_image.copy();
  63. if (m_fog_mask && m_config.fog_enabled) {
  64. QImage fog = m_fog_mask->generate_mask(m_composite_image.width(),
  65. m_composite_image.height());
  66. QPainter painter(&m_composite_image);
  67. if (m_config.fog_multiply_blend) {
  68. painter.setCompositionMode(QPainter::CompositionMode_Multiply);
  69. } else {
  70. painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
  71. }
  72. painter.drawImage(0, 0, fog);
  73. painter.end();
  74. }
  75. m_composite_dirty = false;
  76. if (m_fog_mask) {
  77. m_fog_mask->clear_dirty();
  78. }
  79. }
  80. auto MinimapManager::is_position_visible(float world_x,
  81. float world_z) const -> bool {
  82. if (!m_fog_mask || !m_config.fog_enabled) {
  83. return true;
  84. }
  85. return m_fog_mask->is_visible(world_x, world_z);
  86. }
  87. auto MinimapManager::is_position_revealed(float world_x,
  88. float world_z) const -> bool {
  89. if (!m_fog_mask || !m_config.fog_enabled) {
  90. return true;
  91. }
  92. return m_fog_mask->is_revealed(world_x, world_z);
  93. }
  94. void MinimapManager::reset_fog() {
  95. if (m_fog_mask) {
  96. m_fog_mask->reset();
  97. m_composite_dirty = true;
  98. }
  99. }
  100. void MinimapManager::reveal_all() {
  101. if (m_fog_mask) {
  102. m_fog_mask->reveal_all();
  103. m_composite_dirty = true;
  104. }
  105. }
  106. void MinimapManager::set_fog_enabled(bool enabled) {
  107. if (m_config.fog_enabled != enabled) {
  108. m_config.fog_enabled = enabled;
  109. m_composite_dirty = true;
  110. if (enabled && !m_fog_mask) {
  111. m_fog_mask = std::make_unique<FogOfWarMask>(
  112. m_grid.width, m_grid.height, m_grid.tile_size, m_config.fog_config);
  113. }
  114. }
  115. }
  116. auto MinimapManager::is_fog_enabled() const -> bool {
  117. return m_config.fog_enabled;
  118. }
  119. auto MinimapManager::memory_usage() const -> size_t {
  120. size_t total = sizeof(*this);
  121. total += static_cast<size_t>(m_base_image.sizeInBytes());
  122. total += static_cast<size_t>(m_composite_image.sizeInBytes());
  123. if (m_fog_mask) {
  124. total += m_fog_mask->memory_usage();
  125. }
  126. return total;
  127. }
  128. void MinimapManager::regenerate_base(const MapDefinition &map_def) {
  129. m_grid = map_def.grid;
  130. m_base_image = m_generator->generate(map_def);
  131. if (m_fog_mask) {
  132. m_fog_mask = std::make_unique<FogOfWarMask>(
  133. map_def.grid.width, map_def.grid.height, map_def.grid.tile_size,
  134. m_config.fog_config);
  135. }
  136. m_composite_dirty = true;
  137. }
  138. } // namespace Game::Map::Minimap