1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-13 13:18:43 +02:00

Try to handle queries by ai

This commit is contained in:
nordsoft 2022-11-05 06:34:38 +04:00
parent 0c4e50b63c
commit e9cf3ede2a
6 changed files with 66 additions and 41 deletions

View File

@ -1075,6 +1075,9 @@ void AIGateway::battleEnd(const BattleResult * br, QueryID queryID)
bool won = br->winner == myCb->battleGetMySide();
logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
battlename.clear();
status.addQuery(queryID, "Combat result dialog");
answerQuery(queryID, 0);
status.removeQuery(queryID); //do not wait for answer
CAdventureAI::battleEnd(br, queryID);
}

View File

@ -1591,6 +1591,9 @@ void VCAI::battleEnd(const BattleResult * br, QueryID queryID)
bool won = br->winner == myCb->battleGetMySide();
logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
battlename.clear();
status.addQuery(queryID, "Combat result dialog");
answerQuery(queryID, 0);
status.removeQuery(queryID); //do not wait for answer
CAdventureAI::battleEnd(br, queryID);
}

View File

@ -1434,6 +1434,26 @@ struct BattleSetActiveStack : public CPackForClient
}
};
struct BattleResultAccepted : public CPackForClient
{
void applyGs(CGameState * gs);
CGHeroInstance * hero1 = nullptr;
CGHeroInstance * hero2 = nullptr;
CArmedInstance * army1 = nullptr;
CArmedInstance * army2 = nullptr;
TExpType exp[2];
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hero1;
h & hero2;
h & army1;
h & army2;
h & exp;
}
};
struct BattleResult : public Query
{
enum EResult {NORMAL = 0, ESCAPE = 1, SURRENDER = 2};

View File

@ -1390,10 +1390,17 @@ void BattleResult::applyGs(CGameState *gs)
for (auto & elem : gs->curB->stacks)
delete elem;
for(int i = 0; i < 2; i++)
gs->curB->battleGetArmyObject(i)->battle = nullptr;
for(int i = 0; i < 2; ++i)
gs->curB.dellNull();
}
void BattleResultAccepted::applyGs(CGameState * gs)
{
for(auto * h : {hero1, hero2})
{
if(auto h = gs->curB->battleGetFightingHero(i))
if(h)
{
h->removeBonusesRecursive(Bonus::OneBattle); //remove any "until next battle" bonuses
if (h->commander && h->commander->alive)
@ -1409,16 +1416,16 @@ void BattleResult::applyGs(CGameState *gs)
if(VLC->modh->modules.STACK_EXP)
{
for(int i = 0; i < 2; i++)
{
if(exp[i])
gs->curB->battleGetArmyObject(i)->giveStackExp(exp[i]);
{
if(auto * army = (i == 0 ? army1 : army2))
army->giveStackExp(exp[i]);
}
}
CBonusSystemNode::treeHasChanged();
}
for(int i = 0; i < 2; i++)
gs->curB->battleGetArmyObject(i)->battle = nullptr;
gs->curB.dellNull();
}
DLL_LINKAGE void BattleLogMessage::applyGs(CGameState *gs)

View File

@ -280,6 +280,7 @@ void registerTypesClientPacks2(Serializer &s)
s.template registerType<CPackForClient, BattleNextRound>();
s.template registerType<CPackForClient, BattleSetActiveStack>();
s.template registerType<CPackForClient, BattleResult>();
s.template registerType<CPackForClient, BattleResultAccepted>();
s.template registerType<CPackForClient, BattleLogMessage>();
s.template registerType<CPackForClient, BattleStackMoved>();
s.template registerType<CPackForClient, BattleAttack>();

View File

@ -704,24 +704,13 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
if(heroDefender)
battleResult.data->exp[1] = heroDefender->calculateXp(battleResult.data->exp[1]);
auto findBattleQuery = [this]() -> std::shared_ptr<CBattleQuery>
{
for (auto &q : queries.allQueries())
{
if (auto bq = std::dynamic_pointer_cast<CBattleQuery>(q))
if (bq->bi == gs->curB)
return bq;
}
return std::shared_ptr<CBattleQuery>();
};
auto battleQuery = findBattleQuery();
auto battleQuery = std::dynamic_pointer_cast<CBattleQuery>(queries.topQuery(gs->curB->sides[0].color));
if (!battleQuery)
{
logGlobal->error("Cannot find battle query!");
complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " has no battle query at the top!");
return;
}
if (battleQuery != queries.topQuery(gs->curB->sides[0].color))
complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " although in battle has no battle query at the top!");
battleQuery->result = boost::make_optional(*battleResult.data);
@ -737,24 +726,13 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
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)
auto battleQuery = std::dynamic_pointer_cast<CBattleQuery>(queries.topQuery(battleInfo->sides.at(0).color));
if(!battleQuery)
{
logGlobal->error("Cannot find battle query!");
complain("Player " + boost::lexical_cast<std::string>(battleInfo->sides.at(0).color) + " has no battle query at the top!");
return;
}
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;
@ -927,6 +905,15 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
queries.popIfTop(battleQuery);
BattleResultAccepted raccepted;
raccepted.army1 = const_cast<CArmedInstance*>(bEndArmy1);
raccepted.army2 = const_cast<CArmedInstance*>(bEndArmy2);
raccepted.hero1 = const_cast<CGHeroInstance*>(battleInfo->sides.at(0).hero);
raccepted.hero2 = const_cast<CGHeroInstance*>(battleInfo->sides.at(1).hero);
raccepted.exp[0] = battleResult.data->exp[0];
raccepted.exp[1] = battleResult.data->exp[1];
sendAndApply(&raccepted);
//--> continuation (battleAfterLevelUp) occurs after level-up queries are handled or on removing query (above)
}
@ -934,6 +921,8 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
{
LOG_TRACE(logGlobal);
if(!finishingBattle)
return;
finishingBattle->remainingBattleQueriesCount--;
logGlobal->trace("Decremented queries count to %d", finishingBattle->remainingBattleQueriesCount);
@ -1016,6 +1005,8 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
sendAndApply(&sah);
}
}
finishingBattle.reset();
}
void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter)