diff --git a/client/Client.h b/client/Client.h index b9c98768b..86538827c 100644 --- a/client/Client.h +++ b/client/Client.h @@ -209,8 +209,8 @@ public: void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override {}; void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) override {}; - void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override {} - void changeFogOfWar(std::unordered_set & tiles, PlayerColor player, bool hide) override {} + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) override {} + void changeFogOfWar(std::unordered_set & tiles, PlayerColor player, ETileVisibility mode) override {} void setObjProperty(ObjectInstanceID objid, int prop, si64 val) override {} diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index affbdf49e..483bb1126 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -177,7 +177,7 @@ void ApplyClientNetPackVisitor::visitFoWChange(FoWChange & pack) } if(cl.getPlayerRelations(i.first, pack.player) != PlayerRelations::ENEMIES) { - if(pack.mode == FoWChange::Mode::REVEAL) + if(pack.mode == ETileVisibility::REVEALED) i.second->tileRevealed(pack.tiles); else i.second->tileHidden(pack.tiles); diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp index 45b72a8b4..2be582779 100644 --- a/lib/CGameInfoCallback.cpp +++ b/lib/CGameInfoCallback.cpp @@ -942,7 +942,7 @@ bool CGameInfoCallback::isInTheMap(const int3 &pos) const void CGameInfoCallback::getVisibleTilesInRange(std::unordered_set &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula) const { - gs->getTilesInRange(tiles, pos, radious, *getPlayerID(), -1, distanceFormula); + gs->getTilesInRange(tiles, pos, radious, ETileVisibility::REVEALED, *getPlayerID(), distanceFormula); } void CGameInfoCallback::calculatePaths(const std::shared_ptr & config) @@ -955,7 +955,6 @@ void CGameInfoCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo & gs->calculatePaths(hero, out); } - const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID aid ) const { return gs->map->artInstances[aid.num]; diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 55ceaf9cd..673f8cfa7 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -78,8 +78,8 @@ void CPrivilegedInfoCallback::getFreeTiles(std::vector & tiles) const void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set & tiles, const int3 & pos, int radious, + ETileVisibility mode, std::optional player, - int mode, int3::EDistanceFormula distanceFormula) const { if(!!player && !player->isValidPlayer()) @@ -102,8 +102,8 @@ void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set & tiles, if(distance <= radious) { if(!player - || (mode == 1 && (*team->fogOfWarMap)[pos.z][xd][yd] == 0) - || (mode == -1 && (*team->fogOfWarMap)[pos.z][xd][yd] == 1) + || (mode == ETileVisibility::HIDDEN && (*team->fogOfWarMap)[pos.z][xd][yd] == 0) + || (mode == ETileVisibility::REVEALED && (*team->fogOfWarMap)[pos.z][xd][yd] == 1) ) tiles.insert(int3(xd,yd,pos.z)); } diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index e1f82f87c..33d7737bf 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -51,9 +51,9 @@ public: //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only revealed void getTilesInRange(std::unordered_set & tiles, const int3 & pos, - int radious, + int radius, + ETileVisibility mode, std::optional player = std::optional(), - int mode = 0, int3::EDistanceFormula formula = int3::DIST_2D) const; //returns all tiles on given level (-1 - both levels, otherwise number of level) @@ -125,8 +125,8 @@ public: virtual void changeObjPos(ObjectInstanceID objid, int3 newPos, const PlayerColor & initiator)=0; virtual void sendAndApply(CPackForClient * pack) = 0; virtual void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)=0; //when two heroes meet on adventure map - virtual void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) = 0; - virtual void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) = 0; + virtual void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) = 0; + virtual void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, ETileVisibility mode) = 0; virtual void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) = 0; }; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 017cc0118..6bc6e3f9d 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -344,17 +344,11 @@ struct DLL_LINKAGE SetMovePoints : public CPackForClient struct DLL_LINKAGE FoWChange : public CPackForClient { - enum class Mode : uint8_t - { - HIDE, - REVEAL - }; - void applyGs(CGameState * gs); std::unordered_set tiles; PlayerColor player; - Mode mode; + ETileVisibility mode; bool waitForDialogs = false; virtual void visitTyped(ICPackVisitor & visitor) override; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 65d4878af..5dddc2ff4 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -924,9 +924,9 @@ void FoWChange::applyGs(CGameState *gs) TeamState * team = gs->getPlayerTeam(player); auto fogOfWarMap = team->fogOfWarMap; for(const int3 & t : tiles) - (*fogOfWarMap)[t.z][t.x][t.y] = mode != Mode::HIDE; + (*fogOfWarMap)[t.z][t.x][t.y] = mode != ETileVisibility::HIDDEN; - if (mode == Mode::HIDE) //do not hide too much + if (mode == ETileVisibility::HIDDEN) //do not hide too much { std::unordered_set tilesRevealed; for (auto & elem : gs->map->objects) @@ -941,7 +941,7 @@ void FoWChange::applyGs(CGameState *gs) case Obj::TOWN: case Obj::ABANDONED_MINE: if(vstd::contains(team->players, o->tempOwner)) //check owned observators - gs->getTilesInRange(tilesRevealed, o->getSightCenter(), o->getSightRadius(), o->tempOwner, 1); + gs->getTilesInRange(tilesRevealed, o->getSightCenter(), o->getSightRadius(), ETileVisibility::HIDDEN, o->tempOwner); break; } } diff --git a/lib/constants/Enumerations.h b/lib/constants/Enumerations.h index 1c2cd7b06..c594cc271 100644 --- a/lib/constants/Enumerations.h +++ b/lib/constants/Enumerations.h @@ -250,4 +250,10 @@ enum class EBattleResult : int8_t SURRENDER = 2, }; +enum class ETileVisibility : int8_t // Fog of war change +{ + HIDDEN, + REVEALED +}; + VCMI_LIB_NAMESPACE_END diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index ffdd990df..87f8fac92 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -939,7 +939,7 @@ void CGameState::initFogOfWar() if(!obj || !vstd::contains(elem.second.players, obj->tempOwner)) continue; //not a flagged object std::unordered_set tiles; - getTilesInRange(tiles, obj->getSightCenter(), obj->getSightRadius(), obj->tempOwner, 1); + getTilesInRange(tiles, obj->getSightCenter(), obj->getSightRadius(), ETileVisibility::HIDDEN, obj->tempOwner); for(const int3 & tile : tiles) { (*elem.second.fogOfWarMap)[tile.z][tile.x][tile.y] = 1; diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 78c4399ba..36543e448 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1066,11 +1066,7 @@ void CGTownInstance::battleFinished(const CGHeroInstance * hero, const BattleRes void CGTownInstance::onTownCaptured(const PlayerColor & winner) const { setOwner(winner); - FoWChange fw; - fw.player = winner; - fw.mode = FoWChange::Mode::REVEAL; - cb->getTilesInRange(fw.tiles, getSightCenter(), getSightRadius(), winner, 1); - cb->sendAndApply(& fw); + cb->changeFogOfWar(getSightCenter(), getSightRadius(), winner, ETileVisibility::REVEALED); } void CGTownInstance::afterAddToMap(CMap * map) diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 36f7fd91a..26c1d0e38 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1141,14 +1141,14 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const FoWChange fw; fw.player = h->tempOwner; - fw.mode = FoWChange::Mode::REVEAL; + fw.mode = ETileVisibility::REVEALED; fw.waitForDialogs = true; for(const auto & it : eyelist[subID]) { const CGObjectInstance *eye = cb->getObj(it); - cb->getTilesInRange (fw.tiles, eye->pos, 10, h->tempOwner, 1); + cb->getTilesInRange (fw.tiles, eye->pos, 10, ETileVisibility::HIDDEN, h->tempOwner); cb->sendAndApply(&fw); cv.pos = eye->pos; diff --git a/lib/pathfinder/CPathfinder.cpp b/lib/pathfinder/CPathfinder.cpp index 8044535fb..c5d8cf9a3 100644 --- a/lib/pathfinder/CPathfinder.cpp +++ b/lib/pathfinder/CPathfinder.cpp @@ -368,7 +368,7 @@ void CPathfinderHelper::initializePatrol() if(hero->patrol.patrolRadius) { state = PATROL_RADIUS; - gs->getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, std::optional(), 0, int3::DIST_MANHATTAN); + gs->getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, ETileVisibility::REVEALED, std::optional(), int3::DIST_MANHATTAN); } else state = PATROL_LOCKED; diff --git a/lib/rewardable/Interface.cpp b/lib/rewardable/Interface.cpp index f13a4a5a5..31b5a74e4 100644 --- a/lib/rewardable/Interface.cpp +++ b/lib/rewardable/Interface.cpp @@ -49,17 +49,17 @@ void Rewardable::Interface::grantRewardBeforeLevelup(IGameCallback * cb, const R if (info.reward.revealTiles) { - auto const & props = *info.reward.revealTiles; + const auto & props = *info.reward.revealTiles; FoWChange fw; if (props.hide) - fw.mode = FoWChange::Mode::HIDE; + fw.mode = ETileVisibility::HIDDEN; else - fw.mode = FoWChange::Mode::REVEAL; + fw.mode = ETileVisibility::REVEALED; fw.player = hero->tempOwner; - auto const functor = [&props](const TerrainTile * tile) + const auto functor = [&props](const TerrainTile * tile) { int score = 0; if (tile->terType->isSurface()) @@ -79,9 +79,9 @@ void Rewardable::Interface::grantRewardBeforeLevelup(IGameCallback * cb, const R if (props.radius > 0) { - cb->getTilesInRange(fw.tiles, hero->getSightCenter(), props.radius, hero->tempOwner, 1); + cb->getTilesInRange(fw.tiles, hero->getSightCenter(), props.radius, ETileVisibility::HIDDEN, hero->tempOwner); vstd::erase_if(fw.tiles, [&](const int3 & coord){ - return functor(cb->getTile(coord)); + return !functor(cb->getTile(coord)); }); } else diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 8653120b0..fec358bf8 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -858,7 +858,7 @@ void CGameHandler::onNewTurn() if (player != PlayerColor::NEUTRAL) //do not reveal fow for neutral player { FoWChange fw; - fw.mode = FoWChange::Mode::REVEAL; + fw.mode = ETileVisibility::REVEALED; fw.player = player; // find all hidden tiles const auto fow = getPlayerTeam(player)->fogOfWarMap; @@ -879,7 +879,7 @@ void CGameHandler::onNewTurn() { if (getPlayerStatus(player.first) == EPlayerStatus::INGAME && getPlayerRelations(player.first, t->tempOwner) == PlayerRelations::ENEMIES) - changeFogOfWar(t->visitablePos(), t->getBonusLocalFirst(Selector::type()(BonusType::DARKNESS))->val, player.first, true); + changeFogOfWar(t->visitablePos(), t->getBonusLocalFirst(Selector::type()(BonusType::DARKNESS))->val, player.first, ETileVisibility::HIDDEN); } } } @@ -1174,7 +1174,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo { obj->onHeroLeave(h); } - this->getTilesInRange(tmh.fowRevealed, h->getSightCenter()+(tmh.end-tmh.start), h->getSightRadius(), h->tempOwner, 1); + this->getTilesInRange(tmh.fowRevealed, h->getSightCenter()+(tmh.end-tmh.start), h->getSightRadius(), ETileVisibility::HIDDEN, h->tempOwner); }; auto doMove = [&](TryMoveHero::EResult result, EGuardLook lookForGuards, @@ -1523,7 +1523,7 @@ void CGameHandler::giveHero(ObjectInstanceID id, PlayerColor player, ObjectInsta //Reveal fow around new hero, especially released from Prison auto h = getHero(id); - changeFogOfWar(h->pos, h->getSightRadius(), player, false); + changeFogOfWar(h->pos, h->getSightRadius(), player, ETileVisibility::REVEALED); } void CGameHandler::changeObjPos(ObjectInstanceID objid, int3 newPos, const PlayerColor & initiator) @@ -2387,11 +2387,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID, processAfterBuiltStructure(builtID); // now when everything is built - reveal tiles for lookout tower - FoWChange fw; - fw.player = t->tempOwner; - fw.mode = FoWChange::Mode::REVEAL; - getTilesInRange(fw.tiles, t->getSightCenter(), t->getSightRadius(), t->tempOwner, 1); - sendAndApply(&fw); + changeFogOfWar(t->getSightCenter(), t->getSightRadius(), t->getOwner(), ETileVisibility::REVEALED); if(t->visitingHero) visitCastleObjects(t, t->visitingHero); @@ -4108,34 +4104,40 @@ 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) +void CGameHandler::changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) { std::unordered_set tiles; - getTilesInRange(tiles, center, radius, player, hide? -1 : 1); - if (hide) + + if (mode == ETileVisibility::HIDDEN) { + getTilesInRange(tiles, center, radius, ETileVisibility::REVEALED, player); + std::unordered_set observedTiles; //do not hide tiles observed by heroes. May lead to disastrous AI problems auto p = getPlayerState(player); for (auto h : p->heroes) { - getTilesInRange(observedTiles, h->getSightCenter(), h->getSightRadius(), h->tempOwner, -1); + getTilesInRange(observedTiles, h->getSightCenter(), h->getSightRadius(), ETileVisibility::REVEALED, h->tempOwner); } for (auto t : p->towns) { - getTilesInRange(observedTiles, t->getSightCenter(), t->getSightRadius(), t->tempOwner, -1); + getTilesInRange(observedTiles, t->getSightCenter(), t->getSightRadius(), ETileVisibility::REVEALED, t->tempOwner); } for (auto tile : observedTiles) vstd::erase_if_present (tiles, tile); } - changeFogOfWar(tiles, player, hide); + else + { + getTilesInRange(tiles, center, radius, ETileVisibility::HIDDEN, player); + } + changeFogOfWar(tiles, player, mode); } -void CGameHandler::changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) +void CGameHandler::changeFogOfWar(std::unordered_set &tiles, PlayerColor player, ETileVisibility mode) { FoWChange fow; fow.tiles = tiles; fow.player = player; - fow.mode = hide ? FoWChange::Mode::HIDE : FoWChange::Mode::REVEAL; + fow.mode = mode; sendAndApply(&fow); } diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 2784aa6a7..582eb0c2b 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -148,8 +148,8 @@ public: void changeObjPos(ObjectInstanceID objid, int3 newPos, const PlayerColor & initiator) 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; + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) override; + void changeFogOfWar(std::unordered_set &tiles, PlayerColor player,ETileVisibility mode) override; void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) override; diff --git a/server/processors/PlayerMessageProcessor.cpp b/server/processors/PlayerMessageProcessor.cpp index 7df0a3cb9..62b30a72e 100644 --- a/server/processors/PlayerMessageProcessor.cpp +++ b/server/processors/PlayerMessageProcessor.cpp @@ -346,7 +346,7 @@ void PlayerMessageProcessor::cheatDefeat(PlayerColor player) void PlayerMessageProcessor::cheatMapReveal(PlayerColor player, bool reveal) { FoWChange fc; - fc.mode = reveal ? FoWChange::Mode::REVEAL : FoWChange::Mode::HIDE; + fc.mode = reveal ? ETileVisibility::REVEALED : ETileVisibility::HIDDEN; fc.player = player; const auto & fowMap = gameHandler->gameState()->getPlayerTeam(player)->fogOfWarMap; const auto & mapSize = gameHandler->gameState()->getMapSize(); @@ -356,7 +356,7 @@ void PlayerMessageProcessor::cheatMapReveal(PlayerColor player, bool reveal) for(int z = 0; z < mapSize.z; z++) for(int x = 0; x < mapSize.x; x++) for(int y = 0; y < mapSize.y; y++) - if(!(*fowMap)[z][x][y] || fc.mode == FoWChange::Mode::HIDE) + if(!(*fowMap)[z][x][y] || fc.mode == ETileVisibility::HIDDEN) hlp_tab[lastUnc++] = int3(x, y, z); fc.tiles.insert(hlp_tab, hlp_tab + lastUnc);