mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-15 00:05:02 +02:00
Refactored player-specific data into single struct BattleState.
This commit is contained in:
@ -428,8 +428,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
if (hero2)
|
||||
battleResult.data->exp[1] = hero2->calculateXp(battleResult.data->exp[1]);
|
||||
|
||||
const CArmedInstance *bEndArmy1 = gs->curB->belligerents[0];
|
||||
const CArmedInstance *bEndArmy2 = gs->curB->belligerents[1];
|
||||
const CArmedInstance *bEndArmy1 = gs->curB->sides[0].armyObject;
|
||||
const CArmedInstance *bEndArmy2 = gs->curB->sides[1].armyObject;
|
||||
const BattleResult::EResult result = battleResult.get()->result;
|
||||
|
||||
auto findBattleQuery = [this] () -> shared_ptr<CBattleQuery>
|
||||
@ -452,8 +452,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
battleQuery = make_shared<CBattleQuery>(gs->curB);
|
||||
}
|
||||
}
|
||||
if(battleQuery != queries.topQuery(gs->curB->sides[0]))
|
||||
complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0]) + " although in battle has no battle query at the top!");
|
||||
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 = *battleResult.data;
|
||||
|
||||
@ -480,7 +480,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
{
|
||||
int maxLevel = eagleEyeLevel + 1;
|
||||
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
||||
for(const CSpell *sp : gs->curB->usedSpellsHistory[!battleResult.data->winner])
|
||||
for(const CSpell *sp : gs->curB->sides[!battleResult.data->winner].usedSpellsHistory)
|
||||
if(sp->level <= maxLevel && !vstd::contains(finishingBattle->winnerHero->spells, sp->id) && rand() % 100 < eagleEyeChance)
|
||||
cs.spells.insert(sp->id);
|
||||
}
|
||||
@ -534,7 +534,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto armySlot : gs->curB->belligerents[!battleResult.data->winner]->stacks)
|
||||
for (auto armySlot : gs->curB->battleGetArmyObject(!battleResult.data->winner)->stacks)
|
||||
{
|
||||
auto artifactsWorn = armySlot.second->artifactsWorn;
|
||||
for (auto artSlot : artifactsWorn)
|
||||
@ -647,7 +647,7 @@ void CGameHandler::battleAfterLevelUp( const BattleResult &result )
|
||||
logGlobal->traceStream() << "Decremented queries count to " << finishingBattle->remainingBattleQueriesCount;
|
||||
|
||||
if(finishingBattle->remainingBattleQueriesCount > 0)
|
||||
//Battle results will be hndled when all battle queries are closed
|
||||
//Battle results will be handled when all battle queries are closed
|
||||
return;
|
||||
|
||||
//TODO consider if we really want it to work like above. ATM each player as unblocked as soon as possible
|
||||
@ -657,7 +657,7 @@ void CGameHandler::battleAfterLevelUp( const BattleResult &result )
|
||||
// Necromancy if applicable.
|
||||
const CStackBasicDescriptor raisedStack = finishingBattle->winnerHero ? finishingBattle->winnerHero->calculateNecromancy(*battleResult.data) : CStackBasicDescriptor();
|
||||
// Give raised units to winner and show dialog, if any were raised,
|
||||
// units will be given after casualities are taken
|
||||
// units will be given after casualties are taken
|
||||
const SlotID necroSlot = raisedStack.type ? finishingBattle->winnerHero->getSlotFor(raisedStack.type) : SlotID();
|
||||
|
||||
if (necroSlot != SlotID())
|
||||
@ -706,12 +706,11 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
||||
{
|
||||
bat.bsa.clear();
|
||||
bat.stackAttacking = att->ID;
|
||||
int attackerLuck = att->LuckVal();
|
||||
const CGHeroInstance * h0 = gs->curB->heroes[0],
|
||||
* h1 = gs->curB->heroes[1];
|
||||
const int attackerLuck = att->LuckVal();
|
||||
|
||||
auto sideHeroBlocksLuck = [](const SideInBattle &side){ return NBonus::hasOfType(side.hero, Bonus::BLOCK_LUCK); };
|
||||
|
||||
if(!(h0 && NBonus::hasOfType(h0, Bonus::BLOCK_LUCK)) &&
|
||||
!(h1 && NBonus::hasOfType(h1, Bonus::BLOCK_LUCK)))
|
||||
if(!vstd::contains_if(gs->curB->sides, sideHeroBlocksLuck))
|
||||
{
|
||||
if(attackerLuck > 0 && rand()%24 < attackerLuck)
|
||||
{
|
||||
@ -3339,7 +3338,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
}
|
||||
case Battle::RETREAT: //retreat/flee
|
||||
{
|
||||
if(!gs->curB->battleCanFlee(gs->curB->sides[ba.side]))
|
||||
if(!gs->curB->battleCanFlee(gs->curB->sides[ba.side].color))
|
||||
complain("Cannot retreat!");
|
||||
else
|
||||
setBattleResult(BattleResult::ESCAPE, !ba.side); //surrendering side loses
|
||||
@ -3347,7 +3346,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
}
|
||||
case Battle::SURRENDER:
|
||||
{
|
||||
PlayerColor player = gs->curB->sides[ba.side];
|
||||
PlayerColor player = gs->curB->sides[ba.side].color;
|
||||
int cost = gs->curB->battleGetSurrenderCost(player);
|
||||
if(cost < 0)
|
||||
complain("Cannot surrender!");
|
||||
@ -3477,7 +3476,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
|
||||
//second shot for ballista, only if hero has advanced artillery
|
||||
|
||||
const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side];
|
||||
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
|
||||
if( destStack->alive()
|
||||
&& (stack->getCreature()->idNumber == CreatureID::BALLISTA)
|
||||
@ -3516,7 +3515,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
{
|
||||
StartAction start_action(ba);
|
||||
sendAndApply(&start_action);
|
||||
const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side];
|
||||
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(SecondarySkill::BALLISTICS)];
|
||||
|
||||
EWallParts::EWallParts attackedPart = gs->curB->battleHexToWallPart(ba.destinationTile);
|
||||
@ -3620,7 +3619,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
{
|
||||
StartAction start_action(ba);
|
||||
sendAndApply(&start_action);
|
||||
const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side];
|
||||
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
const CStack *healer = gs->curB->battleGetStackByID(ba.stackNumber),
|
||||
*destStack = gs->curB->battleGetStackByPos(ba.destinationTile);
|
||||
|
||||
@ -4385,7 +4384,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
|
||||
std::vector<CStack *> & battleStacks = gs->curB->stacks;
|
||||
for (auto & battleStack : battleStacks)
|
||||
{
|
||||
if(battleStack->owner == gs->curB->sides[casterSide]) //get enemy stacks which can be affected by this spell
|
||||
if(battleStack->owner == gs->curB->sides[casterSide].color) //get enemy stacks which can be affected by this spell
|
||||
{
|
||||
if (!gs->curB->battleIsImmune(nullptr, spell, ECastingMode::MAGIC_MIRROR, battleStack->position))
|
||||
mirrorTargets.push_back(battleStack);
|
||||
@ -4410,8 +4409,8 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
COMPLAIN_RET_FALSE_IF(ba.side > 1, "Side must be 0 or 1!");
|
||||
|
||||
|
||||
const CGHeroInstance *h = gs->curB->heroes[ba.side];
|
||||
const CGHeroInstance *secondHero = gs->curB->heroes[!ba.side];
|
||||
const CGHeroInstance *h = gs->curB->battleGetFightingHero(ba.side);
|
||||
const CGHeroInstance *secondHero = gs->curB->battleGetFightingHero(!ba.side);
|
||||
if(!h)
|
||||
{
|
||||
logGlobal->warnStream() << "Wrong caster!";
|
||||
@ -4534,10 +4533,11 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
if (st->hasBonusOfType(Bonus::MANA_DRAIN) && !vstd::contains(st->state, EBattleStackState::DRAINED_MANA))
|
||||
{
|
||||
const CGHeroInstance * enemy = gs->curB->getHero(gs->curB->theOtherPlayer(st->owner));
|
||||
const CGHeroInstance * owner = gs->curB->getHero(st->owner);
|
||||
if (enemy)
|
||||
{
|
||||
ui32 manaDrained = st->valOfBonuses(Bonus::MANA_DRAIN);
|
||||
vstd::amin (manaDrained, gs->curB->heroes[0]->mana);
|
||||
vstd::amin(manaDrained, gs->curB->battleGetFightingHero(0)->mana);
|
||||
if (manaDrained)
|
||||
{
|
||||
bte.effect = Bonus::MANA_DRAIN;
|
||||
@ -4569,7 +4569,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
}
|
||||
BonusList bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTER)));
|
||||
int side = gs->curB->whatSide(st->owner);
|
||||
if (bl.size() && st->casts && !gs->curB->enchanterCounter[side])
|
||||
if (bl.size() && st->casts && !gs->curB->sides[side].enchanterCounter)
|
||||
{
|
||||
int index = rand() % bl.size();
|
||||
SpellID spellID = SpellID(bl[index]->subtype);
|
||||
@ -4624,7 +4624,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
|
||||
//helper info
|
||||
const SpellCreatedObstacle *spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(&obstacle); //not nice but we may need spell params
|
||||
const ui8 side = curStack->attackerOwned; //if enemy is defending (false = 0), side of our hero is also 0 (attacker)
|
||||
const CGHeroInstance *hero = gs->curB->heroes[side];
|
||||
const CGHeroInstance *hero = gs->curB->battleGetFightingHero(side);
|
||||
|
||||
if(obstacle.obstacleType == CObstacleInstance::MOAT)
|
||||
{
|
||||
@ -5819,14 +5819,15 @@ void CGameHandler::runBattle()
|
||||
}
|
||||
|
||||
//spells opening battle
|
||||
for(int i=0; i<ARRAY_COUNT(gs->curB->heroes); ++i)
|
||||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
if(gs->curB->heroes[i] && gs->curB->heroes[i]->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||
auto h = gs->curB->battleGetFightingHero(i);
|
||||
if(h && h->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||
{
|
||||
TBonusListPtr bl = gs->curB->heroes[i]->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
for (Bonus *b : *bl)
|
||||
{
|
||||
handleSpellCasting(SpellID(b->subtype), 3, -1, 0, gs->curB->heroes[i]->tempOwner, nullptr, gs->curB->heroes[1-i], b->val, ECastingMode::HERO_CASTING, nullptr);
|
||||
handleSpellCasting(SpellID(b->subtype), 3, -1, 0, h->tempOwner, nullptr, gs->curB->battleGetFightingHero(1-i), b->val, ECastingMode::HERO_CASTING, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5853,7 +5854,8 @@ void CGameHandler::runBattle()
|
||||
//check for bad morale => freeze
|
||||
int nextStackMorale = next->MoraleVal();
|
||||
if( nextStackMorale < 0 &&
|
||||
!(NBonus::hasOfType(gs->curB->heroes[0], Bonus::BLOCK_MORALE) || NBonus::hasOfType(gs->curB->heroes[1], Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses)
|
||||
!(NBonus::hasOfType(gs->curB->battleGetFightingHero(0), Bonus::BLOCK_MORALE)
|
||||
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses)
|
||||
)
|
||||
{
|
||||
if( rand()%24 < -2 * nextStackMorale)
|
||||
@ -6005,7 +6007,8 @@ void CGameHandler::runBattle()
|
||||
&& !vstd::contains(next->state, EBattleStackState::FEAR)
|
||||
&& next->alive()
|
||||
&& nextStackMorale > 0
|
||||
&& !(NBonus::hasOfType(gs->curB->heroes[0], Bonus::BLOCK_MORALE) || NBonus::hasOfType(gs->curB->heroes[1], Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses
|
||||
&& !(NBonus::hasOfType(gs->curB->battleGetFightingHero(0), Bonus::BLOCK_MORALE)
|
||||
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses
|
||||
)
|
||||
{
|
||||
if(rand()%24 < nextStackMorale) //this stack hasn't got morale this turn
|
||||
@ -6033,7 +6036,7 @@ void CGameHandler::runBattle()
|
||||
}
|
||||
}
|
||||
|
||||
endBattle(gs->curB->tile, gs->curB->heroes[0], gs->curB->heroes[1]);
|
||||
endBattle(gs->curB->tile, gs->curB->battleGetFightingHero(0), gs->curB->battleGetFightingHero(1));
|
||||
}
|
||||
|
||||
bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
|
||||
@ -6210,7 +6213,7 @@ bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, con
|
||||
void CGameHandler::duelFinished()
|
||||
{
|
||||
auto si = getStartInfo();
|
||||
auto getName = [&](int i){ return si->getIthPlayersSettings(gs->curB->sides[i]).name; };
|
||||
auto getName = [&](int i){ return si->getIthPlayersSettings(gs->curB->sides[i].color).name; };
|
||||
|
||||
int casualtiesPoints = 0;
|
||||
logGlobal->debugStream() << boost::format("Winner side %d\nWinner casualties:")
|
||||
@ -6310,10 +6313,10 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper(shared_ptr<const CBat
|
||||
auto &result = *Query->result;
|
||||
auto &info = *Query->bi;
|
||||
|
||||
winnerHero = result.winner != 0 ? info.heroes[1] : info.heroes[0];
|
||||
loserHero = result.winner != 0 ? info.heroes[0] : info.heroes[1];
|
||||
victor = info.sides[result.winner];
|
||||
loser = info.sides[!result.winner];
|
||||
winnerHero = result.winner != 0 ? info.sides[1].hero : info.sides[0].hero;
|
||||
loserHero = result.winner != 0 ? info.sides[0].hero : info.sides[1].hero;
|
||||
victor = info.sides[result.winner].color;
|
||||
loser = info.sides[!result.winner].color;
|
||||
duel = Duel;
|
||||
remainingBattleQueriesCount = RemainingBattleQueriesCount;
|
||||
}
|
||||
|
Reference in New Issue
Block a user