diff --git a/client/Client.h b/client/Client.h index 7a49c1952..391da0729 100644 --- a/client/Client.h +++ b/client/Client.h @@ -199,7 +199,7 @@ public: void startBattlePrimary(const CArmedInstance * army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank = false, const CGTownInstance * town = nullptr) override {}; //use hero=nullptr for no hero void startBattleI(const CArmedInstance * army1, const CArmedInstance * army2, int3 tile, bool creatureBank = false) override {}; //if any of armies is hero, hero will be used void startBattleI(const CArmedInstance * army1, const CArmedInstance * army2, bool creatureBank = false) override {}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle - bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override {return false;}; + bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override {return false;}; void giveHeroBonus(GiveBonus * bonus) override {}; void setMovePoints(SetMovePoints * smp) override {}; void setMovePoints(ObjectInstanceID hid, int val, bool absolute) override {}; diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index e1159cf6e..b3d121294 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -117,7 +117,7 @@ public: virtual void startBattlePrimary(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, const CGTownInstance *town = nullptr)=0; //use hero=nullptr for no hero virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank = false)=0; //if any of armies is hero, hero will be used virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank = false)=0; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle - virtual bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL)=0; + virtual bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveMove, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL)=0; virtual bool swapGarrisonOnSiege(ObjectInstanceID tid)=0; virtual void giveHeroBonus(GiveBonus * bonus)=0; virtual void setMovePoints(SetMovePoints * smp)=0; diff --git a/lib/constants/Enumerations.h b/lib/constants/Enumerations.h index acc6fbabd..ef8cd894e 100644 --- a/lib/constants/Enumerations.h +++ b/lib/constants/Enumerations.h @@ -253,4 +253,13 @@ enum class EArmyFormation : int8_t TIGHT }; +enum class EMovementMode : int8_t +{ + STANDARD, + DIMENSION_DOOR, + MONOLITH, + CASTLE_GATE, + TOWN_PORTAL, +}; + VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 661d6fa09..e4eaa39ad 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -524,7 +524,7 @@ void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, else dPos = hero->convertFromVisitablePos(cb->getObj(randomExit)->visitablePos()); - cb->moveHero(hero->id, dPos, true); + cb->moveHero(hero->id, dPos, EMovementMode::MONOLITH); } void CGMonolith::initObj(CRandomGenerator & rand) @@ -703,7 +703,7 @@ void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer dPos = hero->convertFromVisitablePos(*RandomGeneratorUtil::nextItem(tiles, CRandomGenerator::getDefault())); } - cb->moveHero(hero->id, dPos, true); + cb->moveHero(hero->id, dPos, EMovementMode::MONOLITH); } bool CGWhirlpool::isProtected(const CGHeroInstance * h) diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index bd5cbf188..2cd65a1b6 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -439,7 +439,7 @@ void DimensionDoorMechanics::endCast(SpellCastEnvironment * env, const Adventure const TerrainTile * curr = env->getCb()->getTile(casterPosition); if(dest->isClear(curr)) - env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(parameters.pos), true); + env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(parameters.pos), EMovementMode::DIMENSION_DOOR); } ///TownPortalMechanics @@ -567,7 +567,7 @@ void TownPortalMechanics::endCast(SpellCastEnvironment * env, const AdventureSpe destination = dynamic_cast(topObj); } - if(env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(destination->visitablePos()), true)) + if(env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(destination->visitablePos()), EMovementMode::TOWN_PORTAL)) { SetMovePoints smp; smp.hid = ObjectInstanceID(parameters.caster->getCasterUnitId()); diff --git a/lib/spells/ISpellMechanics.h b/lib/spells/ISpellMechanics.h index d0b442959..0f9dc9646 100644 --- a/lib/spells/ISpellMechanics.h +++ b/lib/spells/ISpellMechanics.h @@ -59,7 +59,7 @@ public: virtual const CMap * getMap() const = 0; virtual const CGameInfoCallback * getCb() const = 0; - virtual bool moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) = 0; //TODO: remove + virtual bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode mode) = 0; //TODO: remove virtual void genericQuery(Query * request, PlayerColor color, std::function)> callback) = 0;//TODO: type safety on query, use generic query packet when implemented }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index e87b71eb3..c180c33b0 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1073,11 +1073,11 @@ bool CGameHandler::removeObject(const CGObjectInstance * obj, const PlayerColor return true; } -bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, bool transit, PlayerColor asker) +bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode, bool transit, PlayerColor asker) { const CGHeroInstance *h = getHero(hid); // not turn of that hero or player can't simply teleport hero (at least not with this function) - if(!h || (asker != PlayerColor::NEUTRAL && teleporting)) + if(!h || (asker != PlayerColor::NEUTRAL && movementMode != EMovementMode::STANDARD)) { if(h && getStartInfo()->turnTimerInfo.isEnabled() && gs->players[h->getOwner()].turnTimer.turnTimer == 0) return true; //timer expired, no error @@ -1164,13 +1164,13 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo if(h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand() && t.blocked) return complainRet("Cannot disembark hero, tile is blocked!"); - if(distance(h->pos, dst) >= 1.5 && !teleporting) + if(distance(h->pos, dst) >= 1.5 && movementMode == EMovementMode::STANDARD) return complainRet("Tiles are not neighboring!"); if(h->inTownGarrison) return complainRet("Can not move garrisoned hero!"); - if(h->movementPointsRemaining() < cost && dst != h->pos && !teleporting) + if(h->movementPointsRemaining() < cost && dst != h->pos && movementMode == EMovementMode::STANDARD) return complainRet("Hero doesn't have any movement points left!"); if (transit && !canFly && !(canWalkOnSea && t.terType->isWater()) && !CGTeleport::isTeleport(objectToVisit)) @@ -1259,12 +1259,12 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo return doMove(TryMoveHero::DISEMBARK, CHECK_FOR_GUARDS, VISIT_DEST, LEAVING_TILE); } - if (teleporting) + if (movementMode != EMovementMode::STANDARD) { if (blockingVisit()) // e.g. hero on the other side of teleporter return true; - EGuardLook guardsCheck = VLC->settings()->getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS) + EGuardLook guardsCheck = (VLC->settings()->getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS) && movementMode == EMovementMode::DIMENSION_DOOR) ? CHECK_FOR_GUARDS : IGNORE_GUARDS; @@ -1337,7 +1337,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui return false; int3 pos = h->convertFromVisitablePos(t->visitablePos()); - moveHero(hid,pos,1); + moveHero(hid,pos,EMovementMode::CASTLE_GATE); return true; } diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 8f591d44a..eebb21f68 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -140,7 +140,7 @@ public: void startBattlePrimary(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, const CGTownInstance *town = nullptr) override; //use hero=nullptr for no hero void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank = false) override; //if any of armies is hero, hero will be used void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank = false) override; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle - bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override; + bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override; void giveHeroBonus(GiveBonus * bonus) override; void setMovePoints(SetMovePoints * smp) override; void setMovePoints(ObjectInstanceID hid, int val, bool absolute) override; diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index 1bb9175cd..576b3dffc 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -65,7 +65,7 @@ void ApplyGhNetPackVisitor::visitMoveHero(MoveHero & pack) for (auto const & dest : pack.path) { - if (!gh.moveHero(pack.hid, dest, 0, pack.transit, pack.player)) + if (!gh.moveHero(pack.hid, dest, EMovementMode::STANDARD, pack.transit, pack.player)) { result = false; return; diff --git a/server/ServerSpellCastEnvironment.cpp b/server/ServerSpellCastEnvironment.cpp index b89b9ad8f..035617d6e 100644 --- a/server/ServerSpellCastEnvironment.cpp +++ b/server/ServerSpellCastEnvironment.cpp @@ -89,9 +89,9 @@ const CMap * ServerSpellCastEnvironment::getMap() const return gh->gameState()->map; } -bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) +bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode mode) { - return gh->moveHero(hid, dst, teleporting, false); + return gh->moveHero(hid, dst, mode, false); } void ServerSpellCastEnvironment::genericQuery(Query * request, PlayerColor color, std::function)> callback) diff --git a/server/ServerSpellCastEnvironment.h b/server/ServerSpellCastEnvironment.h index c6f7e124b..307f858ea 100644 --- a/server/ServerSpellCastEnvironment.h +++ b/server/ServerSpellCastEnvironment.h @@ -36,7 +36,7 @@ public: const CMap * getMap() const override; const CGameInfoCallback * getCb() const override; - bool moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) override; + bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode mode) override; void genericQuery(Query * request, PlayerColor color, std::function)> callback) override; private: CGameHandler * gh; diff --git a/test/game/CGameStateTest.cpp b/test/game/CGameStateTest.cpp index aff72a61f..aa37088e4 100644 --- a/test/game/CGameStateTest.cpp +++ b/test/game/CGameStateTest.cpp @@ -121,7 +121,7 @@ public: return gameState.get(); } - bool moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) override + bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode) override { return false; } diff --git a/test/mock/mock_IGameCallback.h b/test/mock/mock_IGameCallback.h index 16b9006ef..9ab8675f1 100644 --- a/test/mock/mock_IGameCallback.h +++ b/test/mock/mock_IGameCallback.h @@ -77,7 +77,7 @@ public: void startBattlePrimary(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, const CGTownInstance *town = nullptr) override {} //use hero=nullptr for no hero void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank = false) override {} //if any of armies is hero, hero will be used void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank = false) override {} //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle - bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override {return false;} + bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override {return false;} bool swapGarrisonOnSiege(ObjectInstanceID tid) override {return false;} void giveHeroBonus(GiveBonus * bonus) override {} void setMovePoints(SetMovePoints * smp) override {}