diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index 2c5ec4c194..4fca628d99 100644 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -135,7 +135,7 @@ static std::map ParabolicRangesOutline */ struct EntityData { - EntityData() : retainInFog(0), owner(-1), inWorld(0), flags(1) { } + EntityData() : visibilities(0), retainInFog(0), owner(-1), inWorld(0), flags(1) { } entity_pos_t x, z; entity_pos_t visionRange; u32 visibilities; // 2-bit visibility, per player @@ -197,8 +197,8 @@ struct SerializeEntityData serialize.NumberFixed_Unbounded("x", value.x); serialize.NumberFixed_Unbounded("z", value.z); serialize.NumberFixed_Unbounded("vision", value.visionRange); - serialize.NumberU8("retain in fog", value.retainInFog, 0, 1); serialize.NumberU32_Unbounded("visibilities", value.visibilities); + serialize.NumberU8("retain in fog", value.retainInFog, 0, 1); serialize.NumberI8_Unbounded("owner", value.owner); serialize.NumberU8("in world", value.inWorld, 0, 1); serialize.NumberU8_Unbounded("flags", value.flags); @@ -288,7 +288,7 @@ public: // Cache for visibility tracking (not serialized) i32 m_LosTilesPerSide; - bool* m_DirtyVisibility; + std::vector m_DirtyVisibility; std::vector > m_LosTiles; // List of entities that must be updated, regardless of the status of their tile std::vector m_ModifiedEntities; @@ -341,14 +341,11 @@ public: m_LosCircular = false; m_TerrainVerticesPerSide = 0; - m_DirtyVisibility = NULL; - m_TerritoriesDirtyID = 0; } virtual void Deinit() { - delete[] m_DirtyVisibility; } template @@ -567,9 +564,9 @@ public: case MT_Update: { m_DebugOverlayDirty = true; - UpdateVisibilityData(); UpdateTerritoriesLos(); ExecuteActiveQueries(); + UpdateVisibilityData(); break; } case MT_RenderSubmit: @@ -674,8 +671,8 @@ public: m_LosStateRevealed.clear(); m_LosStateRevealed.resize(m_TerrainVerticesPerSide*m_TerrainVerticesPerSide); - delete[] m_DirtyVisibility; - m_DirtyVisibility = new bool[m_LosTilesPerSide*m_LosTilesPerSide](); + m_DirtyVisibility.clear(); + m_DirtyVisibility.resize(m_LosTilesPerSide*m_LosTilesPerSide, 1); m_LosTiles.clear(); m_LosTiles.resize(m_LosTilesPerSide*m_LosTilesPerSide); @@ -1379,7 +1376,9 @@ public: virtual ELosVisibility GetLosVisibility(CEntityHandle ent, player_id_t player, bool forceRetainInFog) { - // (We can't use m_EntityData since this needs to handle LOCAL entities too) + // This function provides the real visibility of any entity (even local ones) at any time. + // The m_EntityData visibility is updated at most once per turn with this function's return value + // and must not be used for rendering // Entities not with positions in the world are never visible if (ent.GetId() == INVALID_ENTITY) @@ -1464,7 +1463,7 @@ public: for (i32 n = 0; n < m_LosTilesPerSide*m_LosTilesPerSide; ++n) { - if (m_DirtyVisibility[n]) + if (m_DirtyVisibility[n] == 1) { for (std::set::iterator it = m_LosTiles[n].begin(); it != m_LosTiles[n].end(); @@ -1472,7 +1471,7 @@ public: { UpdateVisibility(*it); } - m_DirtyVisibility[n] = false; + m_DirtyVisibility[n] = 0; } } @@ -1491,14 +1490,14 @@ public: for (player_id_t player = 1; player <= MAX_LOS_PLAYER_ID; ++player) { - u8 oldVis = (itEnts->second.visibilities >> (2*player)) & 0x3; + u8 oldVis = (itEnts->second.visibilities >> (2*(player-1))) & 0x3; u8 newVis = GetLosVisibility(itEnts->first, player, false); if (oldVis != newVis) { CMessageVisibilityChanged msg(player, ent, oldVis, newVis); GetSimContext().GetComponentManager().PostMessage(ent, msg); - itEnts->second.visibilities = (itEnts->second.visibilities & ~(0x3 << 2*player)) | (newVis << 2*player); + itEnts->second.visibilities = (itEnts->second.visibilities & ~(0x3 << 2*(player-1))) | (newVis << 2*(player-1)); } } } @@ -1650,7 +1649,7 @@ public: explored += !(m_LosState[idx] & (LOS_EXPLORED << (2*(owner-1)))); m_LosState[idx] |= ((LOS_VISIBLE | LOS_EXPLORED) << (2*(owner-1))); } - m_DirtyVisibility[(j/LOS_TILES_RATIO)*m_LosTilesPerSide + i/LOS_TILES_RATIO] = true; + m_DirtyVisibility[(j/LOS_TILES_RATIO)*m_LosTilesPerSide + i/LOS_TILES_RATIO] = 1; } ASSERT(counts[idx] < 65535); @@ -1680,7 +1679,7 @@ public: m_LosState[idx] &= ~(LOS_VISIBLE << (2*(owner-1))); i32 i = i0 + idx - idx0; - m_DirtyVisibility[(j/LOS_TILES_RATIO)*m_LosTilesPerSide + i/LOS_TILES_RATIO] = true; + m_DirtyVisibility[(j/LOS_TILES_RATIO)*m_LosTilesPerSide + i/LOS_TILES_RATIO] = 1; } } }