mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-02 00:10:22 +02:00
Client-side support for multiple battles
This commit is contained in:
parent
036df2e0ad
commit
41210c1dbf
@ -27,7 +27,7 @@ void CEmptyAI::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_p
|
|||||||
cb = CB;
|
cb = CB;
|
||||||
env = ENV;
|
env = ENV;
|
||||||
human=false;
|
human=false;
|
||||||
playerID = *cb->getMyColor();
|
playerID = *cb->getPlayerID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEmptyAI::yourTurn(QueryID queryID)
|
void CEmptyAI::yourTurn(QueryID queryID)
|
||||||
|
@ -536,7 +536,7 @@ void AIGateway::initGameInterface(std::shared_ptr<Environment> env, std::shared_
|
|||||||
cbc = CB;
|
cbc = CB;
|
||||||
|
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
playerID = *myCb->getMyColor();
|
playerID = *myCb->getPlayerID();
|
||||||
myCb->waitTillRealize = true;
|
myCb->waitTillRealize = true;
|
||||||
myCb->unlockGsWhenWaiting = true;
|
myCb->unlockGsWhenWaiting = true;
|
||||||
|
|
||||||
|
@ -226,12 +226,12 @@ void CStupidAI::battleEnd(const BattleID & battleID, const BattleResult *br, Que
|
|||||||
// print("battleResultsApplied called");
|
// print("battleResultsApplied called");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void CStupidAI::battleNewRoundFirst(const BattleID & battleID, int round)
|
void CStupidAI::battleNewRoundFirst(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
print("battleNewRoundFirst called");
|
print("battleNewRoundFirst called");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStupidAI::battleNewRound(const BattleID & battleID, int round)
|
void CStupidAI::battleNewRound(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
print("battleNewRound called");
|
print("battleNewRound called");
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,8 @@ public:
|
|||||||
void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged) override; //called when stack receives damage (after battleAttack())
|
void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged) override; //called when stack receives damage (after battleAttack())
|
||||||
void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID) override;
|
void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID) override;
|
||||||
//void battleResultsApplied() override; //called when all effects of last battle are applied
|
//void battleResultsApplied() override; //called when all effects of last battle are applied
|
||||||
void battleNewRoundFirst(const BattleID & battleID, int round) override; //called at the beginning of each turn before changes are applied;
|
void battleNewRoundFirst(const BattleID & battleID) override; //called at the beginning of each turn before changes are applied;
|
||||||
void battleNewRound(const BattleID & battleID, int round) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
void battleNewRound(const BattleID & battleID) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||||
void battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
|
void battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
|
||||||
void battleSpellCast(const BattleID & battleID, const BattleSpellCast *sc) override;
|
void battleSpellCast(const BattleID & battleID, const BattleSpellCast *sc) override;
|
||||||
void battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse) override;//called when a specific effect is set to stacks
|
void battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse) override;//called when a specific effect is set to stacks
|
||||||
|
@ -600,7 +600,7 @@ void VCAI::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<C
|
|||||||
ah->init(CB.get());
|
ah->init(CB.get());
|
||||||
|
|
||||||
NET_EVENT_HANDLER; //sets ah->rm->cb
|
NET_EVENT_HANDLER; //sets ah->rm->cb
|
||||||
playerID = *myCb->getMyColor();
|
playerID = *myCb->getPlayerID();
|
||||||
myCb->waitTillRealize = true;
|
myCb->waitTillRealize = true;
|
||||||
myCb->unlockGsWhenWaiting = true;
|
myCb->unlockGsWhenWaiting = true;
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, BuildingID buildingID)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleCallback::battleMakeSpellAction(const BattleAction & action)
|
void CBattleCallback::battleMakeSpellAction(const BattleID & battleID, const BattleAction & action)
|
||||||
{
|
{
|
||||||
assert(action.actionType == EActionType::HERO_SPELL);
|
assert(action.actionType == EActionType::HERO_SPELL);
|
||||||
MakeAction mca(action);
|
MakeAction mca(action);
|
||||||
@ -212,7 +212,7 @@ void CBattleCallback::battleMakeSpellAction(const BattleAction & action)
|
|||||||
|
|
||||||
int CBattleCallback::sendRequest(const CPackForServer * request)
|
int CBattleCallback::sendRequest(const CPackForServer * request)
|
||||||
{
|
{
|
||||||
int requestID = cl->sendRequest(request, *player);
|
int requestID = cl->sendRequest(request, *getPlayerID());
|
||||||
if(waitTillRealize)
|
if(waitTillRealize)
|
||||||
{
|
{
|
||||||
logGlobal->trace("We'll wait till request %d is answered.\n", requestID);
|
logGlobal->trace("We'll wait till request %d is answered.\n", requestID);
|
||||||
@ -226,8 +226,7 @@ int CBattleCallback::sendRequest(const CPackForServer * request)
|
|||||||
|
|
||||||
void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
||||||
{
|
{
|
||||||
if(town->tempOwner == *player
|
if(town->tempOwner == *player || (town->garrisonHero && town->garrisonHero->tempOwner == *player ))
|
||||||
|| (town->garrisonHero && town->garrisonHero->tempOwner == *player ))
|
|
||||||
{
|
{
|
||||||
GarrisonHeroSwap pack(town->id);
|
GarrisonHeroSwap pack(town->id);
|
||||||
sendRequest(&pack);
|
sendRequest(&pack);
|
||||||
@ -236,7 +235,7 @@ void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
|||||||
|
|
||||||
void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid)
|
void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid)
|
||||||
{
|
{
|
||||||
if(hero->tempOwner != player) return;
|
if(hero->tempOwner != *player) return;
|
||||||
|
|
||||||
BuyArtifact pack(hero->id,aid);
|
BuyArtifact pack(hero->id,aid);
|
||||||
sendRequest(&pack);
|
sendRequest(&pack);
|
||||||
@ -297,8 +296,8 @@ void CCallback::buildBoat( const IShipyard *obj )
|
|||||||
sendRequest(&bb);
|
sendRequest(&bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCallback::CCallback(CGameState * GS, std::optional<PlayerColor> Player, CClient * C):
|
CCallback::CCallback(CGameState * GS, std::optional<PlayerColor> Player, CClient * C)
|
||||||
CBattleCallback(Player, C)
|
: CBattleCallback(Player, C)
|
||||||
{
|
{
|
||||||
gs = GS;
|
gs = GS;
|
||||||
|
|
||||||
@ -306,10 +305,7 @@ CCallback::CCallback(CGameState * GS, std::optional<PlayerColor> Player, CClient
|
|||||||
unlockGsWhenWaiting = false;
|
unlockGsWhenWaiting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCallback::~CCallback()
|
CCallback::~CCallback() = default;
|
||||||
{
|
|
||||||
//trivial, but required. Don`t remove.
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallback::canMoveBetween(const int3 &a, const int3 &b)
|
bool CCallback::canMoveBetween(const int3 &a, const int3 &b)
|
||||||
{
|
{
|
||||||
@ -322,6 +318,11 @@ std::shared_ptr<const CPathsInfo> CCallback::getPathsInfo(const CGHeroInstance *
|
|||||||
return cl->getPathsInfo(h);
|
return cl->getPathsInfo(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<PlayerColor> CCallback::getPlayerID() const
|
||||||
|
{
|
||||||
|
return CBattleCallback::getPlayerID();
|
||||||
|
}
|
||||||
|
|
||||||
int3 CCallback::getGuardingCreaturePosition(int3 tile)
|
int3 CCallback::getGuardingCreaturePosition(int3 tile)
|
||||||
{
|
{
|
||||||
if (!gs->map->isInTheMap(tile))
|
if (!gs->map->isInTheMap(tile))
|
||||||
@ -371,23 +372,23 @@ scripting::Pool * CBattleCallback::getContextPool() const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CBattleCallback::CBattleCallback(std::optional<PlayerColor> Player, CClient * C)
|
CBattleCallback::CBattleCallback(std::optional<PlayerColor> player, CClient * C):
|
||||||
|
cl(C),
|
||||||
|
player(player)
|
||||||
{
|
{
|
||||||
player = Player;
|
|
||||||
cl = C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleCallback::battleMakeUnitAction(const BattleAction & action)
|
void CBattleCallback::battleMakeUnitAction(const BattleID & battleID, const BattleAction & action)
|
||||||
{
|
{
|
||||||
assert(!cl->gs->curB->tacticDistance);
|
assert(!cl->gs->getBattle(battleID)->tacticDistance);
|
||||||
MakeAction ma;
|
MakeAction ma;
|
||||||
ma.ba = action;
|
ma.ba = action;
|
||||||
sendRequest(&ma);
|
sendRequest(&ma);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleCallback::battleMakeTacticAction( const BattleAction & action )
|
void CBattleCallback::battleMakeTacticAction(const BattleID & battleID, const BattleAction & action )
|
||||||
{
|
{
|
||||||
assert(cl->gs->curB->tacticDistance);
|
assert(cl->gs->getBattle(battleID)->tacticDistance);
|
||||||
MakeAction ma;
|
MakeAction ma;
|
||||||
ma.ba = action;
|
ma.ba = action;
|
||||||
sendRequest(&ma);
|
sendRequest(&ma);
|
||||||
@ -395,5 +396,25 @@ void CBattleCallback::battleMakeTacticAction( const BattleAction & action )
|
|||||||
|
|
||||||
std::optional<BattleAction> CBattleCallback::makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState)
|
std::optional<BattleAction> CBattleCallback::makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState)
|
||||||
{
|
{
|
||||||
return cl->playerint[getPlayerID().value()]->makeSurrenderRetreatDecision(battleID< battleState);
|
return cl->playerint[getPlayerID().value()]->makeSurrenderRetreatDecision(battleID, battleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CPlayerBattleCallback> CBattleCallback::getBattle(const BattleID & battleID)
|
||||||
|
{
|
||||||
|
return activeBattles.at(battleID);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<PlayerColor> CBattleCallback::getPlayerID() const
|
||||||
|
{
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBattleCallback::onBattleStarted(const IBattleInfo * info)
|
||||||
|
{
|
||||||
|
activeBattles[info->getBattleID()] = std::make_shared<CPlayerBattleCallback>(info, *getPlayerID());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBattleCallback::onBattleEnded(const BattleID & battleID)
|
||||||
|
{
|
||||||
|
activeBattles.erase(battleID);
|
||||||
}
|
}
|
||||||
|
16
CCallback.h
16
CCallback.h
@ -59,6 +59,7 @@ public:
|
|||||||
virtual std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) = 0;
|
virtual std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) = 0;
|
||||||
|
|
||||||
virtual std::shared_ptr<CPlayerBattleCallback> getBattle(const BattleID & battleID) = 0;
|
virtual std::shared_ptr<CPlayerBattleCallback> getBattle(const BattleID & battleID) = 0;
|
||||||
|
virtual std::optional<PlayerColor> getPlayerID() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IGameActionCallback
|
class IGameActionCallback
|
||||||
@ -114,20 +115,23 @@ class CBattleCallback : public IBattleCallback
|
|||||||
{
|
{
|
||||||
std::map<BattleID, std::shared_ptr<CPlayerBattleCallback>> activeBattles;
|
std::map<BattleID, std::shared_ptr<CPlayerBattleCallback>> activeBattles;
|
||||||
|
|
||||||
|
std::optional<PlayerColor> player;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int sendRequest(const CPackForServer * request); //returns requestID (that'll be matched to requestID in PackageApplied)
|
int sendRequest(const CPackForServer * request); //returns requestID (that'll be matched to requestID in PackageApplied)
|
||||||
CClient *cl;
|
CClient *cl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CBattleCallback(std::optional<PlayerColor> Player, CClient * C);
|
CBattleCallback(std::optional<PlayerColor> player, CClient * C);
|
||||||
void battleMakeSpellAction(const BattleID & battleID, const BattleAction & action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
void battleMakeSpellAction(const BattleID & battleID, const BattleAction & action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
||||||
void battleMakeUnitAction(const BattleID & battleID, const BattleAction & action) override;
|
void battleMakeUnitAction(const BattleID & battleID, const BattleAction & action) override;
|
||||||
void battleMakeTacticAction(const BattleID & battleID, const BattleAction & action) override; // performs tactic phase actions
|
void battleMakeTacticAction(const BattleID & battleID, const BattleAction & action) override; // performs tactic phase actions
|
||||||
std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
|
std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
|
||||||
|
|
||||||
std::shared_ptr<CPlayerBattleCallback> getBattle(const BattleID & battleID) override;
|
std::shared_ptr<CPlayerBattleCallback> getBattle(const BattleID & battleID) override;
|
||||||
|
std::optional<PlayerColor> getPlayerID() const override;
|
||||||
|
|
||||||
void onBattleStarted(const BattleID & battleID);
|
void onBattleStarted(const IBattleInfo * info);
|
||||||
void onBattleEnded(const BattleID & battleID);
|
void onBattleEnded(const BattleID & battleID);
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
@ -145,9 +149,11 @@ public:
|
|||||||
virtual ~CCallback();
|
virtual ~CCallback();
|
||||||
|
|
||||||
//client-specific functionalities (pathfinding)
|
//client-specific functionalities (pathfinding)
|
||||||
virtual bool canMoveBetween(const int3 &a, const int3 &b);
|
bool canMoveBetween(const int3 &a, const int3 &b);
|
||||||
virtual int3 getGuardingCreaturePosition(int3 tile);
|
int3 getGuardingCreaturePosition(int3 tile);
|
||||||
virtual std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
|
std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
|
||||||
|
|
||||||
|
std::optional<PlayerColor> getPlayerID() const override;
|
||||||
|
|
||||||
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
||||||
void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);
|
void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);
|
||||||
|
@ -658,7 +658,7 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, BuildingID build
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleStartBefore(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2)
|
void CPlayerInterface::battleStartBefore(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2)
|
||||||
{
|
{
|
||||||
// when battle starts, game will send battleStart pack *before* movement confirmation
|
// when battle starts, game will send battleStart pack *before* movement confirmation
|
||||||
// and since network thread wait for battle intro to play, movement confirmation will only happen after intro
|
// and since network thread wait for battle intro to play, movement confirmation will only happen after intro
|
||||||
@ -670,7 +670,7 @@ void CPlayerInterface::battleStartBefore(const CCreatureSet *army1, const CCreat
|
|||||||
waitForAllDialogs();
|
waitForAllDialogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed)
|
void CPlayerInterface::battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
|
||||||
@ -685,7 +685,7 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
|||||||
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();
|
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();
|
||||||
|
|
||||||
autofightingAI->initBattleInterface(env, cb, autocombatPreferences);
|
autofightingAI->initBattleInterface(env, cb, autocombatPreferences);
|
||||||
autofightingAI->battleStart(army1, army2, tile, hero1, hero2, side, false);
|
autofightingAI->battleStart(battleID, army1, army2, tile, hero1, hero2, side, false);
|
||||||
isAutoFightOn = true;
|
isAutoFightOn = true;
|
||||||
cb->registerBattleInterface(autofightingAI);
|
cb->registerBattleInterface(autofightingAI);
|
||||||
}
|
}
|
||||||
@ -697,7 +697,7 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
|
|||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleUnitsChanged(const std::vector<UnitChanges> & units)
|
void CPlayerInterface::battleUnitsChanged(const BattleID & battleID, const std::vector<UnitChanges> & units)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -708,7 +708,7 @@ void CPlayerInterface::battleUnitsChanged(const std::vector<UnitChanges> & units
|
|||||||
{
|
{
|
||||||
case UnitChanges::EOperation::RESET_STATE:
|
case UnitChanges::EOperation::RESET_STATE:
|
||||||
{
|
{
|
||||||
const CStack * stack = cb->battleGetStackByID(info.id );
|
const CStack * stack = cb->getBattle(battleID)->battleGetStackByID(info.id );
|
||||||
|
|
||||||
if(!stack)
|
if(!stack)
|
||||||
{
|
{
|
||||||
@ -723,7 +723,7 @@ void CPlayerInterface::battleUnitsChanged(const std::vector<UnitChanges> & units
|
|||||||
break;
|
break;
|
||||||
case UnitChanges::EOperation::ADD:
|
case UnitChanges::EOperation::ADD:
|
||||||
{
|
{
|
||||||
const CStack * unit = cb->battleGetStackByID(info.id);
|
const CStack * unit = cb->getBattle(battleID)->battleGetStackByID(info.id);
|
||||||
if(!unit)
|
if(!unit)
|
||||||
{
|
{
|
||||||
logGlobal->error("Invalid unit ID %d", info.id);
|
logGlobal->error("Invalid unit ID %d", info.id);
|
||||||
@ -739,7 +739,7 @@ void CPlayerInterface::battleUnitsChanged(const std::vector<UnitChanges> & units
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleObstaclesChanged(const std::vector<ObstacleChanges> & obstacles)
|
void CPlayerInterface::battleObstaclesChanged(const BattleID & battleID, const std::vector<ObstacleChanges> & obstacles)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -751,7 +751,7 @@ void CPlayerInterface::battleObstaclesChanged(const std::vector<ObstacleChanges>
|
|||||||
{
|
{
|
||||||
if(change.operation == BattleChanges::EOperation::ADD)
|
if(change.operation == BattleChanges::EOperation::ADD)
|
||||||
{
|
{
|
||||||
auto instance = cb->battleGetObstacleByID(change.id);
|
auto instance = cb->getBattle(battleID)->battleGetObstacleByID(change.id);
|
||||||
if(instance)
|
if(instance)
|
||||||
newObstacles.push_back(instance);
|
newObstacles.push_back(instance);
|
||||||
else
|
else
|
||||||
@ -770,7 +770,7 @@ void CPlayerInterface::battleObstaclesChanged(const std::vector<ObstacleChanges>
|
|||||||
battleInt->fieldController->redrawBackgroundWithHexes();
|
battleInt->fieldController->redrawBackgroundWithHexes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleCatapultAttacked(const CatapultAttack & ca)
|
void CPlayerInterface::battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -778,15 +778,15 @@ void CPlayerInterface::battleCatapultAttacked(const CatapultAttack & ca)
|
|||||||
battleInt->stackIsCatapulting(ca);
|
battleInt->stackIsCatapulting(ca);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleNewRound(int round) //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
void CPlayerInterface::battleNewRound(const BattleID & battleID) //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
battleInt->newRound(round);
|
battleInt->newRound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::actionStarted(const BattleAction &action)
|
void CPlayerInterface::actionStarted(const BattleID & battleID, const BattleAction &action)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -794,7 +794,7 @@ void CPlayerInterface::actionStarted(const BattleAction &action)
|
|||||||
battleInt->startAction(action);
|
battleInt->startAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::actionFinished(const BattleAction &action)
|
void CPlayerInterface::actionFinished(const BattleID & battleID, const BattleAction &action)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -802,17 +802,17 @@ void CPlayerInterface::actionFinished(const BattleAction &action)
|
|||||||
battleInt->endAction(action);
|
battleInt->endAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack
|
void CPlayerInterface::activeStack(const BattleID & battleID, const CStack * stack) //called when it's turn of that stack
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
logGlobal->trace("Awaiting command for %s", stack->nodeName());
|
logGlobal->trace("Awaiting command for %s", stack->nodeName());
|
||||||
|
|
||||||
assert(!cb->battleIsFinished());
|
assert(!cb->getBattle(battleID)->battleIsFinished());
|
||||||
if (cb->battleIsFinished())
|
if (cb->getBattle(battleID)->battleIsFinished())
|
||||||
{
|
{
|
||||||
logGlobal->error("Received CPlayerInterface::activeStack after battle is finished!");
|
logGlobal->error("Received CPlayerInterface::activeStack after battle is finished!");
|
||||||
|
|
||||||
cb->battleMakeUnitAction(BattleAction::makeDefend(stack));
|
cb->battleMakeUnitAction(battleID, BattleAction::makeDefend(stack));
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +823,7 @@ void CPlayerInterface::activeStack(const CStack * stack) //called when it's turn
|
|||||||
//FIXME: we want client rendering to proceed while AI is making actions
|
//FIXME: we want client rendering to proceed while AI is making actions
|
||||||
// so unlock mutex while AI is busy since this might take quite a while, especially if hero has many spells
|
// so unlock mutex while AI is busy since this might take quite a while, especially if hero has many spells
|
||||||
auto unlockPim = vstd::makeUnlockGuard(*pim);
|
auto unlockPim = vstd::makeUnlockGuard(*pim);
|
||||||
autofightingAI->activeStack(stack);
|
autofightingAI->activeStack(battleID, stack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,7 +835,7 @@ void CPlayerInterface::activeStack(const CStack * stack) //called when it's turn
|
|||||||
if(!battleInt)
|
if(!battleInt)
|
||||||
{
|
{
|
||||||
// probably battle is finished already
|
// probably battle is finished already
|
||||||
cb->battleMakeUnitAction(BattleAction::makeDefend(stack));
|
cb->battleMakeUnitAction(battleID, BattleAction::makeDefend(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -845,7 +845,7 @@ void CPlayerInterface::activeStack(const CStack * stack) //called when it's turn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
|
void CPlayerInterface::battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
if(isAutoFightOn || autofightingAI)
|
if(isAutoFightOn || autofightingAI)
|
||||||
@ -880,7 +880,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
|
|||||||
battleInt->battleFinished(*br, queryID);
|
battleInt->battleFinished(*br, queryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleLogMessage(const std::vector<MetaString> & lines)
|
void CPlayerInterface::battleLogMessage(const BattleID & battleID, const std::vector<MetaString> & lines)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -888,28 +888,28 @@ void CPlayerInterface::battleLogMessage(const std::vector<MetaString> & lines)
|
|||||||
battleInt->displayBattleLog(lines);
|
battleInt->displayBattleLog(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport)
|
void CPlayerInterface::battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
battleInt->stackMoved(stack, dest, distance, teleport);
|
battleInt->stackMoved(stack, dest, distance, teleport);
|
||||||
}
|
}
|
||||||
void CPlayerInterface::battleSpellCast( const BattleSpellCast *sc )
|
void CPlayerInterface::battleSpellCast(const BattleID & battleID, const BattleSpellCast * sc)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
battleInt->spellCast(sc);
|
battleInt->spellCast(sc);
|
||||||
}
|
}
|
||||||
void CPlayerInterface::battleStacksEffectsSet( const SetStackEffect & sse )
|
void CPlayerInterface::battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
battleInt->battleStacksEffectsSet(sse);
|
battleInt->battleStacksEffectsSet(sse);
|
||||||
}
|
}
|
||||||
void CPlayerInterface::battleTriggerEffect (const BattleTriggerEffect & bte)
|
void CPlayerInterface::battleTriggerEffect(const BattleID & battleID, const BattleTriggerEffect & bte)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -923,7 +923,7 @@ void CPlayerInterface::battleTriggerEffect (const BattleTriggerEffect & bte)
|
|||||||
battleInt->windowObject->heroManaPointsChanged(manaDrainedHero);
|
battleInt->windowObject->heroManaPointsChanged(manaDrainedHero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa, bool ranged)
|
void CPlayerInterface::battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -931,8 +931,8 @@ void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacke
|
|||||||
std::vector<StackAttackedInfo> arg;
|
std::vector<StackAttackedInfo> arg;
|
||||||
for(auto & elem : bsa)
|
for(auto & elem : bsa)
|
||||||
{
|
{
|
||||||
const CStack * defender = cb->battleGetStackByID(elem.stackAttacked, false);
|
const CStack * defender = cb->getBattle(battleID)->battleGetStackByID(elem.stackAttacked, false);
|
||||||
const CStack * attacker = cb->battleGetStackByID(elem.attackerID, false);
|
const CStack * attacker = cb->getBattle(battleID)->battleGetStackByID(elem.attackerID, false);
|
||||||
|
|
||||||
assert(defender);
|
assert(defender);
|
||||||
|
|
||||||
@ -955,13 +955,13 @@ void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacke
|
|||||||
}
|
}
|
||||||
battleInt->stacksAreAttacked(arg);
|
battleInt->stacksAreAttacked(arg);
|
||||||
}
|
}
|
||||||
void CPlayerInterface::battleAttack(const BattleAttack * ba)
|
void CPlayerInterface::battleAttack(const BattleID & battleID, const BattleAttack * ba)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
StackAttackInfo info;
|
StackAttackInfo info;
|
||||||
info.attacker = cb->battleGetStackByID(ba->stackAttacking);
|
info.attacker = cb->getBattle(battleID)->battleGetStackByID(ba->stackAttacking);
|
||||||
info.defender = nullptr;
|
info.defender = nullptr;
|
||||||
info.indirectAttack = ba->shot();
|
info.indirectAttack = ba->shot();
|
||||||
info.lucky = ba->lucky();
|
info.lucky = ba->lucky();
|
||||||
@ -979,11 +979,11 @@ void CPlayerInterface::battleAttack(const BattleAttack * ba)
|
|||||||
if(!elem.isSecondary())
|
if(!elem.isSecondary())
|
||||||
{
|
{
|
||||||
assert(info.defender == nullptr);
|
assert(info.defender == nullptr);
|
||||||
info.defender = cb->battleGetStackByID(elem.stackAttacked);
|
info.defender = cb->getBattle(battleID)->battleGetStackByID(elem.stackAttacked);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.secondaryDefender.push_back(cb->battleGetStackByID(elem.stackAttacked));
|
info.secondaryDefender.push_back(cb->getBattle(battleID)->battleGetStackByID(elem.stackAttacked));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(info.defender != nullptr);
|
assert(info.defender != nullptr);
|
||||||
@ -992,7 +992,7 @@ void CPlayerInterface::battleAttack(const BattleAttack * ba)
|
|||||||
battleInt->stackAttacking(info);
|
battleInt->stackAttacking(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleGateStateChanged(const EGateState state)
|
void CPlayerInterface::battleGateStateChanged(const BattleID & battleID, const EGateState state)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
@ -1705,12 +1705,12 @@ void CPlayerInterface::tryDigging(const CGHeroInstance * h)
|
|||||||
showInfoDialog(CGI->generaltexth->allTexts[msgToShow]);
|
showInfoDialog(CGI->generaltexth->allTexts[msgToShow]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleNewRoundFirst( int round )
|
void CPlayerInterface::battleNewRoundFirst(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
|
|
||||||
battleInt->newRoundFirst(round);
|
battleInt->newRoundFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::stopMovement()
|
void CPlayerInterface::stopMovement()
|
||||||
|
@ -152,25 +152,25 @@ protected: // Call-ins from server, should not be called directly, but only via
|
|||||||
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
|
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
|
||||||
|
|
||||||
//for battles
|
//for battles
|
||||||
void actionFinished(const BattleAction& action) override;//occurs AFTER action taken by active stack or by the hero
|
void actionFinished(const BattleID & battleID, const BattleAction& action) override;//occurs AFTER action taken by active stack or by the hero
|
||||||
void actionStarted(const BattleAction& action) override;//occurs BEFORE action taken by active stack or by the hero
|
void actionStarted(const BattleID & battleID, const BattleAction& action) override;//occurs BEFORE action taken by active stack or by the hero
|
||||||
void activeStack(const CStack * stack) override; //called when it's turn of that stack
|
void activeStack(const BattleID & battleID, const CStack * stack) override; //called when it's turn of that stack
|
||||||
void battleAttack(const BattleAttack *ba) override; //stack performs attack
|
void battleAttack(const BattleID & battleID, const BattleAttack *ba) override; //stack performs attack
|
||||||
void battleEnd(const BattleResult *br, QueryID queryID) override; //end of battle
|
void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID) override; //end of battle
|
||||||
void battleNewRoundFirst(int round) override; //called at the beginning of each turn before changes are applied; used for HP regen handling
|
void battleNewRoundFirst(const BattleID & battleID) override; //called at the beginning of each turn before changes are applied; used for HP regen handling
|
||||||
void battleNewRound(int round) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
void battleNewRound(const BattleID & battleID) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||||
void battleLogMessage(const std::vector<MetaString> & lines) override;
|
void battleLogMessage(const BattleID & battleID, const std::vector<MetaString> & lines) override;
|
||||||
void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
|
void battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
|
||||||
void battleSpellCast(const BattleSpellCast *sc) override;
|
void battleSpellCast(const BattleID & battleID, const BattleSpellCast *sc) override;
|
||||||
void battleStacksEffectsSet(const SetStackEffect & sse) override; //called when a specific effect is set to stacks
|
void battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse) override; //called when a specific effect is set to stacks
|
||||||
void battleTriggerEffect(const BattleTriggerEffect & bte) override; //various one-shot effect
|
void battleTriggerEffect(const BattleID & battleID, const BattleTriggerEffect & bte) override; //various one-shot effect
|
||||||
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa, bool ranged) override;
|
void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged) override;
|
||||||
void battleStartBefore(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) override; //called by engine just before battle starts; side=0 - left, side=1 - right
|
void battleStartBefore(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) override; //called by engine just before battle starts; side=0 - left, side=1 - right
|
||||||
void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed) override; //called by engine when battle starts; side=0 - left, side=1 - right
|
void battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed) override; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||||
void battleUnitsChanged(const std::vector<UnitChanges> & units) override;
|
void battleUnitsChanged(const BattleID & battleID, const std::vector<UnitChanges> & units) override;
|
||||||
void battleObstaclesChanged(const std::vector<ObstacleChanges> & obstacles) override;
|
void battleObstaclesChanged(const BattleID & battleID, const std::vector<ObstacleChanges> & obstacles) override;
|
||||||
void battleCatapultAttacked(const CatapultAttack & ca) override; //called when catapult makes an attack
|
void battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca) override; //called when catapult makes an attack
|
||||||
void battleGateStateChanged(const EGateState state) override;
|
void battleGateStateChanged(const BattleID & battleID, const EGateState state) override;
|
||||||
void yourTacticPhase(const BattleID & battleID, int distance) override;
|
void yourTacticPhase(const BattleID & battleID, int distance) override;
|
||||||
std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
|
std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
|
||||||
|
|
||||||
|
@ -122,9 +122,9 @@ events::EventBus * CPlayerEnvironment::eventBus() const
|
|||||||
return cl->eventBus();//always get actual value
|
return cl->eventBus();//always get actual value
|
||||||
}
|
}
|
||||||
|
|
||||||
const CPlayerEnvironment::BattleCb * CPlayerEnvironment::battle() const
|
const CPlayerEnvironment::BattleCb * CPlayerEnvironment::battle(const BattleID & battleID) const
|
||||||
{
|
{
|
||||||
return mainCallback.get();
|
return mainCallback->getBattle(battleID).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CPlayerEnvironment::GameCb * CPlayerEnvironment::game() const
|
const CPlayerEnvironment::GameCb * CPlayerEnvironment::game() const
|
||||||
@ -153,9 +153,9 @@ const Services * CClient::services() const
|
|||||||
return VLC; //todo: this should be CGI
|
return VLC; //todo: this should be CGI
|
||||||
}
|
}
|
||||||
|
|
||||||
const CClient::BattleCb * CClient::battle() const
|
const CClient::BattleCb * CClient::battle(const BattleID & battleID) const
|
||||||
{
|
{
|
||||||
return this;
|
return nullptr; //todo?
|
||||||
}
|
}
|
||||||
|
|
||||||
const CClient::GameCb * CClient::game() const
|
const CClient::GameCb * CClient::game() const
|
||||||
@ -345,7 +345,7 @@ void CClient::serialize(BinaryDeserializer & h, const int version)
|
|||||||
|
|
||||||
void CClient::save(const std::string & fname)
|
void CClient::save(const std::string & fname)
|
||||||
{
|
{
|
||||||
if(gs->curB)
|
if(!gs->currentBattles.empty())
|
||||||
{
|
{
|
||||||
logNetwork->error("Game cannot be saved during battle!");
|
logNetwork->error("Game cannot be saved during battle!");
|
||||||
return;
|
return;
|
||||||
@ -565,14 +565,12 @@ int CClient::sendRequest(const CPackForServer * request, PlayerColor player)
|
|||||||
|
|
||||||
void CClient::battleStarted(const BattleInfo * info)
|
void CClient::battleStarted(const BattleInfo * info)
|
||||||
{
|
{
|
||||||
setBattle(info);
|
|
||||||
|
|
||||||
for(auto & battleCb : battleCallbacks)
|
for(auto & battleCb : battleCallbacks)
|
||||||
{
|
{
|
||||||
if(vstd::contains_if(info->sides, [&](const SideInBattle& side) {return side.color == battleCb.first; })
|
if(vstd::contains_if(info->sides, [&](const SideInBattle& side) {return side.color == battleCb.first; })
|
||||||
|| !battleCb.first.isValidPlayer())
|
|| !battleCb.first.isValidPlayer())
|
||||||
{
|
{
|
||||||
battleCb.second->setBattle(info);
|
battleCb.second->onBattleStarted(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,7 +581,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
auto callBattleStart = [&](PlayerColor color, ui8 side)
|
auto callBattleStart = [&](PlayerColor color, ui8 side)
|
||||||
{
|
{
|
||||||
if(vstd::contains(battleints, color))
|
if(vstd::contains(battleints, color))
|
||||||
battleints[color]->battleStart(leftSide.armyObject, rightSide.armyObject, info->tile, leftSide.hero, rightSide.hero, side, info->replayAllowed);
|
battleints[color]->battleStart(info->battleID, leftSide.armyObject, rightSide.armyObject, info->tile, leftSide.hero, rightSide.hero, side, info->replayAllowed);
|
||||||
};
|
};
|
||||||
|
|
||||||
callBattleStart(leftSide.color, 0);
|
callBattleStart(leftSide.color, 0);
|
||||||
@ -601,11 +599,11 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
//Remove player interfaces for auto battle (quickCombat option)
|
//Remove player interfaces for auto battle (quickCombat option)
|
||||||
if(att && att->isAutoFightOn)
|
if(att && att->isAutoFightOn)
|
||||||
{
|
{
|
||||||
if (att->cb->battleGetTacticDist())
|
if (att->cb->getBattle(info->battleID)->battleGetTacticDist())
|
||||||
{
|
{
|
||||||
auto side = att->cb->playerToSide(att->playerID);
|
auto side = att->cb->getBattle(info->battleID)->playerToSide(att->playerID);
|
||||||
auto action = BattleAction::makeEndOFTacticPhase(*side);
|
auto action = BattleAction::makeEndOFTacticPhase(*side);
|
||||||
att->cb->battleMakeTacticAction(action);
|
att->cb->battleMakeTacticAction(info->battleID, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
att.reset();
|
att.reset();
|
||||||
@ -623,7 +621,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
{
|
{
|
||||||
//TODO: This certainly need improvement
|
//TODO: This certainly need improvement
|
||||||
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
|
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
|
||||||
spectratorInt->cb->setBattle(info);
|
spectratorInt->cb->onBattleStarted(info);
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||||
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt);
|
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt);
|
||||||
}
|
}
|
||||||
@ -638,20 +636,17 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::battleFinished()
|
void CClient::battleFinished(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
for(auto & side : gs->curB->sides)
|
for(auto & side : gs->getBattle(battleID)->sides)
|
||||||
if(battleCallbacks.count(side.color))
|
if(battleCallbacks.count(side.color))
|
||||||
battleCallbacks[side.color]->setBattle(nullptr);
|
battleCallbacks[side.color]->onBattleEnded(battleID);
|
||||||
|
|
||||||
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
||||||
battleCallbacks[PlayerColor::SPECTATOR]->setBattle(nullptr);
|
battleCallbacks[PlayerColor::SPECTATOR]->onBattleEnded(battleID);
|
||||||
|
|
||||||
setBattle(nullptr);
|
|
||||||
gs->curB.dellNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::startPlayerBattleAction(PlayerColor color)
|
void CClient::startPlayerBattleAction(const BattleID & battleID, PlayerColor color)
|
||||||
{
|
{
|
||||||
assert(vstd::contains(battleints, color));
|
assert(vstd::contains(battleints, color));
|
||||||
|
|
||||||
@ -661,7 +656,7 @@ void CClient::startPlayerBattleAction(PlayerColor color)
|
|||||||
auto unlock = vstd::makeUnlockGuardIf(*CPlayerInterface::pim, !battleints[color]->human);
|
auto unlock = vstd::makeUnlockGuardIf(*CPlayerInterface::pim, !battleints[color]->human);
|
||||||
|
|
||||||
assert(vstd::contains(battleints, color));
|
assert(vstd::contains(battleints, color));
|
||||||
battleints[color]->activeStack(gs->curB->battleGetStackByID(gs->curB->activeStack, false));
|
battleints[color]->activeStack(battleID, gs->getBattle(battleID)->battleGetStackByID(gs->getBattle(battleID)->activeStack, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ class CGameInterface;
|
|||||||
class BinaryDeserializer;
|
class BinaryDeserializer;
|
||||||
class BinarySerializer;
|
class BinarySerializer;
|
||||||
class BattleAction;
|
class BattleAction;
|
||||||
|
class BattleInfo;
|
||||||
|
|
||||||
template<typename T> class CApplier;
|
template<typename T> class CApplier;
|
||||||
|
|
||||||
@ -150,8 +151,8 @@ public:
|
|||||||
int sendRequest(const CPackForServer * request, PlayerColor player); //returns ID given to that request
|
int sendRequest(const CPackForServer * request, PlayerColor player); //returns ID given to that request
|
||||||
|
|
||||||
void battleStarted(const BattleInfo * info);
|
void battleStarted(const BattleInfo * info);
|
||||||
void battleFinished();
|
void battleFinished(const BattleID & battleID);
|
||||||
void startPlayerBattleAction(PlayerColor color);
|
void startPlayerBattleAction(const BattleID & battleID, PlayerColor color);
|
||||||
|
|
||||||
void invalidatePaths();
|
void invalidatePaths();
|
||||||
std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
|
std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
|
||||||
|
@ -95,18 +95,18 @@ void callAllInterfaces(CClient & cl, void (T::*ptr)(Args...), Args2 && ...args)
|
|||||||
|
|
||||||
//calls all normal interfaces and privileged ones, playerints may be updated when iterating over it, so we need a copy
|
//calls all normal interfaces and privileged ones, playerints may be updated when iterating over it, so we need a copy
|
||||||
template<typename T, typename ... Args, typename ... Args2>
|
template<typename T, typename ... Args, typename ... Args2>
|
||||||
void callBattleInterfaceIfPresentForBothSides(CClient & cl, void (T::*ptr)(Args...), Args2 && ...args)
|
void callBattleInterfaceIfPresentForBothSides(CClient & cl, const BattleID & battleID, void (T::*ptr)(Args...), Args2 && ...args)
|
||||||
{
|
{
|
||||||
assert(cl.gameState()->curB);
|
assert(cl.gameState()->getBattle(battleID));
|
||||||
|
|
||||||
if (!cl.gameState()->curB)
|
if (!cl.gameState()->getBattle(battleID))
|
||||||
{
|
{
|
||||||
logGlobal->error("Attempt to call battle interface without ongoing battle!");
|
logGlobal->error("Attempt to call battle interface without ongoing battle!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
callOnlyThatBattleInterface(cl, cl.gameState()->curB->sides[0].color, ptr, std::forward<Args2>(args)...);
|
callOnlyThatBattleInterface(cl, cl.gameState()->getBattle(battleID)->sides[0].color, ptr, std::forward<Args2>(args)...);
|
||||||
callOnlyThatBattleInterface(cl, cl.gameState()->curB->sides[1].color, ptr, std::forward<Args2>(args)...);
|
callOnlyThatBattleInterface(cl, cl.gameState()->getBattle(battleID)->sides[1].color, ptr, std::forward<Args2>(args)...);
|
||||||
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool() && LOCPLINT->battleInt)
|
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool() && LOCPLINT->battleInt)
|
||||||
{
|
{
|
||||||
callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, ptr, std::forward<Args2>(args)...);
|
callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, ptr, std::forward<Args2>(args)...);
|
||||||
@ -714,11 +714,11 @@ void ApplyClientNetPackVisitor::visitMapObjectSelectDialog(MapObjectSelectDialog
|
|||||||
void ApplyFirstClientNetPackVisitor::visitBattleStart(BattleStart & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleStart(BattleStart & pack)
|
||||||
{
|
{
|
||||||
// Cannot use the usual code because curB is not set yet
|
// Cannot use the usual code because curB is not set yet
|
||||||
callOnlyThatBattleInterface(cl, pack.info->sides[0].color, &IBattleEventsReceiver::battleStartBefore, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
callOnlyThatBattleInterface(cl, pack.info->sides[0].color, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
||||||
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
||||||
callOnlyThatBattleInterface(cl, pack.info->sides[1].color, &IBattleEventsReceiver::battleStartBefore, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
callOnlyThatBattleInterface(cl, pack.info->sides[1].color, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
||||||
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
||||||
callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, &IBattleEventsReceiver::battleStartBefore, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->sides[0].armyObject, pack.info->sides[1].armyObject,
|
||||||
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
pack.info->tile, pack.info->sides[0].hero, pack.info->sides[1].hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,12 +729,12 @@ void ApplyClientNetPackVisitor::visitBattleStart(BattleStart & pack)
|
|||||||
|
|
||||||
void ApplyFirstClientNetPackVisitor::visitBattleNextRound(BattleNextRound & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleNextRound(BattleNextRound & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleNewRoundFirst, pack.round);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleNewRoundFirst, pack.battleID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleNextRound(BattleNextRound & pack)
|
void ApplyClientNetPackVisitor::visitBattleNextRound(BattleNextRound & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleNewRound, pack.round);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleNewRound, pack.battleID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleSetActiveStack(BattleSetActiveStack & pack)
|
void ApplyClientNetPackVisitor::visitBattleSetActiveStack(BattleSetActiveStack & pack)
|
||||||
@ -742,56 +742,56 @@ void ApplyClientNetPackVisitor::visitBattleSetActiveStack(BattleSetActiveStack &
|
|||||||
if(!pack.askPlayerInterface)
|
if(!pack.askPlayerInterface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CStack *activated = gs.curB->battleGetStackByID(pack.stack);
|
const CStack *activated = gs.getBattle(pack.battleID)->battleGetStackByID(pack.stack);
|
||||||
PlayerColor playerToCall; //pack.player that will move activated stack
|
PlayerColor playerToCall; //pack.player that will move activated stack
|
||||||
if (activated->hasBonusOfType(BonusType::HYPNOTIZED))
|
if (activated->hasBonusOfType(BonusType::HYPNOTIZED))
|
||||||
{
|
{
|
||||||
playerToCall = (gs.curB->sides[0].color == activated->unitOwner()
|
playerToCall = (gs.getBattle(pack.battleID)->sides[0].color == activated->unitOwner()
|
||||||
? gs.curB->sides[1].color
|
? gs.getBattle(pack.battleID)->sides[1].color
|
||||||
: gs.curB->sides[0].color);
|
: gs.getBattle(pack.battleID)->sides[0].color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
playerToCall = activated->unitOwner();
|
playerToCall = activated->unitOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
cl.startPlayerBattleAction(playerToCall);
|
cl.startPlayerBattleAction(pack.battleID, playerToCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleLogMessage(BattleLogMessage & pack)
|
void ApplyClientNetPackVisitor::visitBattleLogMessage(BattleLogMessage & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleLogMessage, pack.lines);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleLogMessage, pack.battleID, pack.lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleTriggerEffect(BattleTriggerEffect & pack)
|
void ApplyClientNetPackVisitor::visitBattleTriggerEffect(BattleTriggerEffect & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleTriggerEffect, pack);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleTriggerEffect, pack.battleID, pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFirstClientNetPackVisitor::visitBattleUpdateGateState(BattleUpdateGateState & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleUpdateGateState(BattleUpdateGateState & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleGateStateChanged, pack.state);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleGateStateChanged, pack.battleID, pack.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFirstClientNetPackVisitor::visitBattleResult(BattleResult & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleResult(BattleResult & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleEnd, &pack, pack.queryID);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleEnd, pack.battleID, &pack, pack.queryID);
|
||||||
cl.battleFinished();
|
cl.battleFinished(pack.battleID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFirstClientNetPackVisitor::visitBattleStackMoved(BattleStackMoved & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleStackMoved(BattleStackMoved & pack)
|
||||||
{
|
{
|
||||||
const CStack * movedStack = gs.curB->battleGetStackByID(pack.stack);
|
const CStack * movedStack = gs.getBattle(pack.battleID)->battleGetStackByID(pack.stack);
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStackMoved, movedStack, pack.tilesToMove, pack.distance, pack.teleporting);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleStackMoved, pack.battleID, movedStack, pack.tilesToMove, pack.distance, pack.teleporting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFirstClientNetPackVisitor::visitBattleAttack(BattleAttack & pack)
|
void ApplyFirstClientNetPackVisitor::visitBattleAttack(BattleAttack & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleAttack, &pack);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleAttack, pack.battleID, &pack);
|
||||||
|
|
||||||
// battleStacksAttacked should be excuted before BattleAttack.applyGs() to play animation before damaging unit
|
// battleStacksAttacked should be excuted before BattleAttack.applyGs() to play animation before damaging unit
|
||||||
// so this has to be here instead of ApplyClientNetPackVisitor::visitBattleAttack()
|
// so this has to be here instead of ApplyClientNetPackVisitor::visitBattleAttack()
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStacksAttacked, pack.bsa, pack.shot());
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleStacksAttacked, pack.battleID, pack.bsa, pack.shot());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleAttack(BattleAttack & pack)
|
void ApplyClientNetPackVisitor::visitBattleAttack(BattleAttack & pack)
|
||||||
@ -801,23 +801,23 @@ void ApplyClientNetPackVisitor::visitBattleAttack(BattleAttack & pack)
|
|||||||
void ApplyFirstClientNetPackVisitor::visitStartAction(StartAction & pack)
|
void ApplyFirstClientNetPackVisitor::visitStartAction(StartAction & pack)
|
||||||
{
|
{
|
||||||
cl.currentBattleAction = std::make_unique<BattleAction>(pack.ba);
|
cl.currentBattleAction = std::make_unique<BattleAction>(pack.ba);
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::actionStarted, pack.ba);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::actionStarted, pack.battleID, pack.ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleSpellCast(BattleSpellCast & pack)
|
void ApplyClientNetPackVisitor::visitBattleSpellCast(BattleSpellCast & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleSpellCast, &pack);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleSpellCast, pack.battleID, &pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitSetStackEffect(SetStackEffect & pack)
|
void ApplyClientNetPackVisitor::visitSetStackEffect(SetStackEffect & pack)
|
||||||
{
|
{
|
||||||
//informing about effects
|
//informing about effects
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStacksEffectsSet, pack);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleStacksEffectsSet, pack.battleID, pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitStacksInjured(StacksInjured & pack)
|
void ApplyClientNetPackVisitor::visitStacksInjured(StacksInjured & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStacksAttacked, pack.stacks, false);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleStacksAttacked, pack.battleID, pack.stacks, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied & pack)
|
void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied & pack)
|
||||||
@ -829,24 +829,24 @@ void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied &
|
|||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleUnitsChanged(BattleUnitsChanged & pack)
|
void ApplyClientNetPackVisitor::visitBattleUnitsChanged(BattleUnitsChanged & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleUnitsChanged, pack.changedStacks);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleUnitsChanged, pack.battleID, pack.changedStacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitBattleObstaclesChanged(BattleObstaclesChanged & pack)
|
void ApplyClientNetPackVisitor::visitBattleObstaclesChanged(BattleObstaclesChanged & pack)
|
||||||
{
|
{
|
||||||
//inform interfaces about removed obstacles
|
//inform interfaces about removed obstacles
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleObstaclesChanged, pack.changes);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleObstaclesChanged, pack.battleID, pack.changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitCatapultAttack(CatapultAttack & pack)
|
void ApplyClientNetPackVisitor::visitCatapultAttack(CatapultAttack & pack)
|
||||||
{
|
{
|
||||||
//inform interfaces about catapult attack
|
//inform interfaces about catapult attack
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleCatapultAttacked, pack);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::battleCatapultAttacked, pack.battleID, pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitEndAction(EndAction & pack)
|
void ApplyClientNetPackVisitor::visitEndAction(EndAction & pack)
|
||||||
{
|
{
|
||||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::actionFinished, *cl.currentBattleAction);
|
callBattleInterfaceIfPresentForBothSides(cl, pack.battleID, &IBattleEventsReceiver::actionFinished, pack.battleID, *cl.currentBattleAction);
|
||||||
cl.currentBattleAction.reset();
|
cl.currentBattleAction.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ void BattleActionsController::enterCreatureCastingMode()
|
|||||||
spells::Target target;
|
spells::Target target;
|
||||||
target.emplace_back();
|
target.emplace_back();
|
||||||
|
|
||||||
spells::BattleCast cast(owner.curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
|
spells::BattleCast cast(owner.getBattle().get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
|
||||||
|
|
||||||
auto m = spell->battleMechanics(&cast);
|
auto m = spell->battleMechanics(&cast);
|
||||||
spells::detail::ProblemImpl ignored;
|
spells::detail::ProblemImpl ignored;
|
||||||
@ -207,7 +207,7 @@ std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActi
|
|||||||
data.creatureSpellsToCast.push_back(spell->id);
|
data.creatureSpellsToCast.push_back(spell->id);
|
||||||
|
|
||||||
data.tacticsMode = owner.tacticsMode;
|
data.tacticsMode = owner.tacticsMode;
|
||||||
auto allActions = owner.curInt->cb->getClientActionsForStack(stack, data);
|
auto allActions = owner.getBattle()->getClientActionsForStack(stack, data);
|
||||||
|
|
||||||
allActions.push_back(PossiblePlayerBattleAction::HERO_INFO);
|
allActions.push_back(PossiblePlayerBattleAction::HERO_INFO);
|
||||||
allActions.push_back(PossiblePlayerBattleAction::CREATURE_INFO);
|
allActions.push_back(PossiblePlayerBattleAction::CREATURE_INFO);
|
||||||
@ -231,7 +231,7 @@ void BattleActionsController::reorderPossibleActionsPriority(const CStack * stac
|
|||||||
case PossiblePlayerBattleAction::OBSTACLE:
|
case PossiblePlayerBattleAction::OBSTACLE:
|
||||||
if(!stack->hasBonusOfType(BonusType::NO_SPELLCAST_BY_DEFAULT) && targetStack != nullptr)
|
if(!stack->hasBonusOfType(BonusType::NO_SPELLCAST_BY_DEFAULT) && targetStack != nullptr)
|
||||||
{
|
{
|
||||||
PlayerColor stackOwner = owner.curInt->cb->battleGetOwner(targetStack);
|
PlayerColor stackOwner = owner.getBattle()->battleGetOwner(targetStack);
|
||||||
bool enemyTargetingPositiveSpellcast = item.spell().toSpell()->isPositive() && stackOwner != LOCPLINT->playerID;
|
bool enemyTargetingPositiveSpellcast = item.spell().toSpell()->isPositive() && stackOwner != LOCPLINT->playerID;
|
||||||
bool friendTargetingNegativeSpellcast = item.spell().toSpell()->isNegative() && stackOwner == LOCPLINT->playerID;
|
bool friendTargetingNegativeSpellcast = item.spell().toSpell()->isNegative() && stackOwner == LOCPLINT->playerID;
|
||||||
|
|
||||||
@ -300,12 +300,12 @@ void BattleActionsController::castThisSpell(SpellID spellID)
|
|||||||
//choosing possible targets
|
//choosing possible targets
|
||||||
const CGHeroInstance *castingHero = (owner.attackingHeroInstance->tempOwner == owner.curInt->playerID) ? owner.attackingHeroInstance : owner.defendingHeroInstance;
|
const CGHeroInstance *castingHero = (owner.attackingHeroInstance->tempOwner == owner.curInt->playerID) ? owner.attackingHeroInstance : owner.defendingHeroInstance;
|
||||||
assert(castingHero); // code below assumes non-null hero
|
assert(castingHero); // code below assumes non-null hero
|
||||||
PossiblePlayerBattleAction spellSelMode = owner.curInt->cb->getCasterAction(spellID.toSpell(), castingHero, spells::Mode::HERO);
|
PossiblePlayerBattleAction spellSelMode = owner.getBattle()->getCasterAction(spellID.toSpell(), castingHero, spells::Mode::HERO);
|
||||||
|
|
||||||
if (spellSelMode.get() == PossiblePlayerBattleAction::NO_LOCATION) //user does not have to select location
|
if (spellSelMode.get() == PossiblePlayerBattleAction::NO_LOCATION) //user does not have to select location
|
||||||
{
|
{
|
||||||
heroSpellToCast->aimToHex(BattleHex::INVALID);
|
heroSpellToCast->aimToHex(BattleHex::INVALID);
|
||||||
owner.curInt->cb->battleMakeSpellAction(*heroSpellToCast);
|
owner.curInt->cb->battleMakeSpellAction(owner.getBattleID(), *heroSpellToCast);
|
||||||
endCastingSpell();
|
endCastingSpell();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -353,10 +353,10 @@ const CSpell * BattleActionsController::getCurrentSpell(BattleHex hoveredHex)
|
|||||||
|
|
||||||
const CStack * BattleActionsController::getStackForHex(BattleHex hoveredHex)
|
const CStack * BattleActionsController::getStackForHex(BattleHex hoveredHex)
|
||||||
{
|
{
|
||||||
const CStack * shere = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
const CStack * shere = owner.getBattle()->battleGetStackByPos(hoveredHex, true);
|
||||||
if(shere)
|
if(shere)
|
||||||
return shere;
|
return shere;
|
||||||
return owner.curInt->cb->battleGetStackByPos(hoveredHex, false);
|
return owner.getBattle()->battleGetStackByPos(hoveredHex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action, BattleHex targetHex)
|
void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action, BattleHex targetHex)
|
||||||
@ -400,7 +400,7 @@ void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PossiblePlayerBattleAction::SHOOT:
|
case PossiblePlayerBattleAction::SHOOT:
|
||||||
if (owner.curInt->cb->battleHasShootingPenalty(owner.stacksController->getActiveStack(), targetHex))
|
if (owner.getBattle()->battleHasShootingPenalty(owner.stacksController->getActiveStack(), targetHex))
|
||||||
CCS->curh->set(Cursor::Combat::SHOOT_PENALTY);
|
CCS->curh->set(Cursor::Combat::SHOOT_PENALTY);
|
||||||
else
|
else
|
||||||
CCS->curh->set(Cursor::Combat::SHOOT);
|
CCS->curh->set(Cursor::Combat::SHOOT);
|
||||||
@ -482,7 +482,7 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
|||||||
case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return
|
case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return
|
||||||
{
|
{
|
||||||
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
||||||
DamageEstimation estimation = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), targetStack, attackFromHex);
|
DamageEstimation estimation = owner.getBattle()->battleEstimateDamage(owner.stacksController->getActiveStack(), targetStack, attackFromHex);
|
||||||
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
||||||
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
|||||||
{
|
{
|
||||||
const auto * shooter = owner.stacksController->getActiveStack();
|
const auto * shooter = owner.stacksController->getActiveStack();
|
||||||
|
|
||||||
DamageEstimation estimation = owner.curInt->cb->battleEstimateDamage(shooter, targetStack, shooter->getPosition());
|
DamageEstimation estimation = owner.getBattle()->battleEstimateDamage(shooter, targetStack, shooter->getPosition());
|
||||||
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
||||||
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, B
|
|||||||
case PossiblePlayerBattleAction::ATTACK:
|
case PossiblePlayerBattleAction::ATTACK:
|
||||||
case PossiblePlayerBattleAction::WALK_AND_ATTACK:
|
case PossiblePlayerBattleAction::WALK_AND_ATTACK:
|
||||||
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
|
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
|
||||||
if(owner.curInt->cb->battleCanAttack(owner.stacksController->getActiveStack(), targetStack, targetHex))
|
if(owner.getBattle()->battleCanAttack(owner.stacksController->getActiveStack(), targetStack, targetHex))
|
||||||
{
|
{
|
||||||
if (owner.fieldController->isTileAttackable(targetHex)) // move isTileAttackable to be part of battleCanAttack?
|
if (owner.fieldController->isTileAttackable(targetHex)) // move isTileAttackable to be part of battleCanAttack?
|
||||||
return true;
|
return true;
|
||||||
@ -601,7 +601,7 @@ bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, B
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
case PossiblePlayerBattleAction::SHOOT:
|
case PossiblePlayerBattleAction::SHOOT:
|
||||||
return owner.curInt->cb->battleCanShoot(owner.stacksController->getActiveStack(), targetHex);
|
return owner.getBattle()->battleCanShoot(owner.stacksController->getActiveStack(), targetHex);
|
||||||
|
|
||||||
case PossiblePlayerBattleAction::NO_LOCATION:
|
case PossiblePlayerBattleAction::NO_LOCATION:
|
||||||
return false;
|
return false;
|
||||||
@ -615,7 +615,7 @@ bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, B
|
|||||||
case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
|
case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
|
||||||
if(targetStack && targetStackOwned && targetStack != owner.stacksController->getActiveStack() && targetStack->alive()) //only positive spells for other allied creatures
|
if(targetStack && targetStackOwned && targetStack != owner.stacksController->getActiveStack() && targetStack->alive()) //only positive spells for other allied creatures
|
||||||
{
|
{
|
||||||
int spellID = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), targetStack, CBattleInfoCallback::RANDOM_GENIE);
|
int spellID = owner.getBattle()->battleGetRandomStackSpell(CRandomGenerator::getDefault(), targetStack, CBattleInfoCallback::RANDOM_GENIE);
|
||||||
return spellID > -1;
|
return spellID > -1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -658,7 +658,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
|
|||||||
{
|
{
|
||||||
if(owner.stacksController->getActiveStack()->doubleWide())
|
if(owner.stacksController->getActiveStack()->doubleWide())
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack(), false);
|
std::vector<BattleHex> acc = owner.getBattle()->battleGetAvailableHexes(owner.stacksController->getActiveStack(), false);
|
||||||
BattleHex shiftedDest = targetHex.cloneInDirection(owner.stacksController->getActiveStack()->destShiftDir(), false);
|
BattleHex shiftedDest = targetHex.cloneInDirection(owner.stacksController->getActiveStack()->destShiftDir(), false);
|
||||||
if(vstd::contains(acc, targetHex))
|
if(vstd::contains(acc, targetHex))
|
||||||
owner.giveCommand(EActionType::WALK, targetHex);
|
owner.giveCommand(EActionType::WALK, targetHex);
|
||||||
@ -770,7 +770,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
|
|||||||
heroSpellToCast->aimToHex(targetHex);
|
heroSpellToCast->aimToHex(targetHex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
owner.curInt->cb->battleMakeSpellAction(*heroSpellToCast);
|
owner.curInt->cb->battleMakeSpellAction(owner.getBattleID(), *heroSpellToCast);
|
||||||
endCastingSpell();
|
endCastingSpell();
|
||||||
}
|
}
|
||||||
selectedStack = nullptr;
|
selectedStack = nullptr;
|
||||||
@ -886,7 +886,7 @@ void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterS
|
|||||||
{
|
{
|
||||||
// faerie dragon can cast only one, randomly selected spell until their next move
|
// faerie dragon can cast only one, randomly selected spell until their next move
|
||||||
//TODO: faerie dragon type spell should be selected by server
|
//TODO: faerie dragon type spell should be selected by server
|
||||||
const auto * spellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), casterStack, CBattleInfoCallback::RANDOM_AIMED).toSpell();
|
const auto * spellToCast = owner.getBattle()->battleGetRandomStackSpell(CRandomGenerator::getDefault(), casterStack, CBattleInfoCallback::RANDOM_AIMED).toSpell();
|
||||||
|
|
||||||
if (spellToCast)
|
if (spellToCast)
|
||||||
creatureSpells.push_back(spellToCast);
|
creatureSpells.push_back(spellToCast);
|
||||||
@ -933,7 +933,7 @@ bool BattleActionsController::isCastingPossibleHere(const CSpell * currentSpell,
|
|||||||
target.emplace_back(targetStack);
|
target.emplace_back(targetStack);
|
||||||
target.emplace_back(targetHex);
|
target.emplace_back(targetHex);
|
||||||
|
|
||||||
spells::BattleCast cast(owner.curInt->cb.get(), caster, mode, currentSpell);
|
spells::BattleCast cast(owner.getBattle().get(), caster, mode, currentSpell);
|
||||||
|
|
||||||
auto m = currentSpell->battleMechanics(&cast);
|
auto m = currentSpell->battleMechanics(&cast);
|
||||||
spells::detail::ProblemImpl problem; //todo: display problem in status bar
|
spells::detail::ProblemImpl problem; //todo: display problem in status bar
|
||||||
@ -943,7 +943,7 @@ bool BattleActionsController::isCastingPossibleHere(const CSpell * currentSpell,
|
|||||||
|
|
||||||
bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, BattleHex myNumber) const
|
bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, BattleHex myNumber) const
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(stackToMove, false);
|
std::vector<BattleHex> acc = owner.getBattle()->battleGetAvailableHexes(stackToMove, false);
|
||||||
BattleHex shiftedDest = myNumber.cloneInDirection(stackToMove->destShiftDir(), false);
|
BattleHex shiftedDest = myNumber.cloneInDirection(stackToMove->destShiftDir(), false);
|
||||||
|
|
||||||
if (vstd::contains(acc, myNumber))
|
if (vstd::contains(acc, myNumber))
|
||||||
@ -1006,7 +1006,7 @@ void BattleActionsController::onHexRightClicked(BattleHex clickedHex)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto selectedStack = owner.curInt->cb->battleGetStackByPos(clickedHex, true);
|
auto selectedStack = owner.getBattle()->battleGetStackByPos(clickedHex, true);
|
||||||
|
|
||||||
if (selectedStack != nullptr)
|
if (selectedStack != nullptr)
|
||||||
GH.windows().createAndPushWindow<CStackWindow>(selectedStack, true);
|
GH.windows().createAndPushWindow<CStackWindow>(selectedStack, true);
|
||||||
|
@ -970,7 +970,7 @@ bool EffectAnimation::init()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto * destStack = owner.getCurrentPlayerInterface()->cb->battleGetUnitByPos(battlehexes[i], false);
|
const auto * destStack = owner.getBattle()->battleGetUnitByPos(battlehexes[i], false);
|
||||||
Rect tilePos = owner.fieldController->hexPositionLocal(battlehexes[i]);
|
Rect tilePos = owner.fieldController->hexPositionLocal(battlehexes[i]);
|
||||||
|
|
||||||
be.pos.x = tilePos.x + tilePos.w/2 - first->width()/2;
|
be.pos.x = tilePos.x + tilePos.w/2 - first->width()/2;
|
||||||
|
@ -59,7 +59,7 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
|
|||||||
{
|
{
|
||||||
owner.checkForAnimations();
|
owner.checkForAnimations();
|
||||||
|
|
||||||
const CStack * stack = owner.curInt->cb->battleGetStackByID(bte.stackID);
|
const CStack * stack = owner.getBattle()->battleGetStackByID(bte.stackID);
|
||||||
if(!stack)
|
if(!stack)
|
||||||
{
|
{
|
||||||
logGlobal->error("Invalid stack ID %d", bte.stackID);
|
logGlobal->error("Invalid stack ID %d", bte.stackID);
|
||||||
@ -98,7 +98,7 @@ void BattleEffectsController::startAction(const BattleAction & action)
|
|||||||
{
|
{
|
||||||
owner.checkForAnimations();
|
owner.checkForAnimations();
|
||||||
|
|
||||||
const CStack *stack = owner.curInt->cb->battleGetStackByID(action.stackNumber);
|
const CStack *stack = owner.getBattle()->battleGetStackByID(action.stackNumber);
|
||||||
|
|
||||||
switch(action.actionType)
|
switch(action.actionType)
|
||||||
{
|
{
|
||||||
|
@ -141,7 +141,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
|
|||||||
|
|
||||||
if(!owner.siegeController)
|
if(!owner.siegeController)
|
||||||
{
|
{
|
||||||
auto bfieldType = owner.curInt->cb->battleGetBattlefieldType();
|
auto bfieldType = owner.getBattle()->battleGetBattlefieldType();
|
||||||
|
|
||||||
if(bfieldType == BattleField::NONE)
|
if(bfieldType == BattleField::NONE)
|
||||||
logGlobal->error("Invalid battlefield returned for current battle");
|
logGlobal->error("Invalid battlefield returned for current battle");
|
||||||
@ -284,7 +284,7 @@ void BattleFieldController::redrawBackgroundWithHexes()
|
|||||||
const CStack *activeStack = owner.stacksController->getActiveStack();
|
const CStack *activeStack = owner.stacksController->getActiveStack();
|
||||||
std::vector<BattleHex> attackableHexes;
|
std::vector<BattleHex> attackableHexes;
|
||||||
if(activeStack)
|
if(activeStack)
|
||||||
occupiableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, false, true, &attackableHexes);
|
occupiableHexes = owner.getBattle()->battleGetAvailableHexes(activeStack, false, true, &attackableHexes);
|
||||||
|
|
||||||
// prepare background graphic with hexes and shaded hexes
|
// prepare background graphic with hexes and shaded hexes
|
||||||
backgroundWithHexes->draw(background, Point(0,0));
|
backgroundWithHexes->draw(background, Point(0,0));
|
||||||
@ -339,7 +339,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesForActiveStack()
|
|||||||
|
|
||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
|
|
||||||
std::set<BattleHex> set = owner.curInt->cb->battleGetAttackedHexes(owner.stacksController->getActiveStack(), hoveredHex);
|
std::set<BattleHex> set = owner.getBattle()->battleGetAttackedHexes(owner.stacksController->getActiveStack(), hoveredHex);
|
||||||
for(BattleHex hex : set)
|
for(BattleHex hex : set)
|
||||||
result.insert(hex);
|
result.insert(hex);
|
||||||
|
|
||||||
@ -359,10 +359,10 @@ std::set<BattleHex> BattleFieldController::getMovementRangeForHoveredStack()
|
|||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
|
|
||||||
// add possible movement hexes for stack under mouse
|
// add possible movement hexes for stack under mouse
|
||||||
const CStack * const hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
const CStack * const hoveredStack = owner.getBattle()->battleGetStackByPos(hoveredHex, true);
|
||||||
if(hoveredStack)
|
if(hoveredStack)
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> v = owner.curInt->cb->battleGetAvailableHexes(hoveredStack, true, true, nullptr);
|
std::vector<BattleHex> v = owner.getBattle()->battleGetAvailableHexes(hoveredStack, true, true, nullptr);
|
||||||
for(BattleHex hex : v)
|
for(BattleHex hex : v)
|
||||||
result.insert(hex);
|
result.insert(hex);
|
||||||
}
|
}
|
||||||
@ -387,7 +387,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesForSpellRange()
|
|||||||
if(caster && spell) //when casting spell
|
if(caster && spell) //when casting spell
|
||||||
{
|
{
|
||||||
// printing shaded hex(es)
|
// printing shaded hex(es)
|
||||||
spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
|
spells::BattleCast event(owner.getBattle().get(), caster, mode, spell);
|
||||||
auto shadedHexes = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
|
auto shadedHexes = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
|
||||||
|
|
||||||
for(BattleHex shadedHex : shadedHexes)
|
for(BattleHex shadedHex : shadedHexes)
|
||||||
@ -407,10 +407,10 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesForMovementTarget(
|
|||||||
if(!stack)
|
if(!stack)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::vector<BattleHex> availableHexes = owner.curInt->cb->battleGetAvailableHexes(stack, false, false, nullptr);
|
std::vector<BattleHex> availableHexes = owner.getBattle()->battleGetAvailableHexes(stack, false, false, nullptr);
|
||||||
|
|
||||||
auto hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
auto hoveredStack = owner.getBattle()->battleGetStackByPos(hoveredHex, true);
|
||||||
if(owner.curInt->cb->battleCanAttack(stack, hoveredStack, hoveredHex))
|
if(owner.getBattle()->battleCanAttack(stack, hoveredStack, hoveredHex))
|
||||||
{
|
{
|
||||||
if(isTileAttackable(hoveredHex))
|
if(isTileAttackable(hoveredHex))
|
||||||
{
|
{
|
||||||
@ -670,7 +670,7 @@ BattleHex BattleFieldController::getHoveredHex()
|
|||||||
const CStack* BattleFieldController::getHoveredStack()
|
const CStack* BattleFieldController::getHoveredStack()
|
||||||
{
|
{
|
||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
const CStack* hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
const CStack* hoveredStack = owner.getBattle()->battleGetStackByPos(hoveredHex, true);
|
||||||
|
|
||||||
return hoveredStack;
|
return hoveredStack;
|
||||||
}
|
}
|
||||||
@ -856,7 +856,7 @@ bool BattleFieldController::isTileAttackable(const BattleHex & number) const
|
|||||||
|
|
||||||
void BattleFieldController::updateAccessibleHexes()
|
void BattleFieldController::updateAccessibleHexes()
|
||||||
{
|
{
|
||||||
auto accessibility = owner.curInt->cb->getAccesibility();
|
auto accessibility = owner.getBattle()->getAccesibility();
|
||||||
|
|
||||||
for(int i = 0; i < accessibility.size(); i++)
|
for(int i = 0; i < accessibility.size(); i++)
|
||||||
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE || (accessibility[i] == EAccessibility::SIDE_COLUMN));
|
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE || (accessibility[i] == EAccessibility::SIDE_COLUMN));
|
||||||
|
@ -68,9 +68,9 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
|||||||
}
|
}
|
||||||
|
|
||||||
//hot-seat -> check tactics for both players (defender may be local human)
|
//hot-seat -> check tactics for both players (defender may be local human)
|
||||||
if(attackerInt && attackerInt->cb->battleGetTacticDist())
|
if(attackerInt && attackerInt->cb->getBattle(getBattleID())->battleGetTacticDist())
|
||||||
tacticianInterface = attackerInt;
|
tacticianInterface = attackerInt;
|
||||||
else if(defenderInt && defenderInt->cb->battleGetTacticDist())
|
else if(defenderInt && defenderInt->cb->getBattle(getBattleID())->battleGetTacticDist())
|
||||||
tacticianInterface = defenderInt;
|
tacticianInterface = defenderInt;
|
||||||
|
|
||||||
//if we found interface of player with tactics, then enter tactics mode
|
//if we found interface of player with tactics, then enter tactics mode
|
||||||
@ -80,7 +80,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
|||||||
this->army1 = army1;
|
this->army1 = army1;
|
||||||
this->army2 = army2;
|
this->army2 = army2;
|
||||||
|
|
||||||
const CGTownInstance *town = curInt->cb->battleGetDefendedTown();
|
const CGTownInstance *town = getBattle()->battleGetDefendedTown();
|
||||||
if(town && town->hasFort())
|
if(town && town->hasFort())
|
||||||
siegeController.reset(new BattleSiegeController(*this, town));
|
siegeController.reset(new BattleSiegeController(*this, town));
|
||||||
|
|
||||||
@ -223,12 +223,12 @@ void BattleInterface::stackAttacking( const StackAttackInfo & attackInfo )
|
|||||||
stacksController->stackAttacking(attackInfo);
|
stacksController->stackAttacking(attackInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleInterface::newRoundFirst( int round )
|
void BattleInterface::newRoundFirst()
|
||||||
{
|
{
|
||||||
waitForAnimations();
|
waitForAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleInterface::newRound(int number)
|
void BattleInterface::newRound()
|
||||||
{
|
{
|
||||||
console->addText(CGI->generaltexth->allTexts[412]);
|
console->addText(CGI->generaltexth->allTexts[412]);
|
||||||
}
|
}
|
||||||
@ -241,7 +241,7 @@ void BattleInterface::giveCommand(EActionType action, BattleHex tile, SpellID sp
|
|||||||
actor = stacksController->getActiveStack();
|
actor = stacksController->getActiveStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto side = curInt->cb->playerToSide(curInt->playerID);
|
auto side = getBattle()->playerToSide(curInt->playerID);
|
||||||
if(!side)
|
if(!side)
|
||||||
{
|
{
|
||||||
logGlobal->error("Player %s is not in battle", curInt->playerID.toString());
|
logGlobal->error("Player %s is not in battle", curInt->playerID.toString());
|
||||||
@ -265,11 +265,11 @@ void BattleInterface::sendCommand(BattleAction command, const CStack * actor)
|
|||||||
{
|
{
|
||||||
logGlobal->trace("Setting command for %s", (actor ? actor->nodeName() : "hero"));
|
logGlobal->trace("Setting command for %s", (actor ? actor->nodeName() : "hero"));
|
||||||
stacksController->setActiveStack(nullptr);
|
stacksController->setActiveStack(nullptr);
|
||||||
curInt->cb->battleMakeUnitAction(command);
|
curInt->cb->battleMakeUnitAction(battleID, command);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
curInt->cb->battleMakeTacticAction(command);
|
curInt->cb->battleMakeTacticAction(battleID, command);
|
||||||
stacksController->setActiveStack(nullptr);
|
stacksController->setActiveStack(nullptr);
|
||||||
//next stack will be activated when action ends
|
//next stack will be activated when action ends
|
||||||
}
|
}
|
||||||
@ -368,13 +368,13 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
|
|
||||||
if ( sc->activeCast )
|
if ( sc->activeCast )
|
||||||
{
|
{
|
||||||
const CStack * casterStack = curInt->cb->battleGetStackByID(sc->casterStack);
|
const CStack * casterStack = getBattle()->battleGetStackByID(sc->casterStack);
|
||||||
|
|
||||||
if(casterStack != nullptr )
|
if(casterStack != nullptr )
|
||||||
{
|
{
|
||||||
addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
|
addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
|
||||||
{
|
{
|
||||||
stacksController->addNewAnim(new CastAnimation(*this, casterStack, targetedTile, curInt->cb->battleGetStackByPos(targetedTile), spell));
|
stacksController->addNewAnim(new CastAnimation(*this, casterStack, targetedTile, getBattle()->battleGetStackByPos(targetedTile), spell));
|
||||||
displaySpellCast(spell, casterStack->getPosition());
|
displaySpellCast(spell, casterStack->getPosition());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -385,7 +385,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
|
|
||||||
addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
|
addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
|
||||||
{
|
{
|
||||||
stacksController->addNewAnim(new HeroCastAnimation(*this, hero, targetedTile, curInt->cb->battleGetStackByPos(targetedTile), spell));
|
stacksController->addNewAnim(new HeroCastAnimation(*this, hero, targetedTile, getBattle()->battleGetStackByPos(targetedTile), spell));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +397,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
//queuing affect animation
|
//queuing affect animation
|
||||||
for(auto & elem : sc->affectedCres)
|
for(auto & elem : sc->affectedCres)
|
||||||
{
|
{
|
||||||
auto stack = curInt->cb->battleGetStackByID(elem, false);
|
auto stack = getBattle()->battleGetStackByID(elem, false);
|
||||||
assert(stack);
|
assert(stack);
|
||||||
if(stack)
|
if(stack)
|
||||||
{
|
{
|
||||||
@ -409,7 +409,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
|
|
||||||
for(auto & elem : sc->reflectedCres)
|
for(auto & elem : sc->reflectedCres)
|
||||||
{
|
{
|
||||||
auto stack = curInt->cb->battleGetStackByID(elem, false);
|
auto stack = getBattle()->battleGetStackByID(elem, false);
|
||||||
assert(stack);
|
assert(stack);
|
||||||
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
||||||
effectsController->displayEffect(EBattleEffect::MAGIC_MIRROR, stack->getPosition());
|
effectsController->displayEffect(EBattleEffect::MAGIC_MIRROR, stack->getPosition());
|
||||||
@ -425,7 +425,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
|
|
||||||
for(auto & elem : sc->resistedCres)
|
for(auto & elem : sc->resistedCres)
|
||||||
{
|
{
|
||||||
auto stack = curInt->cb->battleGetStackByID(elem, false);
|
auto stack = getBattle()->battleGetStackByID(elem, false);
|
||||||
assert(stack);
|
assert(stack);
|
||||||
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
||||||
effectsController->displayEffect(EBattleEffect::RESISTANCE, stack->getPosition());
|
effectsController->displayEffect(EBattleEffect::RESISTANCE, stack->getPosition());
|
||||||
@ -487,7 +487,7 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell * spell, const CSp
|
|||||||
|
|
||||||
if (!animation.effectName.empty())
|
if (!animation.effectName.empty())
|
||||||
{
|
{
|
||||||
const CStack * destStack = getCurrentPlayerInterface()->cb->battleGetStackByPos(destinationTile, false);
|
const CStack * destStack = getBattle()->battleGetStackByPos(destinationTile, false);
|
||||||
|
|
||||||
if (destStack)
|
if (destStack)
|
||||||
stacksController->addNewAnim(new ColorTransformAnimation(*this, destStack, animation.effectName, spell ));
|
stacksController->addNewAnim(new ColorTransformAnimation(*this, destStack, animation.effectName, spell ));
|
||||||
@ -566,12 +566,22 @@ bool BattleInterface::makingTurn() const
|
|||||||
return stacksController->getActiveStack() != nullptr;
|
return stacksController->getActiveStack() != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BattleID BattleInterface::getBattleID() const
|
||||||
|
{
|
||||||
|
return battleID;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CPlayerBattleCallback> BattleInterface::getBattle() const
|
||||||
|
{
|
||||||
|
return curInt->cb->getBattle(battleID);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleInterface::endAction(const BattleAction &action)
|
void BattleInterface::endAction(const BattleAction &action)
|
||||||
{
|
{
|
||||||
// it is possible that tactics mode ended while opening music is still playing
|
// it is possible that tactics mode ended while opening music is still playing
|
||||||
waitForAnimations();
|
waitForAnimations();
|
||||||
|
|
||||||
const CStack *stack = curInt->cb->battleGetStackByID(action.stackNumber);
|
const CStack *stack = getBattle()->battleGetStackByID(action.stackNumber);
|
||||||
|
|
||||||
// Activate stack from stackToActivate because this might have been temporary disabled, e.g., during spell cast
|
// Activate stack from stackToActivate because this might have been temporary disabled, e.g., during spell cast
|
||||||
activateStack();
|
activateStack();
|
||||||
@ -606,7 +616,7 @@ void BattleInterface::startAction(const BattleAction & action)
|
|||||||
if (!action.isUnitAction())
|
if (!action.isUnitAction())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(curInt->cb->battleGetStackByID(action.stackNumber));
|
assert(getBattle()->battleGetStackByID(action.stackNumber));
|
||||||
windowObject->updateQueue();
|
windowObject->updateQueue();
|
||||||
effectsController->startAction(action);
|
effectsController->startAction(action);
|
||||||
}
|
}
|
||||||
@ -616,10 +626,10 @@ void BattleInterface::tacticPhaseEnd()
|
|||||||
stacksController->setActiveStack(nullptr);
|
stacksController->setActiveStack(nullptr);
|
||||||
tacticsMode = false;
|
tacticsMode = false;
|
||||||
|
|
||||||
auto side = tacticianInterface->cb->playerToSide(tacticianInterface->playerID);
|
auto side = tacticianInterface->cb->getBattle(battleID)->playerToSide(tacticianInterface->playerID);
|
||||||
auto action = BattleAction::makeEndOFTacticPhase(*side);
|
auto action = BattleAction::makeEndOFTacticPhase(*side);
|
||||||
|
|
||||||
tacticianInterface->cb->battleMakeTacticAction(action);
|
tacticianInterface->cb->battleMakeTacticAction(battleID, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool immobile(const CStack *s)
|
static bool immobile(const CStack *s)
|
||||||
@ -635,7 +645,7 @@ void BattleInterface::tacticNextStack(const CStack * current)
|
|||||||
//no switching stacks when the current one is moving
|
//no switching stacks when the current one is moving
|
||||||
checkForAnimations();
|
checkForAnimations();
|
||||||
|
|
||||||
TStacks stacksOfMine = tacticianInterface->cb->battleGetStacks(CBattleCallback::ONLY_MINE);
|
TStacks stacksOfMine = tacticianInterface->cb->getBattle(battleID)->battleGetStacks(CPlayerBattleCallback::ONLY_MINE);
|
||||||
vstd::erase_if (stacksOfMine, &immobile);
|
vstd::erase_if (stacksOfMine, &immobile);
|
||||||
if (stacksOfMine.empty())
|
if (stacksOfMine.empty())
|
||||||
{
|
{
|
||||||
@ -687,7 +697,7 @@ void BattleInterface::requestAutofightingAIToTakeAction()
|
|||||||
{
|
{
|
||||||
assert(curInt->isAutoFightOn);
|
assert(curInt->isAutoFightOn);
|
||||||
|
|
||||||
if(curInt->cb->battleIsFinished())
|
if(getBattle()->battleIsFinished())
|
||||||
{
|
{
|
||||||
return; // battle finished with spellcast
|
return; // battle finished with spellcast
|
||||||
}
|
}
|
||||||
@ -716,7 +726,7 @@ void BattleInterface::requestAutofightingAIToTakeAction()
|
|||||||
boost::thread aiThread([this, activeStack]()
|
boost::thread aiThread([this, activeStack]()
|
||||||
{
|
{
|
||||||
setThreadName("autofightingAI");
|
setThreadName("autofightingAI");
|
||||||
curInt->autofightingAI->activeStack(activeStack);
|
curInt->autofightingAI->activeStack(battleID, activeStack);
|
||||||
});
|
});
|
||||||
aiThread.detach();
|
aiThread.detach();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ struct BattleTriggerEffect;
|
|||||||
struct BattleHex;
|
struct BattleHex;
|
||||||
struct InfoAboutHero;
|
struct InfoAboutHero;
|
||||||
class ObstacleChanges;
|
class ObstacleChanges;
|
||||||
|
class CPlayerBattleCallback;
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
@ -115,6 +116,9 @@ class BattleInterface
|
|||||||
/// if set to true, battle is still starting and waiting for intro sound to end / key press from player
|
/// if set to true, battle is still starting and waiting for intro sound to end / key press from player
|
||||||
bool battleOpeningDelayActive;
|
bool battleOpeningDelayActive;
|
||||||
|
|
||||||
|
/// ID of ongoing battle
|
||||||
|
BattleID battleID;
|
||||||
|
|
||||||
void playIntroSoundAndUnlockInterface();
|
void playIntroSoundAndUnlockInterface();
|
||||||
void onIntroSoundPlayed();
|
void onIntroSoundPlayed();
|
||||||
public:
|
public:
|
||||||
@ -149,6 +153,9 @@ public:
|
|||||||
|
|
||||||
bool makingTurn() const;
|
bool makingTurn() const;
|
||||||
|
|
||||||
|
BattleID getBattleID() const;
|
||||||
|
std::shared_ptr<CPlayerBattleCallback> getBattle() const;
|
||||||
|
|
||||||
BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr);
|
BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr);
|
||||||
~BattleInterface();
|
~BattleInterface();
|
||||||
|
|
||||||
@ -196,8 +203,8 @@ public:
|
|||||||
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance, bool teleport); //stack with id number moved to destHex
|
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance, bool teleport); //stack with id number moved to destHex
|
||||||
void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
|
void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
|
||||||
void stackAttacking(const StackAttackInfo & attackInfo); //called when stack with id ID is attacking something on hex dest
|
void stackAttacking(const StackAttackInfo & attackInfo); //called when stack with id ID is attacking something on hex dest
|
||||||
void newRoundFirst( int round );
|
void newRoundFirst();
|
||||||
void newRound(int number); //caled when round is ended; number is the number of round
|
void newRound(); //caled when round is ended;
|
||||||
void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
|
void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
|
||||||
void battleFinished(const BattleResult& br, QueryID queryID); //called when battle is finished - battleresult window should be printed
|
void battleFinished(const BattleResult& br, QueryID queryID); //called when battle is finished - battleresult window should be printed
|
||||||
void spellCast(const BattleSpellCast *sc); //called when a hero casts a spell
|
void spellCast(const BattleSpellCast *sc); //called when a hero casts a spell
|
||||||
|
@ -289,7 +289,7 @@ void BattleHero::heroLeftClicked()
|
|||||||
if(!hero || !owner.makingTurn())
|
if(!hero || !owner.makingTurn())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(owner.getCurrentPlayerInterface()->cb->battleCanCastSpell(hero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
|
if(owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
|
||||||
{
|
{
|
||||||
CCS->curh->set(Cursor::Map::POINTER);
|
CCS->curh->set(Cursor::Map::POINTER);
|
||||||
GH.windows().createAndPushWindow<CSpellWindow>(hero, owner.getCurrentPlayerInterface());
|
GH.windows().createAndPushWindow<CSpellWindow>(hero, owner.getCurrentPlayerInterface());
|
||||||
@ -502,7 +502,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
auto heroInfo = owner.cb->battleGetHeroInfo(i);
|
auto heroInfo = owner.cb->getBattle(br.battleID)->battleGetHeroInfo(i);
|
||||||
const int xs[] = {21, 392};
|
const int xs[] = {21, 392};
|
||||||
|
|
||||||
if(heroInfo.portrait >= 0) //attacking hero
|
if(heroInfo.portrait >= 0) //attacking hero
|
||||||
@ -512,7 +512,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto stacks = owner.cb->battleGetAllStacks();
|
auto stacks = owner.cb->getBattle(br.battleID)->battleGetAllStacks();
|
||||||
vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
|
vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
|
||||||
{
|
{
|
||||||
return stack->unitSide() != i || !stack->base;
|
return stack->unitSide() != i || !stack->base;
|
||||||
@ -561,7 +561,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//printing result description
|
//printing result description
|
||||||
bool weAreAttacker = !(owner.cb->battleGetMySide());
|
bool weAreAttacker = !(owner.cb->getBattle(br.battleID)->battleGetMySide());
|
||||||
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
|
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
|
||||||
{
|
{
|
||||||
int text = 304;
|
int text = 304;
|
||||||
@ -584,7 +584,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
CCS->videoh->open("WIN3.BIK");
|
CCS->videoh->open("WIN3.BIK");
|
||||||
std::string str = CGI->generaltexth->allTexts[text];
|
std::string str = CGI->generaltexth->allTexts[text];
|
||||||
|
|
||||||
const CGHeroInstance * ourHero = owner.cb->battleGetMyHero();
|
const CGHeroInstance * ourHero = owner.cb->getBattle(br.battleID)->battleGetMyHero();
|
||||||
if (ourHero)
|
if (ourHero)
|
||||||
{
|
{
|
||||||
str += CGI->generaltexth->allTexts[305];
|
str += CGI->generaltexth->allTexts[305];
|
||||||
@ -714,7 +714,7 @@ void StackQueue::update()
|
|||||||
{
|
{
|
||||||
std::vector<battle::Units> queueData;
|
std::vector<battle::Units> queueData;
|
||||||
|
|
||||||
owner.getCurrentPlayerInterface()->cb->battleGetTurnOrder(queueData, stackBoxes.size(), 0);
|
owner.getBattle()->battleGetTurnOrder(queueData, stackBoxes.size(), 0);
|
||||||
|
|
||||||
size_t boxIndex = 0;
|
size_t boxIndex = 0;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ BattleObstacleController::BattleObstacleController(BattleInterface & owner):
|
|||||||
owner(owner),
|
owner(owner),
|
||||||
timePassed(0.f)
|
timePassed(0.f)
|
||||||
{
|
{
|
||||||
auto obst = owner.curInt->cb->battleGetAllObstacles();
|
auto obst = owner.getBattle()->battleGetAllObstacles();
|
||||||
for(auto & elem : obst)
|
for(auto & elem : obst)
|
||||||
{
|
{
|
||||||
if ( elem->obstacleType == CObstacleInstance::MOAT )
|
if ( elem->obstacleType == CObstacleInstance::MOAT )
|
||||||
@ -99,9 +99,9 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
|
|||||||
{
|
{
|
||||||
for(const auto & oi : obstacles)
|
for(const auto & oi : obstacles)
|
||||||
{
|
{
|
||||||
auto side = owner.curInt->cb->playerToSide(owner.curInt->playerID);
|
auto side = owner.getBattle()->playerToSide(owner.curInt->playerID);
|
||||||
|
|
||||||
if(!oi->visibleForSide(side.value(), owner.curInt->cb->battleHasNativeStack(side.value())))
|
if(!oi->visibleForSide(side.value(), owner.getBattle()->battleHasNativeStack(side.value())))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto animation = std::make_shared<CAnimation>(oi->getAppearAnimation());
|
auto animation = std::make_shared<CAnimation>(oi->getAppearAnimation());
|
||||||
@ -127,7 +127,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
|
|||||||
void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas)
|
void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas)
|
||||||
{
|
{
|
||||||
//Blit absolute obstacles
|
//Blit absolute obstacles
|
||||||
for(auto & obstacle : owner.curInt->cb->battleGetAllObstacles())
|
for(auto & obstacle : owner.getBattle()->battleGetAllObstacles())
|
||||||
{
|
{
|
||||||
if(obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
if(obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
||||||
{
|
{
|
||||||
@ -153,7 +153,7 @@ void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas)
|
|||||||
|
|
||||||
void BattleObstacleController::collectRenderableObjects(BattleRenderer & renderer)
|
void BattleObstacleController::collectRenderableObjects(BattleRenderer & renderer)
|
||||||
{
|
{
|
||||||
for (auto obstacle : owner.curInt->cb->battleGetAllObstacles())
|
for (auto obstacle : owner.getBattle()->battleGetAllObstacles())
|
||||||
{
|
{
|
||||||
if (obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
if (obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -133,9 +133,9 @@ bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what)
|
|||||||
{
|
{
|
||||||
case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
|
case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
|
||||||
case EWallVisual::MOAT_BANK: return town->hasBuilt(BuildingID::CITADEL) && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
|
case EWallVisual::MOAT_BANK: return town->hasBuilt(BuildingID::CITADEL) && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
|
||||||
case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && owner.curInt->cb->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
|
case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && owner.getBattle()->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
|
||||||
case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
|
case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.getBattle()->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
|
||||||
case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
|
case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.getBattle()->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
|
||||||
default: return true;
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con
|
|||||||
|
|
||||||
void BattleSiegeController::gateStateChanged(const EGateState state)
|
void BattleSiegeController::gateStateChanged(const EGateState state)
|
||||||
{
|
{
|
||||||
auto oldState = owner.curInt->cb->battleGetGateState();
|
auto oldState = owner.getBattle()->battleGetGateState();
|
||||||
bool playSound = false;
|
bool playSound = false;
|
||||||
auto stateId = EWallState::NONE;
|
auto stateId = EWallState::NONE;
|
||||||
switch(state)
|
switch(state)
|
||||||
@ -275,7 +275,7 @@ BattleHex BattleSiegeController::getTurretBattleHex(EWallVisual::EWallVisual wal
|
|||||||
|
|
||||||
const CStack * BattleSiegeController::getTurretStack(EWallVisual::EWallVisual wallPiece) const
|
const CStack * BattleSiegeController::getTurretStack(EWallVisual::EWallVisual wallPiece) const
|
||||||
{
|
{
|
||||||
for (auto & stack : owner.curInt->cb->battleGetAllStacks(true))
|
for (auto & stack : owner.getBattle()->battleGetAllStacks(true))
|
||||||
{
|
{
|
||||||
if ( stack->initialPosition == getTurretBattleHex(wallPiece))
|
if ( stack->initialPosition == getTurretBattleHex(wallPiece))
|
||||||
return stack;
|
return stack;
|
||||||
@ -318,15 +318,15 @@ bool BattleSiegeController::isAttackableByCatapult(BattleHex hex) const
|
|||||||
if (owner.tacticsMode)
|
if (owner.tacticsMode)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto wallPart = owner.curInt->cb->battleHexToWallPart(hex);
|
auto wallPart = owner.getBattle()->battleHexToWallPart(hex);
|
||||||
return owner.curInt->cb->isWallPartAttackable(wallPart);
|
return owner.getBattle()->isWallPartAttackable(wallPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
|
void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
|
||||||
{
|
{
|
||||||
if (ca.attacker != -1)
|
if (ca.attacker != -1)
|
||||||
{
|
{
|
||||||
const CStack *stack = owner.curInt->cb->battleGetStackByID(ca.attacker);
|
const CStack *stack = owner.getBattle()->battleGetStackByID(ca.attacker);
|
||||||
for (auto attackInfo : ca.attackedParts)
|
for (auto attackInfo : ca.attackedParts)
|
||||||
{
|
{
|
||||||
owner.stacksController->addNewAnim(new CatapultAnimation(owner, stack, attackInfo.destinationTile, nullptr, attackInfo.damageDealt));
|
owner.stacksController->addNewAnim(new CatapultAnimation(owner, stack, attackInfo.destinationTile, nullptr, attackInfo.damageDealt));
|
||||||
@ -353,7 +353,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
|
|||||||
if (wallId == EWallVisual::GATE)
|
if (wallId == EWallVisual::GATE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto wallState = EWallState(owner.curInt->cb->battleGetWallState(attackInfo.attackedPart));
|
auto wallState = EWallState(owner.getBattle()->battleGetWallState(attackInfo.attackedPart));
|
||||||
|
|
||||||
wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
|
wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
|
|||||||
amountNegative->adjustPalette(shifterNegative, ignoredMask);
|
amountNegative->adjustPalette(shifterNegative, ignoredMask);
|
||||||
amountEffNeutral->adjustPalette(shifterNeutral, ignoredMask);
|
amountEffNeutral->adjustPalette(shifterNeutral, ignoredMask);
|
||||||
|
|
||||||
std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true);
|
std::vector<const CStack*> stacks = owner.getBattle()->battleGetAllStacks(true);
|
||||||
for(const CStack * s : stacks)
|
for(const CStack * s : stacks)
|
||||||
{
|
{
|
||||||
stackAdded(s, true);
|
stackAdded(s, true);
|
||||||
@ -126,7 +126,7 @@ BattleHex BattleStacksController::getStackCurrentPosition(const CStack * stack)
|
|||||||
|
|
||||||
void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer)
|
void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer)
|
||||||
{
|
{
|
||||||
auto stacks = owner.curInt->cb->battleGetAllStacks(false);
|
auto stacks = owner.getBattle()->battleGetAllStacks(false);
|
||||||
|
|
||||||
for (auto stack : stacks)
|
for (auto stack : stacks)
|
||||||
{
|
{
|
||||||
@ -359,7 +359,7 @@ void BattleStacksController::initializeBattleAnimations()
|
|||||||
|
|
||||||
void BattleStacksController::tickFrameBattleAnimations(uint32_t msPassed)
|
void BattleStacksController::tickFrameBattleAnimations(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
for (auto stack : owner.curInt->cb->battleGetAllStacks(true))
|
for (auto stack : owner.getBattle()->battleGetAllStacks(true))
|
||||||
{
|
{
|
||||||
if (stackAnimation.find(stack->unitId()) == stackAnimation.end()) //e.g. for summoned but not yet handled stacks
|
if (stackAnimation.find(stack->unitId()) == stackAnimation.end()) //e.g. for summoned but not yet handled stacks
|
||||||
continue;
|
continue;
|
||||||
@ -552,9 +552,7 @@ void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleH
|
|||||||
|
|
||||||
bool BattleStacksController::shouldAttackFacingRight(const CStack * attacker, const CStack * defender)
|
bool BattleStacksController::shouldAttackFacingRight(const CStack * attacker, const CStack * defender)
|
||||||
{
|
{
|
||||||
bool mustReverse = owner.curInt->cb->isToReverse(
|
bool mustReverse = owner.getBattle()->isToReverse(attacker, defender);
|
||||||
attacker,
|
|
||||||
defender);
|
|
||||||
|
|
||||||
if (attacker->unitSide() == BattleSide::ATTACKER)
|
if (attacker->unitSide() == BattleSide::ATTACKER)
|
||||||
return !mustReverse;
|
return !mustReverse;
|
||||||
@ -670,7 +668,7 @@ void BattleStacksController::endAction(const BattleAction & action)
|
|||||||
owner.checkForAnimations();
|
owner.checkForAnimations();
|
||||||
|
|
||||||
//check if we should reverse stacks
|
//check if we should reverse stacks
|
||||||
TStacks stacks = owner.curInt->cb->battleGetStacks(CBattleCallback::MINE_AND_ENEMY);
|
TStacks stacks = owner.getBattle()->battleGetStacks(CPlayerBattleCallback::MINE_AND_ENEMY);
|
||||||
|
|
||||||
for (const CStack *s : stacks)
|
for (const CStack *s : stacks)
|
||||||
{
|
{
|
||||||
@ -847,7 +845,7 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
|||||||
auto hoveredQueueUnitId = owner.windowObject->getQueueHoveredUnitId();
|
auto hoveredQueueUnitId = owner.windowObject->getQueueHoveredUnitId();
|
||||||
if(hoveredQueueUnitId.has_value())
|
if(hoveredQueueUnitId.has_value())
|
||||||
{
|
{
|
||||||
return { owner.curInt->cb->battleGetStackByID(hoveredQueueUnitId.value(), true) };
|
return { owner.getBattle()->battleGetStackByID(hoveredQueueUnitId.value(), true) };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hoveredHex = owner.fieldController->getHoveredHex();
|
auto hoveredHex = owner.fieldController->getHoveredHex();
|
||||||
@ -867,14 +865,14 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
|||||||
spells::Target target;
|
spells::Target target;
|
||||||
target.emplace_back(hoveredHex);
|
target.emplace_back(hoveredHex);
|
||||||
|
|
||||||
spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
|
spells::BattleCast event(owner.getBattle().get(), caster, mode, spell);
|
||||||
auto mechanics = spell->battleMechanics(&event);
|
auto mechanics = spell->battleMechanics(&event);
|
||||||
return mechanics->getAffectedStacks(target);
|
return mechanics->getAffectedStacks(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hoveredHex.isValid())
|
if(hoveredHex.isValid())
|
||||||
{
|
{
|
||||||
const CStack * const stack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
const CStack * const stack = owner.getBattle()->battleGetStackByPos(hoveredHex, true);
|
||||||
|
|
||||||
if (stack)
|
if (stack)
|
||||||
return {stack};
|
return {stack};
|
||||||
|
@ -367,10 +367,10 @@ void BattleWindow::bSurrenderf()
|
|||||||
if (owner.actionsController->spellcastingModeActive())
|
if (owner.actionsController->spellcastingModeActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int cost = owner.curInt->cb->battleGetSurrenderCost();
|
int cost = owner.getBattle()->battleGetSurrenderCost();
|
||||||
if(cost >= 0)
|
if(cost >= 0)
|
||||||
{
|
{
|
||||||
std::string enemyHeroName = owner.curInt->cb->battleGetEnemyHero().name;
|
std::string enemyHeroName = owner.getBattle()->battleGetEnemyHero().name;
|
||||||
if(enemyHeroName.empty())
|
if(enemyHeroName.empty())
|
||||||
{
|
{
|
||||||
logGlobal->warn("Surrender performed without enemy hero, should not happen!");
|
logGlobal->warn("Surrender performed without enemy hero, should not happen!");
|
||||||
@ -387,7 +387,7 @@ void BattleWindow::bFleef()
|
|||||||
if (owner.actionsController->spellcastingModeActive())
|
if (owner.actionsController->spellcastingModeActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( owner.curInt->cb->battleCanFlee() )
|
if ( owner.getBattle()->battleCanFlee() )
|
||||||
{
|
{
|
||||||
CFunctionList<void()> ony = std::bind(&BattleWindow::reallyFlee,this);
|
CFunctionList<void()> ony = std::bind(&BattleWindow::reallyFlee,this);
|
||||||
owner.curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
|
owner.curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
|
||||||
@ -398,10 +398,10 @@ void BattleWindow::bFleef()
|
|||||||
std::string heroName;
|
std::string heroName;
|
||||||
//calculating fleeing hero's name
|
//calculating fleeing hero's name
|
||||||
if (owner.attackingHeroInstance)
|
if (owner.attackingHeroInstance)
|
||||||
if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
|
if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getPlayerID())
|
||||||
heroName = owner.attackingHeroInstance->getNameTranslated();
|
heroName = owner.attackingHeroInstance->getNameTranslated();
|
||||||
if (owner.defendingHeroInstance)
|
if (owner.defendingHeroInstance)
|
||||||
if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
|
if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getPlayerID())
|
||||||
heroName = owner.defendingHeroInstance->getNameTranslated();
|
heroName = owner.defendingHeroInstance->getNameTranslated();
|
||||||
//calculating text
|
//calculating text
|
||||||
auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present. %s can not retreat!
|
auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present. %s can not retreat!
|
||||||
@ -419,7 +419,7 @@ void BattleWindow::reallyFlee()
|
|||||||
|
|
||||||
void BattleWindow::reallySurrender()
|
void BattleWindow::reallySurrender()
|
||||||
{
|
{
|
||||||
if (owner.curInt->cb->getResourceAmount(EGameResID::GOLD) < owner.curInt->cb->battleGetSurrenderCost())
|
if (owner.curInt->cb->getResourceAmount(EGameResID::GOLD) < owner.getBattle()->battleGetSurrenderCost())
|
||||||
{
|
{
|
||||||
owner.curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
|
owner.curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
|
||||||
}
|
}
|
||||||
@ -509,7 +509,7 @@ void BattleWindow::bAutofightf()
|
|||||||
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();
|
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();
|
||||||
|
|
||||||
ai->initBattleInterface(owner.curInt->env, owner.curInt->cb, autocombatPreferences);
|
ai->initBattleInterface(owner.curInt->env, owner.curInt->cb, autocombatPreferences);
|
||||||
ai->battleStart(owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.curInt->cb->battleGetMySide(), false);
|
ai->battleStart(owner.getBattleID(), owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.getBattle()->battleGetMySide(), false);
|
||||||
owner.curInt->autofightingAI = ai;
|
owner.curInt->autofightingAI = ai;
|
||||||
owner.curInt->cb->registerBattleInterface(ai);
|
owner.curInt->cb->registerBattleInterface(ai);
|
||||||
|
|
||||||
@ -531,7 +531,7 @@ void BattleWindow::bSpellf()
|
|||||||
|
|
||||||
CCS->curh->set(Cursor::Map::POINTER);
|
CCS->curh->set(Cursor::Map::POINTER);
|
||||||
|
|
||||||
ESpellCastProblem spellCastProblem = owner.curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO);
|
ESpellCastProblem spellCastProblem = owner.getBattle()->battleCanCastSpell(myHero, spells::Mode::HERO);
|
||||||
|
|
||||||
if(spellCastProblem == ESpellCastProblem::OK)
|
if(spellCastProblem == ESpellCastProblem::OK)
|
||||||
{
|
{
|
||||||
@ -633,11 +633,11 @@ void BattleWindow::bTacticPhaseEnd()
|
|||||||
void BattleWindow::blockUI(bool on)
|
void BattleWindow::blockUI(bool on)
|
||||||
{
|
{
|
||||||
bool canCastSpells = false;
|
bool canCastSpells = false;
|
||||||
auto hero = owner.curInt->cb->battleGetMyHero();
|
auto hero = owner.getBattle()->battleGetMyHero();
|
||||||
|
|
||||||
if(hero)
|
if(hero)
|
||||||
{
|
{
|
||||||
ESpellCastProblem spellcastingProblem = owner.curInt->cb->battleCanCastSpell(hero, spells::Mode::HERO);
|
ESpellCastProblem spellcastingProblem = owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO);
|
||||||
|
|
||||||
//if magic is blocked, we leave button active, so the message can be displayed after button click
|
//if magic is blocked, we leave button active, so the message can be displayed after button click
|
||||||
canCastSpells = spellcastingProblem == ESpellCastProblem::OK || spellcastingProblem == ESpellCastProblem::MAGIC_IS_BLOCKED;
|
canCastSpells = spellcastingProblem == ESpellCastProblem::OK || spellcastingProblem == ESpellCastProblem::MAGIC_IS_BLOCKED;
|
||||||
@ -646,8 +646,8 @@ void BattleWindow::blockUI(bool on)
|
|||||||
bool canWait = owner.stacksController->getActiveStack() ? !owner.stacksController->getActiveStack()->waitedThisTurn : false;
|
bool canWait = owner.stacksController->getActiveStack() ? !owner.stacksController->getActiveStack()->waitedThisTurn : false;
|
||||||
|
|
||||||
setShortcutBlocked(EShortcut::GLOBAL_OPTIONS, on);
|
setShortcutBlocked(EShortcut::GLOBAL_OPTIONS, on);
|
||||||
setShortcutBlocked(EShortcut::BATTLE_RETREAT, on || !owner.curInt->cb->battleCanFlee());
|
setShortcutBlocked(EShortcut::BATTLE_RETREAT, on || !owner.getBattle()->battleCanFlee());
|
||||||
setShortcutBlocked(EShortcut::BATTLE_SURRENDER, on || owner.curInt->cb->battleGetSurrenderCost() < 0);
|
setShortcutBlocked(EShortcut::BATTLE_SURRENDER, on || owner.getBattle()->battleGetSurrenderCost() < 0);
|
||||||
setShortcutBlocked(EShortcut::BATTLE_CAST_SPELL, on || owner.tacticsMode || !canCastSpells);
|
setShortcutBlocked(EShortcut::BATTLE_CAST_SPELL, on || owner.tacticsMode || !canCastSpells);
|
||||||
setShortcutBlocked(EShortcut::BATTLE_WAIT, on || owner.tacticsMode || !canWait);
|
setShortcutBlocked(EShortcut::BATTLE_WAIT, on || owner.tacticsMode || !canWait);
|
||||||
setShortcutBlocked(EShortcut::BATTLE_DEFEND, on || owner.tacticsMode);
|
setShortcutBlocked(EShortcut::BATTLE_DEFEND, on || owner.tacticsMode);
|
||||||
|
@ -503,7 +503,7 @@ void CSpellWindow::SpellArea::clickPressed(const Point & cursorPosition)
|
|||||||
else if(combatSpell)
|
else if(combatSpell)
|
||||||
{
|
{
|
||||||
spells::detail::ProblemImpl problem;
|
spells::detail::ProblemImpl problem;
|
||||||
if(mySpell->canBeCast(problem, owner->myInt->cb.get(), spells::Mode::HERO, owner->myHero))
|
if(mySpell->canBeCast(problem, owner->myInt->battleInt->getBattle().get(), spells::Mode::HERO, owner->myHero))
|
||||||
{
|
{
|
||||||
owner->myInt->battleInt->castThisSpell(mySpell->id);
|
owner->myInt->battleInt->castThisSpell(mySpell->id);
|
||||||
owner->fexitb();
|
owner->fexitb();
|
||||||
|
@ -677,8 +677,8 @@ std::function<void()> CExchangeController::onSwapArmy()
|
|||||||
{
|
{
|
||||||
return [&]()
|
return [&]()
|
||||||
{
|
{
|
||||||
if(left->tempOwner != cb->getMyColor()
|
if(left->tempOwner != cb->getPlayerID()
|
||||||
|| right->tempOwner != cb->getMyColor())
|
|| right->tempOwner != cb->getPlayerID())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -720,7 +720,7 @@ std::function<void()> CExchangeController::onMoveStackToLeft(SlotID slotID)
|
|||||||
{
|
{
|
||||||
return [=]()
|
return [=]()
|
||||||
{
|
{
|
||||||
if(right->tempOwner != cb->getMyColor())
|
if(right->tempOwner != cb->getPlayerID())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -733,7 +733,7 @@ std::function<void()> CExchangeController::onMoveStackToRight(SlotID slotID)
|
|||||||
{
|
{
|
||||||
return [=]()
|
return [=]()
|
||||||
{
|
{
|
||||||
if(left->tempOwner != cb->getMyColor())
|
if(left->tempOwner != cb->getPlayerID())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -778,7 +778,7 @@ void CExchangeController::moveArmy(bool leftToRight)
|
|||||||
const CGarrisonSlot * selection = this->view->getSelectedSlotID();
|
const CGarrisonSlot * selection = this->view->getSelectedSlotID();
|
||||||
SlotID slot;
|
SlotID slot;
|
||||||
|
|
||||||
if(source->tempOwner != cb->getMyColor())
|
if(source->tempOwner != cb->getPlayerID())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -807,7 +807,7 @@ void CExchangeController::moveArtifacts(bool leftToRight)
|
|||||||
const CGHeroInstance * source = leftToRight ? left : right;
|
const CGHeroInstance * source = leftToRight ? left : right;
|
||||||
const CGHeroInstance * target = leftToRight ? right : left;
|
const CGHeroInstance * target = leftToRight ? right : left;
|
||||||
|
|
||||||
if(source->tempOwner != cb->getMyColor())
|
if(source->tempOwner != cb->getPlayerID())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
|||||||
${MAIN_LIB_DIR}/battle/BattleStateInfoForRetreat.cpp
|
${MAIN_LIB_DIR}/battle/BattleStateInfoForRetreat.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.cpp
|
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.cpp
|
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CCallbackBase.cpp
|
|
||||||
${MAIN_LIB_DIR}/battle/CObstacleInstance.cpp
|
${MAIN_LIB_DIR}/battle/CObstacleInstance.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CPlayerBattleCallback.cpp
|
${MAIN_LIB_DIR}/battle/CPlayerBattleCallback.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CUnitState.cpp
|
${MAIN_LIB_DIR}/battle/CUnitState.cpp
|
||||||
@ -339,7 +338,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
|||||||
${MAIN_LIB_DIR}/battle/BattleProxy.h
|
${MAIN_LIB_DIR}/battle/BattleProxy.h
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.h
|
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.h
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.h
|
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.h
|
||||||
${MAIN_LIB_DIR}/battle/CCallbackBase.h
|
|
||||||
${MAIN_LIB_DIR}/battle/CObstacleInstance.h
|
${MAIN_LIB_DIR}/battle/CObstacleInstance.h
|
||||||
${MAIN_LIB_DIR}/battle/CPlayerBattleCallback.h
|
${MAIN_LIB_DIR}/battle/CPlayerBattleCallback.h
|
||||||
${MAIN_LIB_DIR}/battle/CUnitState.h
|
${MAIN_LIB_DIR}/battle/CUnitState.h
|
||||||
|
@ -66,6 +66,11 @@ bool CGameInfoCallback::isAllowed(int32_t type, int32_t id) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<PlayerColor> CGameInfoCallback::getPlayerID() const
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
const Player * CGameInfoCallback::getPlayer(PlayerColor color) const
|
const Player * CGameInfoCallback::getPlayer(PlayerColor color) const
|
||||||
{
|
{
|
||||||
return getPlayerState(color, false);
|
return getPlayerState(color, false);
|
||||||
@ -151,7 +156,7 @@ const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool v
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isVisible(ret, player) && ret->tempOwner != player)
|
if(!isVisible(ret, getPlayerID()) && ret->tempOwner != getPlayerID())
|
||||||
{
|
{
|
||||||
if(verbose)
|
if(verbose)
|
||||||
logGlobal->error("Cannot get object with id %d. Object is not visible.", oid);
|
logGlobal->error("Cannot get object with id %d. Object is not visible.", oid);
|
||||||
@ -232,7 +237,7 @@ void CGameInfoCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObj
|
|||||||
if(obj->ID == Obj::TOWN || obj->ID == Obj::TAVERN)
|
if(obj->ID == Obj::TOWN || obj->ID == Obj::TAVERN)
|
||||||
{
|
{
|
||||||
int taverns = 0;
|
int taverns = 0;
|
||||||
for(auto town : gs->players[*player].towns)
|
for(auto town : gs->players[*getPlayerID()].towns)
|
||||||
{
|
{
|
||||||
if(town->hasBuilt(BuildingID::TAVERN))
|
if(town->hasBuilt(BuildingID::TAVERN))
|
||||||
taverns++;
|
taverns++;
|
||||||
@ -254,7 +259,7 @@ int CGameInfoCallback::howManyTowns(PlayerColor Player) const
|
|||||||
|
|
||||||
bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject) const
|
bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject) const
|
||||||
{
|
{
|
||||||
ERROR_RET_VAL_IF(!isVisible(town, player), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
ERROR_RET_VAL_IF(!isVisible(town, getPlayerID()), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
||||||
bool detailed = hasAccess(town->tempOwner);
|
bool detailed = hasAccess(town->tempOwner);
|
||||||
|
|
||||||
if(town->ID == Obj::TOWN)
|
if(town->ID == Obj::TOWN)
|
||||||
@ -305,9 +310,9 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
|||||||
|
|
||||||
if (infoLevel == InfoAboutHero::EInfoLevel::BASIC)
|
if (infoLevel == InfoAboutHero::EInfoLevel::BASIC)
|
||||||
{
|
{
|
||||||
auto ourBattle = gs->getBattle(*player);
|
auto ourBattle = gs->getBattle(*getPlayerID());
|
||||||
|
|
||||||
if(ourBattle && ourBattle->playerHasAccessToHeroInfo(*player, h)) //if it's battle we can get enemy hero full data
|
if(ourBattle && ourBattle->playerHasAccessToHeroInfo(*getPlayerID(), h)) //if it's battle we can get enemy hero full data
|
||||||
infoLevel = InfoAboutHero::EInfoLevel::INBATTLE;
|
infoLevel = InfoAboutHero::EInfoLevel::INBATTLE;
|
||||||
else
|
else
|
||||||
ERROR_RET_VAL_IF(!isVisible(h->visitablePos()), "That hero is not visible!", false);
|
ERROR_RET_VAL_IF(!isVisible(h->visitablePos()), "That hero is not visible!", false);
|
||||||
@ -324,7 +329,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
|||||||
dest.initFromHero(h, infoLevel);
|
dest.initFromHero(h, infoLevel);
|
||||||
|
|
||||||
//DISGUISED bonus implementation
|
//DISGUISED bonus implementation
|
||||||
if(getPlayerRelations(*player, hero->tempOwner) == PlayerRelations::ENEMIES)
|
if(getPlayerRelations(*getPlayerID(), hero->tempOwner) == PlayerRelations::ENEMIES)
|
||||||
{
|
{
|
||||||
//todo: bonus cashing
|
//todo: bonus cashing
|
||||||
int disguiseLevel = h->valOfBonuses(Selector::typeSubtype(BonusType::DISGUISED, 0));
|
int disguiseLevel = h->valOfBonuses(Selector::typeSubtype(BonusType::DISGUISED, 0));
|
||||||
@ -422,7 +427,7 @@ bool CGameInfoCallback::isVisible(int3 pos, const std::optional<PlayerColor> & P
|
|||||||
|
|
||||||
bool CGameInfoCallback::isVisible(int3 pos) const
|
bool CGameInfoCallback::isVisible(int3 pos) const
|
||||||
{
|
{
|
||||||
return isVisible(pos, player);
|
return isVisible(pos, getPlayerID());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameInfoCallback::isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & Player) const
|
bool CGameInfoCallback::isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & Player) const
|
||||||
@ -432,7 +437,7 @@ bool CGameInfoCallback::isVisible(const CGObjectInstance * obj, const std::optio
|
|||||||
|
|
||||||
bool CGameInfoCallback::isVisible(const CGObjectInstance *obj) const
|
bool CGameInfoCallback::isVisible(const CGObjectInstance *obj) const
|
||||||
{
|
{
|
||||||
return isVisible(obj, player);
|
return isVisible(obj, getPlayerID());
|
||||||
}
|
}
|
||||||
// const CCreatureSet* CInfoCallback::getGarrison(const CGObjectInstance *obj) const
|
// const CCreatureSet* CInfoCallback::getGarrison(const CGObjectInstance *obj) const
|
||||||
// {
|
// {
|
||||||
@ -464,7 +469,7 @@ std::vector <const CGObjectInstance * > CGameInfoCallback::getVisitableObjs(int3
|
|||||||
|
|
||||||
for(const CGObjectInstance * obj : t->visitableObjects)
|
for(const CGObjectInstance * obj : t->visitableObjects)
|
||||||
{
|
{
|
||||||
if(player || obj->ID != Obj::EVENT) //hide events from players
|
if(getPlayerID() || obj->ID != Obj::EVENT) //hide events from players
|
||||||
ret.push_back(obj);
|
ret.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +505,7 @@ std::vector<const CGHeroInstance *> CGameInfoCallback::getAvailableHeroes(const
|
|||||||
const CGTownInstance * town = getTown(townOrTavern->id);
|
const CGTownInstance * town = getTown(townOrTavern->id);
|
||||||
|
|
||||||
if(townOrTavern->ID == Obj::TAVERN || (town && town->hasBuilt(BuildingID::TAVERN)))
|
if(townOrTavern->ID == Obj::TAVERN || (town && town->hasBuilt(BuildingID::TAVERN)))
|
||||||
return gs->heroesPool->getHeroesFor(*player);
|
return gs->heroesPool->getHeroesFor(*getPlayerID());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -531,8 +536,8 @@ EDiggingStatus CGameInfoCallback::getTileDigStatus(int3 tile, bool verbose) cons
|
|||||||
//TODO: typedef?
|
//TODO: typedef?
|
||||||
std::shared_ptr<const boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVisibleTiles() const
|
std::shared_ptr<const boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVisibleTiles() const
|
||||||
{
|
{
|
||||||
assert(player.has_value());
|
assert(getPlayerID().has_value());
|
||||||
const auto * team = getPlayerTeam(player.value());
|
const auto * team = getPlayerTeam(getPlayerID().value());
|
||||||
|
|
||||||
size_t width = gs->map->width;
|
size_t width = gs->map->width;
|
||||||
size_t height = gs->map->height;
|
size_t height = gs->map->height;
|
||||||
@ -631,7 +636,7 @@ const CMapHeader * CGameInfoCallback::getMapHeader() const
|
|||||||
|
|
||||||
bool CGameInfoCallback::hasAccess(std::optional<PlayerColor> playerId) const
|
bool CGameInfoCallback::hasAccess(std::optional<PlayerColor> playerId) const
|
||||||
{
|
{
|
||||||
return !player || player->isSpectator() || gs->getPlayerRelations(*playerId, *player) != PlayerRelations::ENEMIES;
|
return !getPlayerID() || getPlayerID()->isSpectator() || gs->getPlayerRelations(*playerId, *getPlayerID()) != PlayerRelations::ENEMIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlayerStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const
|
EPlayerStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const
|
||||||
@ -713,23 +718,22 @@ bool CGameInfoCallback::isPlayerMakingTurn(PlayerColor player) const
|
|||||||
return gs->actingPlayers.count(player);
|
return gs->actingPlayers.count(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameInfoCallback::CGameInfoCallback(CGameState * GS, std::optional<PlayerColor> Player):
|
CGameInfoCallback::CGameInfoCallback(CGameState * GS):
|
||||||
gs(GS)
|
gs(GS)
|
||||||
{
|
{
|
||||||
player = std::move(Player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const boost::multi_array<ui8, 3>> CPlayerSpecificInfoCallback::getVisibilityMap() const
|
std::shared_ptr<const boost::multi_array<ui8, 3>> CPlayerSpecificInfoCallback::getVisibilityMap() const
|
||||||
{
|
{
|
||||||
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
return gs->getPlayerTeam(*player)->fogOfWarMap;
|
return gs->getPlayerTeam(*getPlayerID())->fogOfWarMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPlayerSpecificInfoCallback::howManyTowns() const
|
int CPlayerSpecificInfoCallback::howManyTowns() const
|
||||||
{
|
{
|
||||||
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1);
|
ERROR_RET_VAL_IF(!getPlayerID(), "Applicable only for player callbacks", -1);
|
||||||
return CGameInfoCallback::howManyTowns(*player);
|
return CGameInfoCallback::howManyTowns(*getPlayerID());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(bool onlyOur) const
|
std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(bool onlyOur) const
|
||||||
@ -740,7 +744,7 @@ std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(
|
|||||||
{
|
{
|
||||||
for(const auto & town : i.second.towns)
|
for(const auto & town : i.second.towns)
|
||||||
{
|
{
|
||||||
if(i.first == player || (!onlyOur && isVisible(town, player)))
|
if(i.first == getPlayerID() || (!onlyOur && isVisible(town, getPlayerID())))
|
||||||
{
|
{
|
||||||
ret.push_back(town);
|
ret.push_back(town);
|
||||||
}
|
}
|
||||||
@ -755,8 +759,8 @@ std::vector < const CGHeroInstance *> CPlayerSpecificInfoCallback::getHeroesInfo
|
|||||||
for(auto hero : gs->map->heroesOnMap)
|
for(auto hero : gs->map->heroesOnMap)
|
||||||
{
|
{
|
||||||
// !player || // - why would we even get access to hero not owned by any player?
|
// !player || // - why would we even get access to hero not owned by any player?
|
||||||
if((hero->tempOwner == *player) ||
|
if((hero->tempOwner == *getPlayerID()) ||
|
||||||
(isVisible(hero->visitablePos(), player) && !onlyOur) )
|
(isVisible(hero->visitablePos(), getPlayerID()) && !onlyOur) )
|
||||||
{
|
{
|
||||||
ret.push_back(hero);
|
ret.push_back(hero);
|
||||||
}
|
}
|
||||||
@ -764,18 +768,13 @@ std::vector < const CGHeroInstance *> CPlayerSpecificInfoCallback::getHeroesInfo
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<PlayerColor> CPlayerSpecificInfoCallback::getMyColor() const
|
|
||||||
{
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const
|
int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const
|
||||||
{
|
{
|
||||||
if (hero->inTownGarrison && !includeGarrisoned)
|
if (hero->inTownGarrison && !includeGarrisoned)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
auto & heroes = gs->players[*player].heroes;
|
auto & heroes = gs->players[*getPlayerID()].heroes;
|
||||||
|
|
||||||
for (auto & heroe : heroes)
|
for (auto & heroe : heroes)
|
||||||
{
|
{
|
||||||
@ -790,13 +789,13 @@ int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool
|
|||||||
|
|
||||||
int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio )
|
int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio )
|
||||||
{
|
{
|
||||||
if (!player || CGObelisk::obeliskCount == 0)
|
if (!getPlayerID() || CGObelisk::obeliskCount == 0)
|
||||||
{
|
{
|
||||||
*outKnownRatio = 0.0;
|
*outKnownRatio = 0.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TeamID t = gs->getPlayerTeam(*player)->id;
|
TeamID t = gs->getPlayerTeam(*getPlayerID())->id;
|
||||||
double visited = 0.0;
|
double visited = 0.0;
|
||||||
if(CGObelisk::visited.count(t))
|
if(CGObelisk::visited.count(t))
|
||||||
visited = static_cast<double>(CGObelisk::visited[t]);
|
visited = static_cast<double>(CGObelisk::visited[t]);
|
||||||
@ -811,7 +810,7 @@ std::vector < const CGObjectInstance * > CPlayerSpecificInfoCallback::getMyObjec
|
|||||||
std::vector < const CGObjectInstance * > ret;
|
std::vector < const CGObjectInstance * > ret;
|
||||||
for(const CGObjectInstance * obj : gs->map->objects)
|
for(const CGObjectInstance * obj : gs->map->objects)
|
||||||
{
|
{
|
||||||
if(obj && obj->tempOwner == player)
|
if(obj && obj->tempOwner == getPlayerID())
|
||||||
ret.push_back(obj);
|
ret.push_back(obj);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -821,7 +820,7 @@ std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings()
|
|||||||
{
|
{
|
||||||
ASSERT_IF_CALLED_WITH_PLAYER
|
ASSERT_IF_CALLED_WITH_PLAYER
|
||||||
std::vector < const CGDwelling * > ret;
|
std::vector < const CGDwelling * > ret;
|
||||||
for(CGDwelling * dw : gs->getPlayerState(*player)->dwellings)
|
for(CGDwelling * dw : gs->getPlayerState(*getPlayerID())->dwellings)
|
||||||
{
|
{
|
||||||
ret.push_back(dw);
|
ret.push_back(dw);
|
||||||
}
|
}
|
||||||
@ -831,7 +830,7 @@ std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings()
|
|||||||
std::vector <QuestInfo> CPlayerSpecificInfoCallback::getMyQuests() const
|
std::vector <QuestInfo> CPlayerSpecificInfoCallback::getMyQuests() const
|
||||||
{
|
{
|
||||||
std::vector <QuestInfo> ret;
|
std::vector <QuestInfo> ret;
|
||||||
for(const auto & quest : gs->getPlayerState(*player)->quests)
|
for(const auto & quest : gs->getPlayerState(*getPlayerID())->quests)
|
||||||
{
|
{
|
||||||
ret.push_back (quest);
|
ret.push_back (quest);
|
||||||
}
|
}
|
||||||
@ -841,14 +840,14 @@ std::vector <QuestInfo> CPlayerSpecificInfoCallback::getMyQuests() const
|
|||||||
int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const
|
int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const
|
||||||
{
|
{
|
||||||
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1);
|
ERROR_RET_VAL_IF(!getPlayerID(), "Applicable only for player callbacks", -1);
|
||||||
return getHeroCount(*player,includeGarrisoned);
|
return getHeroCount(*getPlayerID(), includeGarrisoned);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId, bool includeGarrisoned) const
|
const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId, bool includeGarrisoned) const
|
||||||
{
|
{
|
||||||
ASSERT_IF_CALLED_WITH_PLAYER
|
ASSERT_IF_CALLED_WITH_PLAYER
|
||||||
const PlayerState *p = getPlayerState(*player);
|
const PlayerState *p = getPlayerState(*getPlayerID());
|
||||||
ERROR_RET_VAL_IF(!p, "No player info", nullptr);
|
ERROR_RET_VAL_IF(!p, "No player info", nullptr);
|
||||||
|
|
||||||
if (!includeGarrisoned)
|
if (!includeGarrisoned)
|
||||||
@ -864,7 +863,7 @@ const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId,
|
|||||||
const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const
|
const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const
|
||||||
{
|
{
|
||||||
ASSERT_IF_CALLED_WITH_PLAYER
|
ASSERT_IF_CALLED_WITH_PLAYER
|
||||||
const PlayerState *p = getPlayerState(*player);
|
const PlayerState *p = getPlayerState(*getPlayerID());
|
||||||
ERROR_RET_VAL_IF(!p, "No player info", nullptr);
|
ERROR_RET_VAL_IF(!p, "No player info", nullptr);
|
||||||
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", nullptr);
|
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", nullptr);
|
||||||
return p->towns[serialId];
|
return p->towns[serialId];
|
||||||
@ -873,15 +872,15 @@ const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId)
|
|||||||
int CPlayerSpecificInfoCallback::getResourceAmount(GameResID type) const
|
int CPlayerSpecificInfoCallback::getResourceAmount(GameResID type) const
|
||||||
{
|
{
|
||||||
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1);
|
ERROR_RET_VAL_IF(!getPlayerID(), "Applicable only for player callbacks", -1);
|
||||||
return getResource(*player, type);
|
return getResource(*getPlayerID(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
TResources CPlayerSpecificInfoCallback::getResourceAmount() const
|
TResources CPlayerSpecificInfoCallback::getResourceAmount() const
|
||||||
{
|
{
|
||||||
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", TResources());
|
ERROR_RET_VAL_IF(!getPlayerID(), "Applicable only for player callbacks", TResources());
|
||||||
return gs->players[*player].resources;
|
return gs->players[*getPlayerID()].resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const
|
const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const
|
||||||
@ -892,11 +891,11 @@ const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const
|
|||||||
if (team != gs->teams.end())
|
if (team != gs->teams.end())
|
||||||
{
|
{
|
||||||
const TeamState *ret = &team->second;
|
const TeamState *ret = &team->second;
|
||||||
if(!player.has_value()) //neutral (or invalid) player
|
if(!getPlayerID().has_value()) //neutral (or invalid) player
|
||||||
return ret;
|
return ret;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vstd::contains(ret->players, *player)) //specific player
|
if (vstd::contains(ret->players, *getPlayerID())) //specific player
|
||||||
return ret;
|
return ret;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -942,7 +941,7 @@ bool CGameInfoCallback::isInTheMap(const int3 &pos) const
|
|||||||
|
|
||||||
void CGameInfoCallback::getVisibleTilesInRange(std::unordered_set<int3> &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula) const
|
void CGameInfoCallback::getVisibleTilesInRange(std::unordered_set<int3> &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula) const
|
||||||
{
|
{
|
||||||
gs->getTilesInRange(tiles, pos, radious, *player, -1, distanceFormula);
|
gs->getTilesInRange(tiles, pos, radious, *getPlayerID(), -1, distanceFormula);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameInfoCallback::calculatePaths(const std::shared_ptr<PathfinderConfig> & config)
|
void CGameInfoCallback::calculatePaths(const std::shared_ptr<PathfinderConfig> & config)
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
#include "int3.h"
|
#include "int3.h"
|
||||||
#include "ResourceSet.h" // for Res
|
#include "ResourceSet.h" // for Res
|
||||||
#include "battle/CCallbackBase.h"
|
|
||||||
|
#define ASSERT_IF_CALLED_WITH_PLAYER if(!getPlayerID()) {logGlobal->error(BOOST_CURRENT_FUNCTION); assert(0);}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ public:
|
|||||||
virtual bool isAllowed(int32_t type, int32_t id) const = 0; //type: 0 - spell; 1- artifact; 2 - secondary skill
|
virtual bool isAllowed(int32_t type, int32_t id) const = 0; //type: 0 - spell; 1- artifact; 2 - secondary skill
|
||||||
|
|
||||||
//player
|
//player
|
||||||
|
virtual std::optional<PlayerColor> getPlayerID() const = 0;
|
||||||
virtual const Player * getPlayer(PlayerColor color) const = 0;
|
virtual const Player * getPlayer(PlayerColor color) const = 0;
|
||||||
// virtual int getResource(PlayerColor Player, EGameResID which) const = 0;
|
// virtual int getResource(PlayerColor Player, EGameResID which) const = 0;
|
||||||
// bool isVisible(int3 pos) const;
|
// bool isVisible(int3 pos) const;
|
||||||
@ -123,13 +125,13 @@ public:
|
|||||||
// bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const;
|
// bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGameInfoCallback : public virtual CCallbackBase, public IGameInfoCallback
|
class DLL_LINKAGE CGameInfoCallback : public IGameInfoCallback
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CGameState * gs;//todo: replace with protected const getter, only actual Server and Client objects should hold game state
|
CGameState * gs;//todo: replace with protected const getter, only actual Server and Client objects should hold game state
|
||||||
|
|
||||||
CGameInfoCallback() = default;
|
CGameInfoCallback() = default;
|
||||||
CGameInfoCallback(CGameState * GS, std::optional<PlayerColor> Player);
|
CGameInfoCallback(CGameState * GS);
|
||||||
bool hasAccess(std::optional<PlayerColor> playerId) const;
|
bool hasAccess(std::optional<PlayerColor> playerId) const;
|
||||||
|
|
||||||
bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode
|
bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode
|
||||||
@ -142,6 +144,7 @@ public:
|
|||||||
bool isAllowed(int32_t type, int32_t id) const override; //type: 0 - spell; 1- artifact; 2 - secondary skill
|
bool isAllowed(int32_t type, int32_t id) const override; //type: 0 - spell; 1- artifact; 2 - secondary skill
|
||||||
|
|
||||||
//player
|
//player
|
||||||
|
std::optional<PlayerColor> getPlayerID() const override;
|
||||||
const Player * getPlayer(PlayerColor color) const override;
|
const Player * getPlayer(PlayerColor color) const override;
|
||||||
virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const;
|
virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const;
|
||||||
virtual int getResource(PlayerColor Player, GameResID which) const;
|
virtual int getResource(PlayerColor Player, GameResID which) const;
|
||||||
@ -229,7 +232,6 @@ public:
|
|||||||
virtual int howManyTowns() const;
|
virtual int howManyTowns() const;
|
||||||
virtual int howManyHeroes(bool includeGarrisoned = true) const;
|
virtual int howManyHeroes(bool includeGarrisoned = true) const;
|
||||||
virtual int3 getGrailPos(double *outKnownRatio);
|
virtual int3 getGrailPos(double *outKnownRatio);
|
||||||
virtual std::optional<PlayerColor> getMyColor() const;
|
|
||||||
|
|
||||||
virtual std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
|
virtual std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
|
||||||
virtual int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const;
|
virtual int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const;
|
||||||
|
@ -157,9 +157,9 @@ CGlobalAI::CGlobalAI()
|
|||||||
human = false;
|
human = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureAI::battleNewRound(const BattleID & battleID, int round)
|
void CAdventureAI::battleNewRound(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
battleAI->battleNewRound(battleID, round);
|
battleAI->battleNewRound(battleID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureAI::battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca)
|
void CAdventureAI::battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca)
|
||||||
@ -187,9 +187,9 @@ void CAdventureAI::actionStarted(const BattleID & battleID, const BattleAction &
|
|||||||
battleAI->actionStarted(battleID, action);
|
battleAI->actionStarted(battleID, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureAI::battleNewRoundFirst(const BattleID & battleID, int round)
|
void CAdventureAI::battleNewRoundFirst(const BattleID & battleID)
|
||||||
{
|
{
|
||||||
battleAI->battleNewRoundFirst(battleID, round);
|
battleAI->battleNewRoundFirst(battleID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureAI::actionFinished(const BattleID & battleID, const BattleAction & action)
|
void CAdventureAI::actionFinished(const BattleID & battleID, const BattleAction & action)
|
||||||
|
@ -147,12 +147,12 @@ public:
|
|||||||
virtual void activeStack(const BattleID & battleID, const CStack * stack) override;
|
virtual void activeStack(const BattleID & battleID, const CStack * stack) override;
|
||||||
virtual void yourTacticPhase(const BattleID & battleID, int distance) override;
|
virtual void yourTacticPhase(const BattleID & battleID, int distance) override;
|
||||||
|
|
||||||
virtual void battleNewRound(const BattleID & battleID, int round) override;
|
virtual void battleNewRound(const BattleID & battleID) override;
|
||||||
virtual void battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca) override;
|
virtual void battleCatapultAttacked(const BattleID & battleID, const CatapultAttack & ca) override;
|
||||||
virtual void battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed) override;
|
virtual void battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side, bool replayAllowed) override;
|
||||||
virtual void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged) override;
|
virtual void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged) override;
|
||||||
virtual void actionStarted(const BattleID & battleID, const BattleAction &action) override;
|
virtual void actionStarted(const BattleID & battleID, const BattleAction &action) override;
|
||||||
virtual void battleNewRoundFirst(const BattleID & battleID, int round) override;
|
virtual void battleNewRoundFirst(const BattleID & battleID) override;
|
||||||
virtual void actionFinished(const BattleID & battleID, const BattleAction &action) override;
|
virtual void actionFinished(const BattleID & battleID, const BattleAction &action) override;
|
||||||
virtual void battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse) override;
|
virtual void battleStacksEffectsSet(const BattleID & battleID, const SetStackEffect & sse) override;
|
||||||
virtual void battleObstaclesChanged(const BattleID & battleID, const std::vector<ObstacleChanges> & obstacles) override;
|
virtual void battleObstaclesChanged(const BattleID & battleID, const std::vector<ObstacleChanges> & obstacles) override;
|
||||||
|
@ -61,8 +61,8 @@ public:
|
|||||||
virtual void battleAttack(const BattleID & battleID, const BattleAttack *ba){}; //called when stack is performing attack
|
virtual void battleAttack(const BattleID & battleID, const BattleAttack *ba){}; //called when stack is performing attack
|
||||||
virtual void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged){}; //called when stack receives damage (after battleAttack())
|
virtual void battleStacksAttacked(const BattleID & battleID, const std::vector<BattleStackAttacked> & bsa, bool ranged){}; //called when stack receives damage (after battleAttack())
|
||||||
virtual void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID){};
|
virtual void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID){};
|
||||||
virtual void battleNewRoundFirst(const BattleID & battleID, int round){}; //called at the beginning of each turn before changes are applied;
|
virtual void battleNewRoundFirst(const BattleID & battleID){}; //called at the beginning of each turn before changes are applied;
|
||||||
virtual void battleNewRound(const BattleID & battleID, int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
virtual void battleNewRound(const BattleID & battleID){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||||
virtual void battleLogMessage(const BattleID & battleID, const std::vector<MetaString> & lines){};
|
virtual void battleLogMessage(const BattleID & battleID, const std::vector<MetaString> & lines){};
|
||||||
virtual void battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport){};
|
virtual void battleStackMoved(const BattleID & battleID, const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport){};
|
||||||
virtual void battleSpellCast(const BattleID & battleID, const BattleSpellCast *sc){};
|
virtual void battleSpellCast(const BattleID & battleID, const BattleSpellCast *sc){};
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include <vcmi/spells/Magic.h>
|
#include <vcmi/spells/Magic.h>
|
||||||
|
|
||||||
#include "CCallbackBase.h"
|
|
||||||
#include "ReachabilityInfo.h"
|
#include "ReachabilityInfo.h"
|
||||||
#include "BattleAttackInfo.h"
|
#include "BattleAttackInfo.h"
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "CCallbackBase.h"
|
|
||||||
#include "IBattleInfoCallback.h"
|
#include "IBattleInfoCallback.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* CCallbackBase.cpp, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "StdInc.h"
|
|
||||||
#include "CCallbackBase.h"
|
|
||||||
#include "IBattleState.h"
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
CCallbackBase::CCallbackBase(std::optional<PlayerColor> Player):
|
|
||||||
player(std::move(Player))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<PlayerColor> CCallbackBase::getPlayerID() const
|
|
||||||
{
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* CCallbackBase.h, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include "../GameConstants.h"
|
|
||||||
|
|
||||||
#define RETURN_IF_NOT_BATTLE(...) if(!duringBattle()) {logGlobal->error("%s called when no battle!", __FUNCTION__); return __VA_ARGS__; }
|
|
||||||
#define ASSERT_IF_CALLED_WITH_PLAYER if(!getPlayerID()) {logGlobal->error(BOOST_CURRENT_FUNCTION); assert(0);}
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
class IBattleInfo;
|
|
||||||
class BattleInfo;
|
|
||||||
class CBattleInfoEssentials;
|
|
||||||
|
|
||||||
//Basic class for various callbacks (interfaces called by players to get info about game and so forth)
|
|
||||||
class DLL_LINKAGE CCallbackBase
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::optional<PlayerColor> player; // not set gives access to all information, otherwise callback provides only information "visible" for player
|
|
||||||
|
|
||||||
CCallbackBase(std::optional<PlayerColor> Player);
|
|
||||||
CCallbackBase() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::optional<PlayerColor> getPlayerID() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
|
@ -11,9 +11,27 @@
|
|||||||
#include "CPlayerBattleCallback.h"
|
#include "CPlayerBattleCallback.h"
|
||||||
#include "../CStack.h"
|
#include "../CStack.h"
|
||||||
#include "../gameState/InfoAboutArmy.h"
|
#include "../gameState/InfoAboutArmy.h"
|
||||||
|
#include "../CGameInfoCallback.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
CPlayerBattleCallback::CPlayerBattleCallback(const IBattleInfo * battle, PlayerColor player):
|
||||||
|
battle(battle),
|
||||||
|
player(player)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const IBattleInfo * CPlayerBattleCallback::getBattle() const
|
||||||
|
{
|
||||||
|
return battle;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<PlayerColor> CPlayerBattleCallback::getPlayerID() const
|
||||||
|
{
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
bool CPlayerBattleCallback::battleCanFlee() const
|
bool CPlayerBattleCallback::battleCanFlee() const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(false);
|
RETURN_IF_NOT_BATTLE(false);
|
||||||
|
@ -16,7 +16,15 @@ class CGHeroInstance;
|
|||||||
|
|
||||||
class DLL_LINKAGE CPlayerBattleCallback : public CBattleInfoCallback
|
class DLL_LINKAGE CPlayerBattleCallback : public CBattleInfoCallback
|
||||||
{
|
{
|
||||||
|
const IBattleInfo * battle;
|
||||||
|
PlayerColor player;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CPlayerBattleCallback(const IBattleInfo * battle, PlayerColor player);
|
||||||
|
|
||||||
|
const IBattleInfo * getBattle() const override;
|
||||||
|
std::optional<PlayerColor> getPlayerID() const override;
|
||||||
|
|
||||||
bool battleCanFlee() const; //returns true if caller can flee from the battle
|
bool battleCanFlee() const; //returns true if caller can flee from the battle
|
||||||
TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true) const; //returns stacks on battlefield
|
TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true) const; //returns stacks on battlefield
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include <vcmi/Entity.h>
|
#include <vcmi/Entity.h>
|
||||||
|
|
||||||
|
#define RETURN_IF_NOT_BATTLE(...) if(!duringBattle()) {logGlobal->error("%s called when no battle!", __FUNCTION__); return __VA_ARGS__; }
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct CObstacleInstance;
|
struct CObstacleInstance;
|
||||||
|
@ -456,7 +456,7 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPathfinderHelper::CPathfinderHelper(CGameState * gs, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
CPathfinderHelper::CPathfinderHelper(CGameState * gs, const CGHeroInstance * Hero, const PathfinderOptions & Options):
|
||||||
CGameInfoCallback(gs, std::optional<PlayerColor>()),
|
CGameInfoCallback(gs),
|
||||||
turn(-1),
|
turn(-1),
|
||||||
hero(Hero),
|
hero(Hero),
|
||||||
options(Options),
|
options(Options),
|
||||||
|
Loading…
Reference in New Issue
Block a user