From ad632d1e8a30b46cc7b7c013e39e337676f63b4a Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 24 Jun 2014 14:50:27 +0300 Subject: [PATCH] Moved FoW management from CGObjectInstance to callback --- client/Client.h | 3 +++ lib/CGameState.cpp | 2 +- lib/IGameCallback.h | 2 ++ lib/NetPacksLib.cpp | 2 +- lib/mapObjects/CGTownInstance.cpp | 2 +- lib/mapObjects/CObjectHandler.cpp | 30 +----------------------------- lib/mapObjects/CObjectHandler.h | 13 +++---------- lib/mapObjects/MiscObjects.cpp | 7 ++++++- server/CGameHandler.cpp | 26 +++++++++++++++++++++++--- server/CGameHandler.h | 2 ++ 10 files changed, 43 insertions(+), 46 deletions(-) diff --git a/client/Client.h b/client/Client.h index 8ebb49d98..f19410001 100644 --- a/client/Client.h +++ b/client/Client.h @@ -218,6 +218,9 @@ public: void sendAndApply(CPackForClient * info) override {}; void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override {}; + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override {} + void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) override {} + ////////////////////////////////////////////////////////////////////////// friend class CCallback; //handling players actions friend class CBattleCallback; //handling players actions diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 45b1510a0..1de0f422b 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1637,7 +1637,7 @@ void CGameState::initFogOfWar() if(!obj || !vstd::contains(elem.second.players, obj->tempOwner)) continue; //not a flagged object std::unordered_set tiles; - obj->getSightTiles(tiles); + getTilesInRange(tiles, obj->getSightCenter(), obj->getSightRadious(), obj->tempOwner, 1); for(int3 tile : tiles) { elem.second.fogOfWarMap[tile.x][tile.y][tile.z] = 1; diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index e6183e2b2..dda271759 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -93,6 +93,8 @@ public: virtual void sendAndApply(CPackForClient * info)=0; virtual void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)=0; //when two heroes meet on adventure map virtual void addQuest(int player, QuestInfo & quest){}; + virtual void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) = 0; + virtual void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) = 0; }; class DLL_LINKAGE CNonConstInfoCallback : public CPrivilagedInfoCallback diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 50df1a5a9..cfef3489f 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -177,7 +177,7 @@ DLL_LINKAGE void FoWChange::applyGs( CGameState *gs ) case Obj::TOWN: case Obj::ABANDONED_MINE: if(vstd::contains(team->players, o->tempOwner)) //check owned observators - o->getSightTiles(tilesRevealed); + gs->getTilesInRange(tiles, o->getSightCenter(), o->getSightRadious(), o->tempOwner, 1); break; } } diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 2e0e1b8a4..48bd08f0c 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1007,7 +1007,7 @@ void CGTownInstance::battleFinished(const CGHeroInstance *hero, const BattleResu FoWChange fw; fw.player = hero->tempOwner; fw.mode = 1; - getSightTiles (fw.tiles); //update visibility for castle structures + cb->getTilesInRange(fw.tiles, getSightCenter(), getSightRadious(), tempOwner, 1); cb->sendAndApply (&fw); } } diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 8c138a86d..5d00cce34 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -246,42 +246,14 @@ void CGObjectInstance::setPropertyDer( ui8 what, ui32 val ) int3 CGObjectInstance::getSightCenter() const { - //return vistiable tile if possible - for(int i=0; i < 8; i++) - for(int j=0; j < 6; j++) - if(visitableAt(i,j)) - return(pos + int3(i-7, j-5, 0)); - return pos; + return visitablePos(); } int CGObjectInstance::getSightRadious() const { return 3; } -void CGObjectInstance::getSightTiles(std::unordered_set &tiles) const //returns reference to the set -{ - cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1); -} -void CGObjectInstance::hideTiles(PlayerColor ourplayer, int radius) const -{ - for (auto i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++) - { - if ( !vstd::contains(i->second.players, ourplayer ))//another team - { - for (auto & elem : i->second.players) - if ( cb->getPlayer(elem)->status == EPlayerStatus::INGAME )//seek for living player (if any) - { - FoWChange fw; - fw.mode = 0; - fw.player = elem; - cb->getTilesInRange (fw.tiles, pos, radius, (elem), -1); - cb->sendAndApply (&fw); - break; - } - } - } -} int3 CGObjectInstance::getVisitableOffset() const { for(int y = 0; y < appearance.getHeight(); y++) diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index 90d890dc6..3ebb74a65 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -121,7 +121,7 @@ public: PlayerColor getOwner() const; void setOwner(PlayerColor ow); - /// APPEARANCE ACCESSORS /// + /** APPEARANCE ACCESSORS **/ int getWidth() const; //returns width of object graphic in tiles int getHeight() const; //returns height of object graphic in tiles @@ -133,14 +133,7 @@ public: std::set getBlockedOffsets() const; //returns set of relative positions blocked by this object bool isVisitable() const; //returns true if object is visitable - /// HELPERS THAT SHOULD BE REMOVED /// - - /// fills set with tiles which are visible from this object. TODO: remove? - void getSightTiles(std::unordered_set &tiles) const; - /// Hides tiles visible for any player but ours. TODO: move to callback/game state? - void hideTiles(PlayerColor ourplayer, int radius) const; - - /// VIRTUAL METHODS /// + /** VIRTUAL METHODS **/ /// Returns true if player can pass through visitable tiles of this object virtual bool passableFor(PlayerColor color) const; @@ -154,7 +147,7 @@ public: /// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman") virtual void setType(si32 ID, si32 subID); - ///IObjectInterface OVERRIDES + /** OVERRIDES OF IObjectInterface **/ void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 7674a8ece..d5136a697 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1048,7 +1048,12 @@ void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const case Obj::COVER_OF_DARKNESS: { iw.text.addTxt (MetaString::ADVOB_TXT, 31); - hideTiles(h->tempOwner, 20); + for (auto player : cb->gameState()->players) + { + if (cb->getPlayerStatus(player.first) == EPlayerStatus::INGAME && + cb->getPlayerRelations(player.first, h->tempOwner) == PlayerRelations::ENEMIES) + cb->changeFogOfWar(visitablePos(), 20, player.first, true); + } break; } } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 98255ea42..de78ebab4 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1351,9 +1351,13 @@ void CGameHandler::newTurn() } if (t->hasBonusOfType (Bonus::DARKNESS)) { - t->hideTiles(t->getOwner(), t->getBonusLocalFirst(Selector::type(Bonus::DARKNESS))->val); + for (auto player : gameState()->players) + { + if (getPlayerStatus(player.first) == EPlayerStatus::INGAME && + getPlayerRelations(player.first, t->tempOwner) == PlayerRelations::ENEMIES) + changeFogOfWar(t->visitablePos(), t->getBonusLocalFirst(Selector::type(Bonus::DARKNESS))->val, player.first, true); + } } - //unhiding what shouldn't be hidden? //that's handled in netpacks client } if(newMonth) @@ -2523,7 +2527,7 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID, FoWChange fw; fw.player = t->tempOwner; fw.mode = 1; - t->getSightTiles(fw.tiles); + getTilesInRange(fw.tiles, t->getSightCenter(), t->getSightRadious(), t->tempOwner, 1); sendAndApply(&fw); if(t->visitingHero) @@ -6252,6 +6256,22 @@ void CGameHandler::removeAfterVisit(const CGObjectInstance *object) assert("This function needs to be called during the object visit!"); } +void CGameHandler::changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) +{ + std::unordered_set tiles; + getTilesInRange(tiles, center, radius, player, hide? -1 : 1); + changeFogOfWar(tiles, player, hide); +} + +void CGameHandler::changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) +{ + FoWChange fow; + fow.tiles = tiles; + fow.player = player; + fow.mode = hide? 0 : 1; + sendAndApply(&fow); +} + bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) { if(auto topQuery = queries.topQuery(hero->getOwner())) diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 36798d519..e09dd9152 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -174,6 +174,8 @@ public: void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) override; void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override; + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override; + void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) override; bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override;