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

Fixed ending of battles due to retreat/surrender

This commit is contained in:
Ivan Savenko
2023-08-22 20:57:58 +03:00
parent a852236602
commit 81242d3500
7 changed files with 35 additions and 25 deletions

View File

@@ -601,28 +601,13 @@ void BattleInterface::startAction(const BattleAction & action)
return; return;
} }
const CStack *stack = curInt->cb->battleGetStackByID(action.stackNumber);
if (stack)
{
windowObject->updateQueue();
}
else
{
assert(action.actionType == EActionType::HERO_SPELL); //only cast spell is valid action without acting stack number
}
stacksController->startAction(action); stacksController->startAction(action);
if(action.actionType == EActionType::HERO_SPELL) //when hero casts spell if (!action.isUnitAction())
return; return;
if (!stack) assert(curInt->cb->battleGetStackByID(action.stackNumber));
{ windowObject->updateQueue();
logGlobal->error("Something wrong with stackNumber in actionStarted. Stack number: %d", action.stackNumber);
return;
}
effectsController->startAction(action); effectsController->startAction(action);
} }

View File

@@ -205,7 +205,6 @@ bool BattleAction::isUnitAction() const
EActionType::BAD_MORALE, EActionType::BAD_MORALE,
EActionType::STACK_HEAL EActionType::STACK_HEAL
}; };
return vstd::contains(actions, actionType); return vstd::contains(actions, actionType);
} }
@@ -215,7 +214,15 @@ bool BattleAction::isSpellAction() const
EActionType::HERO_SPELL, EActionType::HERO_SPELL,
EActionType::MONSTER_SPELL EActionType::MONSTER_SPELL
}; };
return vstd::contains(actions, actionType);
}
bool BattleAction::isBattleEndAction() const
{
static const std::array<EActionType, 2> actions = {
EActionType::RETREAT,
EActionType::SURRENDER
};
return vstd::contains(actions, actionType); return vstd::contains(actions, actionType);
} }
@@ -227,7 +234,6 @@ bool BattleAction::isTacticsAction() const
EActionType::RETREAT, EActionType::RETREAT,
EActionType::SURRENDER EActionType::SURRENDER
}; };
return vstd::contains(actions, actionType); return vstd::contains(actions, actionType);
} }

View File

@@ -46,6 +46,7 @@ public:
bool isTacticsAction() const; bool isTacticsAction() const;
bool isUnitAction() const; bool isUnitAction() const;
bool isSpellAction() const; bool isSpellAction() const;
bool isBattleEndAction() const;
std::string toString() const; std::string toString() const;
void aimToHex(const BattleHex & destination); void aimToHex(const BattleHex & destination);

View File

@@ -535,13 +535,20 @@ bool BattleActionProcessor::makeBattleActionImpl(const BattleAction &ba)
logGlobal->trace("Making action: %s", ba.toString()); logGlobal->trace("Making action: %s", ba.toString());
const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber); const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber);
// for these events client does not expects StartAction/EndAction wrapper
if (!ba.isBattleEndAction())
{
StartAction startAction(ba); StartAction startAction(ba);
gameHandler->sendAndApply(&startAction); gameHandler->sendAndApply(&startAction);
}
bool result = dispatchBattleAction(ba); bool result = dispatchBattleAction(ba);
if (!ba.isBattleEndAction())
{
EndAction endAction; EndAction endAction;
gameHandler->sendAndApply(&endAction); gameHandler->sendAndApply(&endAction);
}
if(ba.actionType == EActionType::WAIT || ba.actionType == EActionType::DEFEND || ba.actionType == EActionType::SHOOT || ba.actionType == EActionType::MONSTER_SPELL) if(ba.actionType == EActionType::WAIT || ba.actionType == EActionType::DEFEND || ba.actionType == EActionType::SHOOT || ba.actionType == EActionType::MONSTER_SPELL)
gameHandler->handleObstacleTriggersForUnit(*gameHandler->spellEnv, *stack); gameHandler->handleObstacleTriggersForUnit(*gameHandler->spellEnv, *stack);

View File

@@ -147,6 +147,9 @@ bool BattleProcessor::checkBattleStateChanges()
if (gameHandler->battleGetSiegeLevel() > 0) if (gameHandler->battleGetSiegeLevel() > 0)
updateGateState(); updateGateState();
if (resultProcessor->battleIsEnding())
return true;
//check if battle ended //check if battle ended
if (auto result = gameHandler->battleIsFinished()) if (auto result = gameHandler->battleIsFinished())
{ {

View File

@@ -528,6 +528,7 @@ void BattleResultProcessor::battleAfterLevelUp(const BattleResult &result)
} }
finishingBattle.reset(); finishingBattle.reset();
battleResult.reset();
} }
void BattleResultProcessor::setBattleResult(EBattleResult resultType, int victoriusSide) void BattleResultProcessor::setBattleResult(EBattleResult resultType, int victoriusSide)
@@ -537,3 +538,8 @@ void BattleResultProcessor::setBattleResult(EBattleResult resultType, int victor
battleResult->winner = victoriusSide; //surrendering side loses battleResult->winner = victoriusSide; //surrendering side loses
gameHandler->gameState()->curB->calculateCasualties(battleResult->casualties); gameHandler->gameState()->curB->calculateCasualties(battleResult->casualties);
} }
bool BattleResultProcessor::battleIsEnding() const
{
return battleResult != nullptr;
}

View File

@@ -71,6 +71,8 @@ public:
explicit BattleResultProcessor(BattleProcessor * owner); explicit BattleResultProcessor(BattleProcessor * owner);
void setGameHandler(CGameHandler * newGameHandler); void setGameHandler(CGameHandler * newGameHandler);
bool battleIsEnding() const;
void setBattleResult(EBattleResult resultType, int victoriusSide); void setBattleResult(EBattleResult resultType, int victoriusSide);
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 endBattleConfirm(const BattleInfo * battleInfo);