diff --git a/binaries/data/mods/public/simulation/components/Fogging.js b/binaries/data/mods/public/simulation/components/Fogging.js index 87e6907f03..5249af610f 100644 --- a/binaries/data/mods/public/simulation/components/Fogging.js +++ b/binaries/data/mods/public/simulation/components/Fogging.js @@ -106,6 +106,12 @@ Fogging.prototype.LoadMirage = function(player) ); }; +Fogging.prototype.ForceMiraging = function(player) +{ + this.seen[player] = true; + this.LoadMirage(player); +}; + Fogging.prototype.IsMiraged = function(player) { if (player >= this.mirages.length) diff --git a/binaries/data/mods/public/simulation/helpers/InitGame.js b/binaries/data/mods/public/simulation/helpers/InitGame.js index 62dcbc2e51..b345ee683e 100644 --- a/binaries/data/mods/public/simulation/helpers/InitGame.js +++ b/binaries/data/mods/public/simulation/helpers/InitGame.js @@ -9,6 +9,20 @@ function ReplaceSkirmishGlobals() function InitGame(settings) { + if (settings.ExploreMap) + { + var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + if (cmpRangeManager) + for (var i = 0; i < settings.PlayerData.length; i++) + cmpRangeManager.ExploreAllTiles(i+1); + } + else + { + // Explore the map only inside the players' territory borders + var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + cmpRangeManager.ExploreTerritories(); + } + // No settings when loading a map in Atlas, so do nothing if (!settings) return; diff --git a/binaries/data/mods/public/simulation/helpers/Setup.js b/binaries/data/mods/public/simulation/helpers/Setup.js index 7d22983a4c..0d7a012a8f 100644 --- a/binaries/data/mods/public/simulation/helpers/Setup.js +++ b/binaries/data/mods/public/simulation/helpers/Setup.js @@ -36,16 +36,6 @@ function LoadMapSettings(settings) cmpObstructionManager.SetPassabilityCircular(true); } - if (settings.ExploreMap) - { - // this needs to happen after changing the map to a circular one - // as by making the map circular, the explored tiles get reset - var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - if (cmpRangeManager) - for (var i = 0; i < settings.PlayerData.length; i++) - cmpRangeManager.ExploreAllTiles(i+1); - } - var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); if (settings.GameType) cmpEndGameManager.SetGameType(settings.GameType); diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index af64223c51..bab2c450a2 100644 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -287,7 +287,6 @@ public: std::vector m_LosRevealAll; bool m_LosCircular; i32 m_TerrainVerticesPerSide; - size_t m_TerritoriesDirtyID; // Cache for visibility tracking (not serialized) i32 m_LosTilesPerSide; @@ -343,8 +342,6 @@ public: m_LosCircular = false; m_TerrainVerticesPerSide = 0; - - m_TerritoriesDirtyID = 0; } virtual void Deinit() @@ -1603,13 +1600,13 @@ public: m_LosState[i + j*m_TerrainVerticesPerSide] |= (LOS_EXPLORED << (2*(p-1))); } } + + SeeExploredEntities(p); } - void UpdateTerritoriesLos() + virtual void ExploreTerritories() { CmpPtr cmpTerritoryManager(GetSystemEntity()); - if (!cmpTerritoryManager || !cmpTerritoryManager->NeedUpdate(&m_TerritoriesDirtyID)) - return; const Grid& grid = cmpTerritoryManager->GetTerritoryGrid(); ENSURE(grid.m_W == m_TerrainVerticesPerSide-1 && grid.m_H == m_TerrainVerticesPerSide-1); @@ -1636,6 +1633,36 @@ public: } } } + + for (player_id_t p = 1; p < MAX_LOS_PLAYER_ID+1; ++p) + SeeExploredEntities(p); + } + + /** + * Force any entity in explored territory to appear for player p. + * This is useful for miraging entities inside the territory borders at the beginning of a game, + * or if the "Explore Map" option has been set. + */ + void SeeExploredEntities(player_id_t p) + { + for (EntityMap::iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it) + { + CmpPtr cmpPosition(GetSimContext(), it->first); + if (!cmpPosition || !cmpPosition->IsInWorld()) + continue; + + CFixedVector2D pos = cmpPosition->GetPosition2D(); + int i = (pos.X / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNearest(); + int j = (pos.Y / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNearest(); + + CLosQuerier los(GetSharedLosMask(p), m_LosState, m_TerrainVerticesPerSide); + if (!los.IsExplored(i,j) || los.IsVisible(i,j)) + continue; + + CmpPtr cmpFogging(GetSimContext(), it->first); + if (cmpFogging) + cmpFogging->ForceMiraging(p); + } } /** diff --git a/source/simulation2/components/ICmpFogging.cpp b/source/simulation2/components/ICmpFogging.cpp index a981adb187..083e8bede3 100644 --- a/source/simulation2/components/ICmpFogging.cpp +++ b/source/simulation2/components/ICmpFogging.cpp @@ -39,6 +39,11 @@ public: { return m_Script.Call("IsMiraged", player); } + + virtual void ForceMiraging(player_id_t player) + { + return m_Script.CallVoid("ForceMiraging", player); + } }; REGISTER_COMPONENT_SCRIPT_WRAPPER(FoggingScripted) diff --git a/source/simulation2/components/ICmpFogging.h b/source/simulation2/components/ICmpFogging.h index cd759f601d..e8ea51a3e0 100644 --- a/source/simulation2/components/ICmpFogging.h +++ b/source/simulation2/components/ICmpFogging.h @@ -32,6 +32,7 @@ class ICmpFogging : public IComponent public: virtual bool WasSeen(player_id_t player) = 0; virtual bool IsMiraged(player_id_t player) = 0; + virtual void ForceMiraging(player_id_t player) = 0; DECLARE_INTERFACE_TYPE(Fogging) }; diff --git a/source/simulation2/components/ICmpRangeManager.cpp b/source/simulation2/components/ICmpRangeManager.cpp index 095032537c..99edb7e0f7 100644 --- a/source/simulation2/components/ICmpRangeManager.cpp +++ b/source/simulation2/components/ICmpRangeManager.cpp @@ -47,6 +47,7 @@ DEFINE_INTERFACE_METHOD_1("GetEntityFlagMask", u8, ICmpRangeManager, GetEntityFl DEFINE_INTERFACE_METHOD_1("GetEntitiesByPlayer", std::vector, ICmpRangeManager, GetEntitiesByPlayer, player_id_t) DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOverlay, bool) DEFINE_INTERFACE_METHOD_1("ExploreAllTiles", void, ICmpRangeManager, ExploreAllTiles, player_id_t) +DEFINE_INTERFACE_METHOD_0("ExploreTerritories", void, ICmpRangeManager, ExploreTerritories) DEFINE_INTERFACE_METHOD_2("SetLosRevealAll", void, ICmpRangeManager, SetLosRevealAll, player_id_t, bool) DEFINE_INTERFACE_METHOD_1("GetLosRevealAll", bool, ICmpRangeManager, GetLosRevealAll, player_id_t) DEFINE_INTERFACE_METHOD_5("GetElevationAdaptedRange", entity_pos_t, ICmpRangeManager, GetElevationAdaptedRange, CFixedVector3D, CFixedVector3D, entity_pos_t, entity_pos_t, entity_pos_t) diff --git a/source/simulation2/components/ICmpRangeManager.h b/source/simulation2/components/ICmpRangeManager.h index f977ce10aa..4f4545899f 100644 --- a/source/simulation2/components/ICmpRangeManager.h +++ b/source/simulation2/components/ICmpRangeManager.h @@ -338,6 +338,12 @@ public: */ virtual void ExploreAllTiles(player_id_t p) = 0; + /** + * Explore the tiles inside each player's territory. + * This is done only at the beginning of the game. + */ + virtual void ExploreTerritories() = 0; + /** * Set whether the whole map should be made visible to the given player. * If player is -1, the map will be made visible to all players.