1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +02:00

Support draw scenario (doesnt work properly)

This commit is contained in:
nordsoft 2022-11-16 02:50:47 +04:00
parent 9b597fc8d4
commit b253b19dc3
7 changed files with 39 additions and 25 deletions

View File

@ -707,12 +707,15 @@ 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;
bool replay = (lastBattleArmies.first == army1 && lastBattleArmies.second == army2);
bool replay = (lastBattleArmies.first == army1 && lastBattleArmies.second == army2); //will be true if player already refused auto-battle result
lastBattleArmies.first = army1;
lastBattleArmies.second = army2;
//quick combat with neutral creatures only
auto * army2_object = dynamic_cast<const CGObjectInstance *>(army2);
if(!replay && army2_object && army2_object->getOwner() == PlayerColor::UNFLAGGABLE && settings["adventure"]["quickCombat"].Bool())
if((!replay && army2_object
&& army2_object->getOwner() == PlayerColor::UNFLAGGABLE
&& settings["adventure"]["quickCombat"].Bool())
|| settings["adventure"]["alwaysSkipBattle"].Bool())
{
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
autofightingAI->init(env, cb);
@ -938,7 +941,8 @@ void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
if(!battleInt)
{
auto wnd = std::make_shared<CBattleResultWindow>(*br, *this, true);
bool replay = !settings["adventure"]["alwaysSkipCombat"].Bool(); //do not allow manual replay
auto wnd = std::make_shared<CBattleResultWindow>(*br, *this, replay);
wnd->resultCallback = [=](ui32 selection)
{
cb->selectionMade(selection, queryID);

View File

@ -600,7 +600,7 @@ void CClient::battleStarted(const BattleInfo * info)
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
//Remove player interfaces for auto battle (quickCombat option)
if(att && att->isAutoFightOn)
{
att.reset();

View File

@ -570,9 +570,9 @@ void CBattleResultWindow::show(SDL_Surface * to)
CCS->videoh->update(pos.x + 107, pos.y + 70, screen, true, false);
}
void CBattleResultWindow::bExitf()
void CBattleResultWindow::buttonPressed(int button)
{
resultCallback(0);
resultCallback(button);
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
close();
@ -586,20 +586,14 @@ void CBattleResultWindow::bExitf()
CCS->videoh->close();
}
void CBattleResultWindow::bExitf()
{
buttonPressed(0);
}
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();
buttonPressed(1);
}
Point CClickableHex::getXYUnitAnim(BattleHex hexNum, const CStack * stack, CBattleInterface * cbi)

View File

@ -122,6 +122,8 @@ private:
std::vector<std::shared_ptr<CAnimImage>> icons;
std::shared_ptr<CTextBox> description;
CPlayerInterface & owner;
void buttonPressed(int button); //internal function for button callbacks
public:
CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay = false);
~CBattleResultWindow();

View File

@ -124,7 +124,7 @@
"type" : "object",
"additionalProperties" : false,
"default": {},
"required" : [ "heroSpeed", "enemySpeed", "scrollSpeed", "heroReminder", "quickCombat" ],
"required" : [ "heroSpeed", "enemySpeed", "scrollSpeed", "heroReminder", "quickCombat", "alwaysSkipCombat" ],
"properties" : {
"heroSpeed" : {
"type" : "number",
@ -144,7 +144,13 @@
},
"quickCombat" : {
"type" : "boolean",
"default" : true
"default" : true,
"description" : "enable to allow AI to play combats versus neutrals. Player can refuse battle result and replay it manually. This option can be switched from in-game menu"
},
"alwaysSkipCombat" : {
"type" : "boolean",
"default" : false,
"description" : "if enabled, all battles will be controlled by AI"
}
}
},

View File

@ -741,9 +741,9 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
CasualtiesAfterBattle cab1(bEndArmy1, battleInfo), cab2(bEndArmy2, battleInfo); //calculate casualties before deleting battle
ChangeSpells cs; //for Eagle Eye
if (finishingBattle->winnerHero)
if(!finishingBattle->isDraw() && finishingBattle->winnerHero)
{
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);
for(auto & spellId : battleInfo->sides.at(!battleResult.data->winner).usedSpellsHistory)
@ -756,7 +756,7 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
}
std::vector<const CArtifactInstance *> arts; //display them in window
if (result == BattleResult::NORMAL && finishingBattle->winnerHero)
if(result == BattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero)
{
auto sendMoveArtifact = [&](const CArtifactInstance *art, MoveArtifact *ma)
{
@ -890,6 +890,11 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
RemoveObject ro(finishingBattle->loserHero->id);
sendAndApply(&ro);
}
if(finishingBattle->isDraw() && finishingBattle->winnerHero) //for draw case both heroes should be removed
{
RemoveObject ro(finishingBattle->winnerHero->id);
sendAndApply(&ro);
}
if(battleResult.data->winner == BattleSide::DEFENDER
&& finishingBattle->winnerHero
@ -900,10 +905,10 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
swapGarrisonOnSiege(finishingBattle->winnerHero->visitedTown->id); //return defending visitor from garrison to its rightful place
}
//give exp
if(battleResult.data->exp[finishingBattle->winnerSide] && finishingBattle->winnerHero)
if(!finishingBattle->isDraw() && battleResult.data->exp[finishingBattle->winnerSide] && finishingBattle->winnerHero)
changePrimSkill(finishingBattle->winnerHero, PrimarySkill::EXPERIENCE, battleResult.data->exp[finishingBattle->winnerSide]);
queries.popIfTop(battleQuery);
//queries.popIfTop(battleQuery);
BattleResultAccepted raccepted;
raccepted.army1 = const_cast<CArmedInstance*>(bEndArmy1);
@ -914,6 +919,7 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
raccepted.exp[1] = battleResult.data->exp[1];
sendAndApply(&raccepted);
queries.popIfTop(battleQuery);
//--> continuation (battleAfterLevelUp) occurs after level-up queries are handled or on removing query (above)
}

View File

@ -308,6 +308,8 @@ public:
{
FinishingBattleHelper();
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
inline bool isDraw() const {return winnerSide == 2;}
const CGHeroInstance *winnerHero, *loserHero;
PlayerColor victor, loser;