mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
First step
This commit is contained in:
parent
ae1d2c50e2
commit
219a282916
@ -81,7 +81,7 @@ public:
|
||||
//void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
|
||||
//void battleAttack(const BattleAttack *ba) override; //called when stack is performing attack
|
||||
//void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) override; //called when stack receives damage (after battleAttack())
|
||||
//void battleEnd(const BattleResult *br) override;
|
||||
//void battleEnd(const BattleResult *br, QueryID queryID) override;
|
||||
//void battleResultsApplied() override; //called when all effects of last battle are applied
|
||||
//void battleNewRoundFirst(int round) override; //called at the beginning of each turn before changes are applied;
|
||||
//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
|
||||
|
@ -1067,7 +1067,7 @@ void AIGateway::battleStart(const CCreatureSet * army1, const CCreatureSet * arm
|
||||
CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
|
||||
}
|
||||
|
||||
void AIGateway::battleEnd(const BattleResult * br)
|
||||
void AIGateway::battleEnd(const BattleResult * br, QueryID queryID)
|
||||
{
|
||||
NET_EVENT_HANDLER;
|
||||
assert(status.getBattle() == ONGOING_BATTLE);
|
||||
@ -1075,7 +1075,7 @@ void AIGateway::battleEnd(const BattleResult * br)
|
||||
bool won = br->winner == myCb->battleGetMySide();
|
||||
logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
|
||||
battlename.clear();
|
||||
CAdventureAI::battleEnd(br);
|
||||
CAdventureAI::battleEnd(br, queryID);
|
||||
}
|
||||
|
||||
void AIGateway::waitTillFree()
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState) override;
|
||||
|
||||
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
|
||||
void battleEnd(const BattleResult * br) override;
|
||||
void battleEnd(const BattleResult * br, QueryID queryID) override;
|
||||
|
||||
void makeTurn();
|
||||
|
||||
|
@ -182,7 +182,7 @@ void CStupidAI::battleStacksAttacked(const std::vector<BattleStackAttacked> & bs
|
||||
print("battleStacksAttacked called");
|
||||
}
|
||||
|
||||
void CStupidAI::battleEnd(const BattleResult *br)
|
||||
void CStupidAI::battleEnd(const BattleResult *br, QueryID queryID)
|
||||
{
|
||||
print("battleEnd called");
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
|
||||
void battleAttack(const BattleAttack *ba) override; //called when stack is performing attack
|
||||
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) override; //called when stack receives damage (after battleAttack())
|
||||
void battleEnd(const BattleResult *br) override;
|
||||
void battleEnd(const BattleResult *br, QueryID queryID) override;
|
||||
//void battleResultsApplied() override; //called when all effects of last battle are applied
|
||||
void battleNewRoundFirst(int round) override; //called at the beginning of each turn before changes are applied;
|
||||
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
|
||||
|
@ -1583,7 +1583,7 @@ void VCAI::battleStart(const CCreatureSet * army1, const CCreatureSet * army2, i
|
||||
CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
|
||||
}
|
||||
|
||||
void VCAI::battleEnd(const BattleResult * br)
|
||||
void VCAI::battleEnd(const BattleResult * br, QueryID queryID)
|
||||
{
|
||||
NET_EVENT_HANDLER;
|
||||
assert(status.getBattle() == ONGOING_BATTLE);
|
||||
@ -1591,7 +1591,7 @@ void VCAI::battleEnd(const BattleResult * br)
|
||||
bool won = br->winner == myCb->battleGetMySide();
|
||||
logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
|
||||
battlename.clear();
|
||||
CAdventureAI::battleEnd(br);
|
||||
CAdventureAI::battleEnd(br, queryID);
|
||||
}
|
||||
|
||||
void VCAI::waitTillFree()
|
||||
|
@ -201,7 +201,7 @@ public:
|
||||
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
|
||||
|
||||
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
|
||||
void battleEnd(const BattleResult * br) override;
|
||||
void battleEnd(const BattleResult * br, QueryID queryID) override;
|
||||
|
||||
void makeTurn();
|
||||
void mainLoop();
|
||||
|
@ -707,7 +707,9 @@ 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)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (settings["adventure"]["quickCombat"].Bool())
|
||||
//quick combat with neutral creatures only
|
||||
auto * army2_object = dynamic_cast<const CGObjectInstance *>(army2);
|
||||
if(army2_object && army2_object->getOwner() == PlayerColor::UNFLAGGABLE && settings["adventure"]["quickCombat"].Bool())
|
||||
{
|
||||
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
|
||||
autofightingAI->init(env, cb);
|
||||
@ -922,7 +924,7 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleEnd(const BattleResult *br)
|
||||
void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if(isAutoFightOn || autofightingAI)
|
||||
@ -933,7 +935,12 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
|
||||
|
||||
if(!battleInt)
|
||||
{
|
||||
GH.pushIntT<CBattleResultWindow>(*br, *this);
|
||||
auto wnd = std::make_shared<CBattleResultWindow>(*br, *this, true);
|
||||
wnd->resultCallback = [=](ui32 selection)
|
||||
{
|
||||
cb->selectionMade(selection, queryID);
|
||||
};
|
||||
GH.pushInt(wnd);
|
||||
// #1490 - during AI turn when quick combat is on, we need to display the message and wait for user to close it.
|
||||
// Otherwise NewTurn causes freeze.
|
||||
waitWhileDialog();
|
||||
@ -944,7 +951,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
|
||||
|
||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||
|
||||
battleInt->battleFinished(*br);
|
||||
battleInt->battleFinished(*br, queryID);
|
||||
adventureInt->quickCombatUnlock();
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ public:
|
||||
void actionStarted(const BattleAction& action) override;//occurs BEFORE action taken by active stack or by the hero
|
||||
BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack
|
||||
void battleAttack(const BattleAttack *ba) override; //stack performs attack
|
||||
void battleEnd(const BattleResult *br) override; //end of battle
|
||||
void battleEnd(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 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 battleLogMessage(const std::vector<MetaString> & lines) override;
|
||||
|
@ -583,7 +583,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
auto & leftSide = info->sides[0], & rightSide = info->sides[1];
|
||||
|
||||
//If quick combat is not, do not prepare interfaces for battleint
|
||||
if(!settings["adventure"]["quickCombat"].Bool())
|
||||
if(rightSide.color != PlayerColor::NEUTRAL || !settings["adventure"]["quickCombat"].Bool())
|
||||
{
|
||||
if(vstd::contains(playerint, leftSide.color) && playerint[leftSide.color]->human)
|
||||
att = std::dynamic_pointer_cast<CPlayerInterface>(playerint[leftSide.color]);
|
||||
|
@ -708,7 +708,7 @@ void BattleUpdateGateState::applyFirstCl(CClient * cl)
|
||||
|
||||
void BattleResult::applyFirstCl(CClient *cl)
|
||||
{
|
||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleEnd, this);
|
||||
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleEnd, this, queryID);
|
||||
cl->battleFinished();
|
||||
}
|
||||
|
||||
|
@ -859,11 +859,14 @@ void CBattleInterface::reallySurrender()
|
||||
|
||||
void CBattleInterface::bAutofightf()
|
||||
{
|
||||
if (spellDestSelectMode) //we are casting a spell
|
||||
//if(bresult) //battle is already finished
|
||||
//return;
|
||||
|
||||
if(spellDestSelectMode) //we are casting a spell
|
||||
return;
|
||||
|
||||
//Stop auto-fight mode
|
||||
if (curInt->isAutoFightOn)
|
||||
if(curInt->isAutoFightOn)
|
||||
{
|
||||
assert(curInt->autofightingAI);
|
||||
curInt->isAutoFightOn = false;
|
||||
@ -1129,7 +1132,8 @@ void CBattleInterface::newRoundFirst( int round )
|
||||
|
||||
void CBattleInterface::newRound(int number)
|
||||
{
|
||||
console->addText(CGI->generaltexth->allTexts[412]);
|
||||
if(console)
|
||||
console->addText(CGI->generaltexth->allTexts[412]);
|
||||
}
|
||||
|
||||
void CBattleInterface::giveCommand(EActionType action, BattleHex tile, si32 additional)
|
||||
@ -1254,7 +1258,7 @@ void CBattleInterface::stackIsCatapulting(const CatapultAttack & ca)
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::battleFinished(const BattleResult& br)
|
||||
void CBattleInterface::battleFinished(const BattleResult& br, QueryID queryID)
|
||||
{
|
||||
bresult = &br;
|
||||
{
|
||||
@ -1262,19 +1266,25 @@ void CBattleInterface::battleFinished(const BattleResult& br)
|
||||
animsAreDisplayed.waitUntil(false);
|
||||
}
|
||||
setActiveStack(nullptr);
|
||||
displayBattleFinished();
|
||||
displayBattleFinished(queryID);
|
||||
}
|
||||
|
||||
void CBattleInterface::displayBattleFinished()
|
||||
void CBattleInterface::displayBattleFinished(QueryID queryID)
|
||||
{
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
|
||||
if(settings["session"]["spectate"].Bool() && settings["session"]["spectate-skip-battle-result"].Bool())
|
||||
{
|
||||
curInt->cb->selectionMade(0, queryID);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
GH.pushInt(std::make_shared<CBattleResultWindow>(*bresult, *(this->curInt)));
|
||||
auto wnd = std::make_shared<CBattleResultWindow>(*bresult, *(this->curInt));
|
||||
wnd->resultCallback = [=](ui32 selection)
|
||||
{
|
||||
curInt->cb->selectionMade(selection, queryID);
|
||||
};
|
||||
GH.pushInt(wnd);
|
||||
curInt->waitWhileDialog(); // Avoid freeze when AI end turn after battle. Check bug #1897
|
||||
CPlayerInterface::battleInt = nullptr;
|
||||
}
|
||||
|
@ -353,8 +353,8 @@ public:
|
||||
void newRound(int number); //caled when round is ended; number is the number of round
|
||||
void hexLclicked(int whichOne); //hex only call-in
|
||||
void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
|
||||
void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed
|
||||
void displayBattleFinished(); //displays battle result
|
||||
void battleFinished(const BattleResult& br, QueryID queryID); //called when battle is finished - battleresult window should be printed
|
||||
void displayBattleFinished(QueryID queryID); //displays battle result
|
||||
void spellCast(const BattleSpellCast *sc); //called when a hero casts a spell
|
||||
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
|
||||
void castThisSpell(SpellID spellID); //called when player has chosen a spell from spellbook
|
||||
|
@ -394,7 +394,7 @@ void CBattleOptionsWindow::bExitf()
|
||||
close();
|
||||
}
|
||||
|
||||
CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner)
|
||||
CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay)
|
||||
: owner(_owner)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
@ -405,6 +405,12 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterfa
|
||||
|
||||
exit = std::make_shared<CButton>(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, SDLK_RETURN);
|
||||
exit->setBorderColor(Colors::METALLIC_GOLD);
|
||||
|
||||
if(allowReplay)
|
||||
{
|
||||
repeat = std::make_shared<CButton>(Point(24, 505), "icn6432.def", std::make_pair("", ""), [&](){ bRepeatf();}, SDLK_ESCAPE);
|
||||
repeat->setBorderColor(Colors::METALLIC_GOLD);
|
||||
}
|
||||
|
||||
if(br.winner == 0) //attacker won
|
||||
{
|
||||
@ -566,6 +572,7 @@ void CBattleResultWindow::show(SDL_Surface * to)
|
||||
|
||||
void CBattleResultWindow::bExitf()
|
||||
{
|
||||
resultCallback(0);
|
||||
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||
|
||||
close();
|
||||
@ -579,6 +586,22 @@ void CBattleResultWindow::bExitf()
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
void CBattleResultWindow::bRepeatf()
|
||||
{
|
||||
resultCallback(1);
|
||||
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||
|
||||
close();
|
||||
|
||||
if(dynamic_cast<CBattleInterface*>(GH.topInt().get()))
|
||||
GH.popInts(1); //pop battle interface if present
|
||||
|
||||
//Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle,
|
||||
//so we can be sure that there is no dialogs left on GUI stack.
|
||||
intTmp.showingDialog->setn(false);
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
Point CClickableHex::getXYUnitAnim(BattleHex hexNum, const CStack * stack, CBattleInterface * cbi)
|
||||
{
|
||||
assert(cbi);
|
||||
|
@ -118,14 +118,17 @@ private:
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::shared_ptr<CButton> exit;
|
||||
std::shared_ptr<CButton> repeat;
|
||||
std::vector<std::shared_ptr<CAnimImage>> icons;
|
||||
std::shared_ptr<CTextBox> description;
|
||||
CPlayerInterface & owner;
|
||||
public:
|
||||
CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner);
|
||||
CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay = false);
|
||||
~CBattleResultWindow();
|
||||
|
||||
void bExitf(); //exit button callback
|
||||
void bRepeatf(); //repeat button callback
|
||||
std::function<void(int result)> resultCallback; //callback receiving which button was pressed
|
||||
|
||||
void activate() override;
|
||||
void show(SDL_Surface * to = 0) override;
|
||||
|
@ -219,9 +219,9 @@ void CAdventureAI::battleSpellCast(const BattleSpellCast * sc)
|
||||
battleAI->battleSpellCast(sc);
|
||||
}
|
||||
|
||||
void CAdventureAI::battleEnd(const BattleResult * br)
|
||||
void CAdventureAI::battleEnd(const BattleResult * br, QueryID queryID)
|
||||
{
|
||||
battleAI->battleEnd(br);
|
||||
battleAI->battleEnd(br, queryID);
|
||||
battleAI.reset();
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ public:
|
||||
virtual void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance) override;
|
||||
virtual void battleAttack(const BattleAttack *ba) override;
|
||||
virtual void battleSpellCast(const BattleSpellCast *sc) override;
|
||||
virtual void battleEnd(const BattleResult *br) override;
|
||||
virtual void battleEnd(const BattleResult *br, QueryID queryID) override;
|
||||
virtual void battleUnitsChanged(const std::vector<UnitChanges> & units, const std::vector<CustomEffectInfo> & customEffects) override;
|
||||
|
||||
virtual void saveGame(BinarySerializer & h, const int version) override;
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
virtual void actionStarted(const BattleAction &action){};//occurs BEFORE every action taken by any stack or by the hero
|
||||
virtual void battleAttack(const BattleAttack *ba){}; //called when stack is performing attack
|
||||
virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa){}; //called when stack receives damage (after battleAttack())
|
||||
virtual void battleEnd(const BattleResult *br){};
|
||||
virtual void battleEnd(const BattleResult *br, QueryID queryID){};
|
||||
virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied;
|
||||
virtual void battleNewRound(int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
virtual void battleLogMessage(const std::vector<MetaString> & lines){};
|
||||
|
@ -1434,7 +1434,7 @@ struct BattleSetActiveStack : public CPackForClient
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleResult : public CPackForClient
|
||||
struct BattleResult : public Query
|
||||
{
|
||||
enum EResult {NORMAL = 0, ESCAPE = 1, SURRENDER = 2};
|
||||
|
||||
@ -1447,6 +1447,7 @@ struct BattleResult : public CPackForClient
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyGs(CGameState *gs);
|
||||
|
||||
|
||||
EResult result;
|
||||
ui8 winner; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
|
||||
std::map<ui32,si32> casualties[2]; //first => casualties of attackers - map crid => number
|
||||
@ -1455,6 +1456,7 @@ struct BattleResult : public CPackForClient
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & queryID;
|
||||
h & result;
|
||||
h & winner;
|
||||
h & casualties[0];
|
||||
|
@ -818,6 +818,10 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto battleDialogQuery = std::make_shared<CDialogQuery>(this);
|
||||
battleResult.data->queryID = battleDialogQuery->queryID;
|
||||
queries.addQuery(battleDialogQuery);
|
||||
sendAndApply(battleResult.data); //after this point casualties objects are destroyed
|
||||
|
||||
if (arts.size()) //display loot
|
||||
|
@ -380,6 +380,16 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const
|
||||
return CDialogQuery::blocksPack(pack);
|
||||
}
|
||||
|
||||
void CBattleDialogQuery::onRemoval(PlayerColor color)
|
||||
{
|
||||
assert(answer);
|
||||
if(*answer == 1)
|
||||
{
|
||||
int a = 0;
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
||||
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
|
||||
{
|
||||
assert(answer);
|
||||
|
@ -144,6 +144,12 @@ public:
|
||||
virtual bool blocksPack(const CPack *pack) const override;
|
||||
};
|
||||
|
||||
class CBattleDialogQuery : public CDialogQuery
|
||||
{
|
||||
public:
|
||||
virtual void onRemoval(PlayerColor color) override;
|
||||
};
|
||||
|
||||
//yes/no and component selection dialogs
|
||||
class CBlockingDialogQuery : public CDialogQuery
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user