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:
parent
9b597fc8d4
commit
b253b19dc3
@ -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)
|
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);
|
bool replay = (lastBattleArmies.first == army1 && lastBattleArmies.second == army2); //will be true if player already refused auto-battle result
|
||||||
lastBattleArmies.first = army1;
|
lastBattleArmies.first = army1;
|
||||||
lastBattleArmies.second = army2;
|
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(!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 = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
|
||||||
autofightingAI->init(env, cb);
|
autofightingAI->init(env, cb);
|
||||||
@ -938,7 +941,8 @@ void CPlayerInterface::battleEnd(const BattleResult *br, QueryID queryID)
|
|||||||
|
|
||||||
if(!battleInt)
|
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)
|
wnd->resultCallback = [=](ui32 selection)
|
||||||
{
|
{
|
||||||
cb->selectionMade(selection, queryID);
|
cb->selectionMade(selection, queryID);
|
||||||
|
@ -600,7 +600,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human)
|
if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human)
|
||||||
def = std::dynamic_pointer_cast<CPlayerInterface>(playerint[rightSide.color]);
|
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)
|
if(att && att->isAutoFightOn)
|
||||||
{
|
{
|
||||||
att.reset();
|
att.reset();
|
||||||
|
@ -570,9 +570,9 @@ void CBattleResultWindow::show(SDL_Surface * to)
|
|||||||
CCS->videoh->update(pos.x + 107, pos.y + 70, screen, true, false);
|
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
|
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||||
|
|
||||||
close();
|
close();
|
||||||
@ -586,20 +586,14 @@ void CBattleResultWindow::bExitf()
|
|||||||
CCS->videoh->close();
|
CCS->videoh->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleResultWindow::bExitf()
|
||||||
|
{
|
||||||
|
buttonPressed(0);
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleResultWindow::bRepeatf()
|
void CBattleResultWindow::bRepeatf()
|
||||||
{
|
{
|
||||||
resultCallback(1);
|
buttonPressed(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)
|
Point CClickableHex::getXYUnitAnim(BattleHex hexNum, const CStack * stack, CBattleInterface * cbi)
|
||||||
|
@ -122,6 +122,8 @@ private:
|
|||||||
std::vector<std::shared_ptr<CAnimImage>> icons;
|
std::vector<std::shared_ptr<CAnimImage>> icons;
|
||||||
std::shared_ptr<CTextBox> description;
|
std::shared_ptr<CTextBox> description;
|
||||||
CPlayerInterface & owner;
|
CPlayerInterface & owner;
|
||||||
|
|
||||||
|
void buttonPressed(int button); //internal function for button callbacks
|
||||||
public:
|
public:
|
||||||
CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay = false);
|
CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay = false);
|
||||||
~CBattleResultWindow();
|
~CBattleResultWindow();
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"type" : "object",
|
"type" : "object",
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"default": {},
|
"default": {},
|
||||||
"required" : [ "heroSpeed", "enemySpeed", "scrollSpeed", "heroReminder", "quickCombat" ],
|
"required" : [ "heroSpeed", "enemySpeed", "scrollSpeed", "heroReminder", "quickCombat", "alwaysSkipCombat" ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"heroSpeed" : {
|
"heroSpeed" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
@ -144,7 +144,13 @@
|
|||||||
},
|
},
|
||||||
"quickCombat" : {
|
"quickCombat" : {
|
||||||
"type" : "boolean",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -741,9 +741,9 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
|
|||||||
CasualtiesAfterBattle cab1(bEndArmy1, battleInfo), cab2(bEndArmy2, battleInfo); //calculate casualties before deleting battle
|
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->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);
|
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
||||||
for(auto & spellId : battleInfo->sides.at(!battleResult.data->winner).usedSpellsHistory)
|
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
|
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)
|
auto sendMoveArtifact = [&](const CArtifactInstance *art, MoveArtifact *ma)
|
||||||
{
|
{
|
||||||
@ -890,6 +890,11 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
|
|||||||
RemoveObject ro(finishingBattle->loserHero->id);
|
RemoveObject ro(finishingBattle->loserHero->id);
|
||||||
sendAndApply(&ro);
|
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
|
if(battleResult.data->winner == BattleSide::DEFENDER
|
||||||
&& finishingBattle->winnerHero
|
&& 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
|
swapGarrisonOnSiege(finishingBattle->winnerHero->visitedTown->id); //return defending visitor from garrison to its rightful place
|
||||||
}
|
}
|
||||||
//give exp
|
//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]);
|
changePrimSkill(finishingBattle->winnerHero, PrimarySkill::EXPERIENCE, battleResult.data->exp[finishingBattle->winnerSide]);
|
||||||
|
|
||||||
queries.popIfTop(battleQuery);
|
//queries.popIfTop(battleQuery);
|
||||||
|
|
||||||
BattleResultAccepted raccepted;
|
BattleResultAccepted raccepted;
|
||||||
raccepted.army1 = const_cast<CArmedInstance*>(bEndArmy1);
|
raccepted.army1 = const_cast<CArmedInstance*>(bEndArmy1);
|
||||||
@ -914,6 +919,7 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
|
|||||||
raccepted.exp[1] = battleResult.data->exp[1];
|
raccepted.exp[1] = battleResult.data->exp[1];
|
||||||
sendAndApply(&raccepted);
|
sendAndApply(&raccepted);
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,6 +309,8 @@ public:
|
|||||||
FinishingBattleHelper();
|
FinishingBattleHelper();
|
||||||
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
|
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
|
||||||
|
|
||||||
|
inline bool isDraw() const {return winnerSide == 2;}
|
||||||
|
|
||||||
const CGHeroInstance *winnerHero, *loserHero;
|
const CGHeroInstance *winnerHero, *loserHero;
|
||||||
PlayerColor victor, loser;
|
PlayerColor victor, loser;
|
||||||
ui8 winnerSide;
|
ui8 winnerSide;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user