Browse Source

Fix camera viewport overlay stacking on minimap

Co-authored-by: djeada <[email protected]>
copilot-swe-agent[bot] 3 days ago
parent
commit
0079a067a5
2 changed files with 20 additions and 9 deletions
  1. 19 9
      app/core/minimap_manager.cpp
  2. 1 0
      app/core/minimap_manager.h

+ 19 - 9
app/core/minimap_manager.cpp

@@ -34,6 +34,10 @@ void MinimapManager::generate_for_map(const Game::Map::MapDefinition &map_def) {
     m_world_height = static_cast<float>(map_def.grid.height);
     m_tile_size = map_def.grid.tile_size;
 
+    // Initialize fog image with a copy of the base image
+    m_minimap_fog_image = m_minimap_base_image.copy();
+    m_minimap_image = m_minimap_fog_image.copy();
+
     m_unit_layer = std::make_unique<Game::Map::Minimap::UnitLayer>();
     m_unit_layer->init(m_minimap_base_image.width(),
                        m_minimap_base_image.height(), m_world_width,
@@ -68,14 +72,16 @@ void MinimapManager::update_fog(float dt, int local_owner_id) {
 
   auto &visibility_service = Game::Map::VisibilityService::instance();
   if (!visibility_service.is_initialized()) {
-    if (m_minimap_image != m_minimap_base_image) {
-      m_minimap_image = m_minimap_base_image;
+    if (m_minimap_fog_image.isNull() ||
+        m_minimap_fog_image.size() != m_minimap_base_image.size()) {
+      m_minimap_fog_image = m_minimap_base_image.copy();
     }
     return;
   }
 
   const auto current_version = visibility_service.version();
-  if (current_version == m_minimap_fog_version && !m_minimap_image.isNull()) {
+  if (current_version == m_minimap_fog_version &&
+      !m_minimap_fog_image.isNull()) {
     return;
   }
   m_minimap_fog_version = current_version;
@@ -85,14 +91,14 @@ void MinimapManager::update_fog(float dt, int local_owner_id) {
   const auto cells = visibility_service.snapshotCells();
 
   if (cells.empty() || vis_width <= 0 || vis_height <= 0) {
-    m_minimap_image = m_minimap_base_image;
+    m_minimap_fog_image = m_minimap_base_image.copy();
     return;
   }
 
-  m_minimap_image = m_minimap_base_image.copy();
+  m_minimap_fog_image = m_minimap_base_image.copy();
 
-  const int img_width = m_minimap_image.width();
-  const int img_height = m_minimap_image.height();
+  const int img_width = m_minimap_fog_image.width();
+  const int img_height = m_minimap_fog_image.height();
 
   constexpr float k_inv_cos = -0.70710678118F;
   constexpr float k_inv_sin = 0.70710678118F;
@@ -134,7 +140,7 @@ void MinimapManager::update_fog(float dt, int local_owner_id) {
   const float half_vis_h = static_cast<float>(vis_height) * 0.5F;
 
   for (int y = 0; y < img_height; ++y) {
-    auto *scanline = reinterpret_cast<QRgb *>(m_minimap_image.scanLine(y));
+    auto *scanline = reinterpret_cast<QRgb *>(m_minimap_fog_image.scanLine(y));
 
     for (int x = 0; x < img_width; ++x) {
       const float centered_x = static_cast<float>(x) - half_img_w;
@@ -185,10 +191,14 @@ void MinimapManager::update_fog(float dt, int local_owner_id) {
 void MinimapManager::update_units(
     Engine::Core::World *world,
     Game::Systems::SelectionSystem *selection_system) {
-  if (m_minimap_image.isNull() || !m_unit_layer || !world) {
+  if (m_minimap_fog_image.isNull() || !m_unit_layer || !world) {
     return;
   }
 
+  // Always start with a fresh copy of the fog-processed base image
+  // to prevent overlays (units, camera viewport) from accumulating
+  m_minimap_image = m_minimap_fog_image.copy();
+
   std::vector<Game::Map::Minimap::UnitMarker> markers;
 
   constexpr size_t EXPECTED_MAX_UNITS = 128;

+ 1 - 0
app/core/minimap_manager.h

@@ -45,6 +45,7 @@ public:
 private:
   QImage m_minimap_image;
   QImage m_minimap_base_image;
+  QImage m_minimap_fog_image;
   std::uint64_t m_minimap_fog_version = 0;
   std::unique_ptr<Game::Map::Minimap::UnitLayer> m_unit_layer;
   std::unique_ptr<Game::Map::Minimap::CameraViewportLayer> m_camera_viewport_layer;