mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Initial prototype works
This commit is contained in:
@@ -707,9 +707,12 @@ void CPlayerInterface::battleStartBefore(const CCreatureSet *army1, const CCreat
|
|||||||
void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side)
|
void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
bool replay = (lastBattleArmies.first == army1 && lastBattleArmies.second == army2);
|
||||||
|
lastBattleArmies.first = army1;
|
||||||
|
lastBattleArmies.second = army2;
|
||||||
//quick combat with neutral creatures only
|
//quick combat with neutral creatures only
|
||||||
auto * army2_object = dynamic_cast<const CGObjectInstance *>(army2);
|
auto * army2_object = dynamic_cast<const CGObjectInstance *>(army2);
|
||||||
if(army2_object && army2_object->getOwner() == PlayerColor::UNFLAGGABLE && settings["adventure"]["quickCombat"].Bool())
|
if(!replay && army2_object && army2_object->getOwner() == PlayerColor::UNFLAGGABLE && settings["adventure"]["quickCombat"].Bool())
|
||||||
{
|
{
|
||||||
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
|
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
|
||||||
autofightingAI->init(env, cb);
|
autofightingAI->init(env, cb);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ namespace boost
|
|||||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||||
{
|
{
|
||||||
const CArmedInstance * currentSelection;
|
const CArmedInstance * currentSelection;
|
||||||
|
std::pair<const CCreatureSet *, const CCreatureSet *> lastBattleArmies;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<Environment> env;
|
std::shared_ptr<Environment> env;
|
||||||
|
|||||||
@@ -581,15 +581,30 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
|
|
||||||
std::shared_ptr<CPlayerInterface> att, def;
|
std::shared_ptr<CPlayerInterface> att, def;
|
||||||
auto & leftSide = info->sides[0], & rightSide = info->sides[1];
|
auto & leftSide = info->sides[0], & rightSide = info->sides[1];
|
||||||
|
|
||||||
|
auto callBattleStart = [&](PlayerColor color, ui8 side)
|
||||||
|
{
|
||||||
|
if(vstd::contains(battleints, color))
|
||||||
|
battleints[color]->battleStart(leftSide.armyObject, rightSide.armyObject, info->tile, leftSide.hero, rightSide.hero, side);
|
||||||
|
};
|
||||||
|
|
||||||
|
callBattleStart(leftSide.color, 0);
|
||||||
|
callBattleStart(rightSide.color, 1);
|
||||||
|
callBattleStart(PlayerColor::UNFLAGGABLE, 1);
|
||||||
|
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
||||||
|
callBattleStart(PlayerColor::SPECTATOR, 1);
|
||||||
|
|
||||||
|
if(vstd::contains(playerint, leftSide.color) && playerint[leftSide.color]->human)
|
||||||
|
att = std::dynamic_pointer_cast<CPlayerInterface>(playerint[leftSide.color]);
|
||||||
|
|
||||||
|
if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human)
|
||||||
|
def = std::dynamic_pointer_cast<CPlayerInterface>(playerint[rightSide.color]);
|
||||||
|
|
||||||
//If quick combat is not, do not prepare interfaces for battleint
|
//If quick combat is not, do not prepare interfaces for battleint
|
||||||
if(rightSide.color != PlayerColor::NEUTRAL || !settings["adventure"]["quickCombat"].Bool())
|
if(att && att->isAutoFightOn)
|
||||||
{
|
{
|
||||||
if(vstd::contains(playerint, leftSide.color) && playerint[leftSide.color]->human)
|
att.reset();
|
||||||
att = std::dynamic_pointer_cast<CPlayerInterface>(playerint[leftSide.color]);
|
def.reset();
|
||||||
|
|
||||||
if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human)
|
|
||||||
def = std::dynamic_pointer_cast<CPlayerInterface>(playerint[rightSide.color]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!settings["session"]["headless"].Bool())
|
if(!settings["session"]["headless"].Bool())
|
||||||
@@ -610,18 +625,6 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto callBattleStart = [&](PlayerColor color, ui8 side)
|
|
||||||
{
|
|
||||||
if(vstd::contains(battleints, color))
|
|
||||||
battleints[color]->battleStart(leftSide.armyObject, rightSide.armyObject, info->tile, leftSide.hero, rightSide.hero, side);
|
|
||||||
};
|
|
||||||
|
|
||||||
callBattleStart(leftSide.color, 0);
|
|
||||||
callBattleStart(rightSide.color, 1);
|
|
||||||
callBattleStart(PlayerColor::UNFLAGGABLE, 1);
|
|
||||||
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
|
||||||
callBattleStart(PlayerColor::SPECTATOR, 1);
|
|
||||||
|
|
||||||
if(info->tacticDistance && vstd::contains(battleints, info->sides[info->tacticsSide].color))
|
if(info->tacticDistance && vstd::contains(battleints, info->sides[info->tacticsSide].color))
|
||||||
{
|
{
|
||||||
boost::thread(&CClient::commenceTacticPhaseForInt, this, battleints[info->sides[info->tacticsSide].color]);
|
boost::thread(&CClient::commenceTacticPhaseForInt, this, battleints[info->sides[info->tacticsSide].color]);
|
||||||
|
|||||||
@@ -703,11 +703,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
battleResult.data->exp[0] = heroAttacker->calculateXp(battleResult.data->exp[0]);//scholar skill
|
battleResult.data->exp[0] = heroAttacker->calculateXp(battleResult.data->exp[0]);//scholar skill
|
||||||
if(heroDefender)
|
if(heroDefender)
|
||||||
battleResult.data->exp[1] = heroDefender->calculateXp(battleResult.data->exp[1]);
|
battleResult.data->exp[1] = heroDefender->calculateXp(battleResult.data->exp[1]);
|
||||||
|
|
||||||
const CArmedInstance *bEndArmy1 = gs->curB->sides.at(0).armyObject;
|
|
||||||
const CArmedInstance *bEndArmy2 = gs->curB->sides.at(1).armyObject;
|
|
||||||
const BattleResult::EResult result = battleResult.get()->result;
|
|
||||||
|
|
||||||
auto findBattleQuery = [this]() -> std::shared_ptr<CBattleQuery>
|
auto findBattleQuery = [this]() -> std::shared_ptr<CBattleQuery>
|
||||||
{
|
{
|
||||||
for (auto &q : queries.allQueries())
|
for (auto &q : queries.allQueries())
|
||||||
@@ -732,8 +728,39 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
//Check how many battle queries were created (number of players blocked by battle)
|
//Check how many battle queries were created (number of players blocked by battle)
|
||||||
const int queriedPlayers = battleQuery ? (int)boost::count(queries.allQueries(), battleQuery) : 0;
|
const int queriedPlayers = battleQuery ? (int)boost::count(queries.allQueries(), battleQuery) : 0;
|
||||||
finishingBattle = make_unique<FinishingBattleHelper>(battleQuery, queriedPlayers);
|
finishingBattle = make_unique<FinishingBattleHelper>(battleQuery, queriedPlayers);
|
||||||
|
|
||||||
|
auto battleDialogQuery = std::make_shared<CBattleDialogQuery>(this, gs->curB);
|
||||||
|
battleResult.data->queryID = battleDialogQuery->queryID;
|
||||||
|
queries.addQuery(battleDialogQuery);
|
||||||
|
sendAndApply(battleResult.data); //after this point casualties objects are destroyed
|
||||||
|
}
|
||||||
|
|
||||||
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
|
void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
|
||||||
|
{
|
||||||
|
auto findBattleQuery = [this, battleInfo]() -> std::shared_ptr<CBattleQuery>
|
||||||
|
{
|
||||||
|
for (auto &q : queries.allQueries())
|
||||||
|
{
|
||||||
|
if (auto bq = std::dynamic_pointer_cast<CBattleQuery>(q))
|
||||||
|
if (bq->bi == battleInfo)
|
||||||
|
return bq;
|
||||||
|
}
|
||||||
|
return std::shared_ptr<CBattleQuery>();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto battleQuery = findBattleQuery();
|
||||||
|
if (!battleQuery)
|
||||||
|
{
|
||||||
|
logGlobal->error("Cannot find battle query!");
|
||||||
|
}
|
||||||
|
if (battleQuery != queries.topQuery(battleInfo->sides[0].color))
|
||||||
|
complain("Player " + boost::lexical_cast<std::string>(battleInfo->sides[0].color) + " although in battle has no battle query at the top!");
|
||||||
|
|
||||||
|
const CArmedInstance *bEndArmy1 = battleInfo->sides.at(0).armyObject;
|
||||||
|
const CArmedInstance *bEndArmy2 = battleInfo->sides.at(1).armyObject;
|
||||||
|
const BattleResult::EResult result = battleResult.get()->result;
|
||||||
|
|
||||||
|
CasualtiesAfterBattle cab1(bEndArmy1, battleInfo), cab2(bEndArmy2, battleInfo); //calculate casualties before deleting battle
|
||||||
ChangeSpells cs; //for Eagle Eye
|
ChangeSpells cs; //for Eagle Eye
|
||||||
|
|
||||||
if (finishingBattle->winnerHero)
|
if (finishingBattle->winnerHero)
|
||||||
@@ -741,7 +768,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
if (int eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_VAL2, SecondarySkill::EAGLE_EYE))
|
if (int eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_VAL2, SecondarySkill::EAGLE_EYE))
|
||||||
{
|
{
|
||||||
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
||||||
for(auto & spellId : gs->curB->sides.at(!battleResult.data->winner).usedSpellsHistory)
|
for(auto & spellId : battleInfo->sides.at(!battleResult.data->winner).usedSpellsHistory)
|
||||||
{
|
{
|
||||||
auto spell = spellId.toSpell(VLC->spells());
|
auto spell = spellId.toSpell(VLC->spells());
|
||||||
if(spell && spell->getLevel() <= eagleEyeLevel && !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId()) && getRandomGenerator().nextInt(99) < eagleEyeChance)
|
if(spell && spell->getLevel() <= eagleEyeLevel && !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId()) && getRandomGenerator().nextInt(99) < eagleEyeChance)
|
||||||
@@ -770,8 +797,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
ma.src = ArtifactLocation(finishingBattle->loserHero, artSlot.first);
|
ma.src = ArtifactLocation(finishingBattle->loserHero, artSlot.first);
|
||||||
const CArtifactInstance * art = ma.src.getArt();
|
const CArtifactInstance * art = ma.src.getArt();
|
||||||
if (art && !art->artType->isBig() &&
|
if (art && !art->artType->isBig() &&
|
||||||
art->artType->id != ArtifactID::SPELLBOOK)
|
art->artType->id != ArtifactID::SPELLBOOK)
|
||||||
// don't move war machines or locked arts (spellbook)
|
// don't move war machines or locked arts (spellbook)
|
||||||
{
|
{
|
||||||
sendMoveArtifact(art, &ma);
|
sendMoveArtifact(art, &ma);
|
||||||
}
|
}
|
||||||
@@ -781,7 +808,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
//we assume that no big artifacts can be found
|
//we assume that no big artifacts can be found
|
||||||
MoveArtifact ma;
|
MoveArtifact ma;
|
||||||
ma.src = ArtifactLocation(finishingBattle->loserHero,
|
ma.src = ArtifactLocation(finishingBattle->loserHero,
|
||||||
ArtifactPosition(GameConstants::BACKPACK_START)); //backpack automatically shifts arts to beginning
|
ArtifactPosition(GameConstants::BACKPACK_START)); //backpack automatically shifts arts to beginning
|
||||||
const CArtifactInstance * art = ma.src.getArt();
|
const CArtifactInstance * art = ma.src.getArt();
|
||||||
if (art->artType->id != ArtifactID::GRAIL) //grail may not be won
|
if (art->artType->id != ArtifactID::GRAIL) //grail may not be won
|
||||||
{
|
{
|
||||||
@@ -803,7 +830,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto armySlot : gs->curB->battleGetArmyObject(!battleResult.data->winner)->stacks)
|
for (auto armySlot : battleInfo->sides.at(!battleResult.data->winner).armyObject->stacks)
|
||||||
{
|
{
|
||||||
auto artifactsWorn = armySlot.second->artifactsWorn;
|
auto artifactsWorn = armySlot.second->artifactsWorn;
|
||||||
for (auto artSlot : artifactsWorn)
|
for (auto artSlot : artifactsWorn)
|
||||||
@@ -819,11 +846,6 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto battleDialogQuery = std::make_shared<CBattleDialogQuery>(this, battleQuery->bi);
|
|
||||||
battleResult.data->queryID = battleDialogQuery->queryID;
|
|
||||||
queries.addQuery(battleDialogQuery);
|
|
||||||
sendAndApply(battleResult.data); //after this point casualties objects are destroyed
|
|
||||||
|
|
||||||
if (arts.size()) //display loot
|
if (arts.size()) //display loot
|
||||||
{
|
{
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
@@ -884,33 +906,25 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
|||||||
}
|
}
|
||||||
cab1.updateArmy(this);
|
cab1.updateArmy(this);
|
||||||
cab2.updateArmy(this); //take casualties after battle is deleted
|
cab2.updateArmy(this); //take casualties after battle is deleted
|
||||||
|
|
||||||
if(battleResult.data->winner != BattleSide::ATTACKER && heroAttacker) //remove beaten Attacker
|
if(finishingBattle->loserHero) //remove beaten hero
|
||||||
{
|
{
|
||||||
RemoveObject ro(heroAttacker->id);
|
RemoveObject ro(finishingBattle->loserHero->id);
|
||||||
sendAndApply(&ro);
|
sendAndApply(&ro);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(battleResult.data->winner != BattleSide::DEFENDER && heroDefender) //remove beaten Defender
|
if(battleResult.data->winner == BattleSide::DEFENDER
|
||||||
|
&& finishingBattle->winnerHero
|
||||||
|
&& finishingBattle->winnerHero->visitedTown
|
||||||
|
&& !finishingBattle->winnerHero->inTownGarrison
|
||||||
|
&& finishingBattle->winnerHero->visitedTown->garrisonHero == finishingBattle->winnerHero)
|
||||||
{
|
{
|
||||||
RemoveObject ro(heroDefender->id);
|
swapGarrisonOnSiege(finishingBattle->winnerHero->visitedTown->id); //return defending visitor from garrison to its rightful place
|
||||||
sendAndApply(&ro);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(battleResult.data->winner == BattleSide::DEFENDER
|
|
||||||
&& heroDefender
|
|
||||||
&& heroDefender->visitedTown
|
|
||||||
&& !heroDefender->inTownGarrison
|
|
||||||
&& heroDefender->visitedTown->garrisonHero == heroDefender)
|
|
||||||
{
|
|
||||||
swapGarrisonOnSiege(heroDefender->visitedTown->id); //return defending visitor from garrison to its rightful place
|
|
||||||
}
|
}
|
||||||
//give exp
|
//give exp
|
||||||
if(battleResult.data->exp[0] && heroAttacker && battleResult.get()->winner == BattleSide::ATTACKER)
|
if(battleResult.data->exp[finishingBattle->winnerSide] && finishingBattle->winnerHero)
|
||||||
changePrimSkill(heroAttacker, PrimarySkill::EXPERIENCE, battleResult.data->exp[0]);
|
changePrimSkill(finishingBattle->winnerHero, PrimarySkill::EXPERIENCE, battleResult.data->exp[finishingBattle->winnerSide]);
|
||||||
else if(battleResult.data->exp[1] && heroDefender && battleResult.get()->winner == BattleSide::DEFENDER)
|
|
||||||
changePrimSkill(heroDefender, PrimarySkill::EXPERIENCE, battleResult.data->exp[1]);
|
|
||||||
|
|
||||||
queries.popIfTop(battleQuery);
|
queries.popIfTop(battleQuery);
|
||||||
|
|
||||||
//--> continuation (battleAfterLevelUp) occurs after level-up queries are handled or on removing query (above)
|
//--> continuation (battleAfterLevelUp) occurs after level-up queries are handled or on removing query (above)
|
||||||
@@ -7259,7 +7273,7 @@ void CGameHandler::showInfoDialog(const std::string & msg, PlayerColor player)
|
|||||||
showInfoDialog(&iw);
|
showInfoDialog(&iw);
|
||||||
}
|
}
|
||||||
|
|
||||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat):
|
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, const BattleInfo * bat):
|
||||||
army(_army)
|
army(_army)
|
||||||
{
|
{
|
||||||
heroWithDeadCommander = ObjectInstanceID();
|
heroWithDeadCommander = ObjectInstanceID();
|
||||||
@@ -7411,12 +7425,14 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const
|
|||||||
loserHero = result.winner != 0 ? info.sides[0].hero : info.sides[1].hero;
|
loserHero = result.winner != 0 ? info.sides[0].hero : info.sides[1].hero;
|
||||||
victor = info.sides[result.winner].color;
|
victor = info.sides[result.winner].color;
|
||||||
loser = info.sides[!result.winner].color;
|
loser = info.sides[!result.winner].color;
|
||||||
|
winnerSide = result.winner;
|
||||||
remainingBattleQueriesCount = RemainingBattleQueriesCount;
|
remainingBattleQueriesCount = RemainingBattleQueriesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
||||||
{
|
{
|
||||||
winnerHero = loserHero = nullptr;
|
winnerHero = loserHero = nullptr;
|
||||||
|
winnerSide = 0;
|
||||||
remainingBattleQueriesCount = 0;
|
remainingBattleQueriesCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ struct CasualtiesAfterBattle
|
|||||||
TSummoned summoned;
|
TSummoned summoned;
|
||||||
ObjectInstanceID heroWithDeadCommander; //TODO: unify stack locations
|
ObjectInstanceID heroWithDeadCommander; //TODO: unify stack locations
|
||||||
|
|
||||||
CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat);
|
CasualtiesAfterBattle(const CArmedInstance * _army, const BattleInfo * bat);
|
||||||
void updateArmy(CGameHandler *gh);
|
void updateArmy(CGameHandler *gh);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,7 +129,8 @@ public:
|
|||||||
////used only in endBattle - don't touch elsewhere
|
////used only in endBattle - don't touch elsewhere
|
||||||
bool visitObjectAfterVictory;
|
bool visitObjectAfterVictory;
|
||||||
//
|
//
|
||||||
void endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2); //ends battle
|
void endBattle(int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2); //ends battle
|
||||||
|
void endBattleConfirm(const BattleInfo * battleInfo);
|
||||||
|
|
||||||
void makeAttack(const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter);
|
void makeAttack(const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter);
|
||||||
|
|
||||||
@@ -309,6 +310,7 @@ public:
|
|||||||
|
|
||||||
const CGHeroInstance *winnerHero, *loserHero;
|
const CGHeroInstance *winnerHero, *loserHero;
|
||||||
PlayerColor victor, loser;
|
PlayerColor victor, loser;
|
||||||
|
ui8 winnerSide;
|
||||||
|
|
||||||
int remainingBattleQueriesCount;
|
int remainingBattleQueriesCount;
|
||||||
|
|
||||||
@@ -318,6 +320,7 @@ public:
|
|||||||
h & loserHero;
|
h & loserHero;
|
||||||
h & victor;
|
h & victor;
|
||||||
h & loser;
|
h & loser;
|
||||||
|
h & winnerSide;
|
||||||
h & remainingBattleQueriesCount;
|
h & remainingBattleQueriesCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -396,6 +396,10 @@ void CBattleDialogQuery::onRemoval(PlayerColor color)
|
|||||||
{
|
{
|
||||||
gh->startBattlePrimary(bi->sides[0].armyObject, bi->sides[1].armyObject, bi->tile, bi->sides[0].hero, bi->sides[1].hero, bi->creatureBank, bi->town);
|
gh->startBattlePrimary(bi->sides[0].armyObject, bi->sides[1].armyObject, bi->tile, bi->sides[0].hero, bi->sides[1].hero, bi->creatureBank, bi->town);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gh->endBattleConfirm(bi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
|
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
|
||||||
|
|||||||
Reference in New Issue
Block a user