1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-20 20:23:03 +02:00

Properly pass battleID in all battle netpack's

This commit is contained in:
Ivan Savenko 2023-08-31 18:45:52 +03:00
parent 747e28947a
commit 9fa7a93fb0
26 changed files with 136 additions and 54 deletions

View File

@ -320,6 +320,11 @@ battle::Units HypotheticBattle::getUnitsIf(battle::UnitFilter predicate) const
return ret;
}
BattleID HypotheticBattle::getBattleID() const
{
return subject->getBattle()->getBattleID();
}
int32_t HypotheticBattle::getActiveStackID() const
{
return activeUnitId;

View File

@ -207,6 +207,7 @@ void CBattleCallback::battleMakeSpellAction(const BattleID & battleID, const Bat
{
assert(action.actionType == EActionType::HERO_SPELL);
MakeAction mca(action);
mca.battleID = battleID;
sendRequest(&mca);
}
@ -376,6 +377,7 @@ void CBattleCallback::battleMakeUnitAction(const BattleID & battleID, const Batt
assert(!cl->gs->getBattle(battleID)->tacticDistance);
MakeAction ma;
ma.ba = action;
ma.battleID = battleID;
sendRequest(&ma);
}
@ -384,6 +386,7 @@ void CBattleCallback::battleMakeTacticAction(const BattleID & battleID, const Ba
assert(cl->gs->getBattle(battleID)->tacticDistance);
MakeAction ma;
ma.ba = action;
ma.battleID = battleID;
sendRequest(&ma);
}

View File

@ -615,7 +615,7 @@ void CClient::battleStarted(const BattleInfo * info)
if(att || def)
{
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def);
}
else if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
{
@ -623,7 +623,7 @@ void CClient::battleStarted(const BattleInfo * info)
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
spectratorInt->cb->onBattleStarted(info);
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt);
}
}

View File

@ -45,7 +45,7 @@
#include "../../lib/TerrainHandler.h"
#include "../../lib/CThreadHelper.h"
BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2,
BattleInterface::BattleInterface(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2,
const CGHeroInstance *hero1, const CGHeroInstance *hero2,
std::shared_ptr<CPlayerInterface> att,
std::shared_ptr<CPlayerInterface> defen,
@ -55,6 +55,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
, attackerInt(att)
, defenderInt(defen)
, curInt(att)
, battleID(battleID)
, battleOpeningDelayActive(true)
{
if(spectatorInt)

View File

@ -156,7 +156,7 @@ public:
BattleID getBattleID() const;
std::shared_ptr<CPlayerBattleCallback> getBattle() const;
BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr);
BattleInterface(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr);
~BattleInterface();
void trySetActivePlayer( PlayerColor player ); // if in hotseat, will activate interface of chosen player

View File

@ -1492,6 +1492,7 @@ struct DLL_LINKAGE BattleStart : public CPackForClient
{
h & battleID;
h & info;
assert(battleID != BattleID::NONE);
}
};
@ -1506,6 +1507,7 @@ struct DLL_LINKAGE BattleNextRound : public CPackForClient
template <typename Handler> void serialize(Handler & h, const int version)
{
h & battleID;
assert(battleID != BattleID::NONE);
}
};
@ -1524,6 +1526,7 @@ struct DLL_LINKAGE BattleSetActiveStack : public CPackForClient
h & battleID;
h & stack;
h & askPlayerInterface;
assert(battleID != BattleID::NONE);
}
};
@ -1557,6 +1560,7 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient
h & battleID;
h & heroResult;
h & winnerSide;
assert(battleID != BattleID::NONE);
}
};
@ -1583,6 +1587,7 @@ struct DLL_LINKAGE BattleResult : public Query
h & casualties[1];
h & exp;
h & artifacts;
assert(battleID != BattleID::NONE);
}
};
@ -1600,6 +1605,7 @@ struct DLL_LINKAGE BattleLogMessage : public CPackForClient
{
h & battleID;
h & lines;
assert(battleID != BattleID::NONE);
}
};
@ -1623,6 +1629,7 @@ struct DLL_LINKAGE BattleStackMoved : public CPackForClient
h & tilesToMove;
h & distance;
h & teleporting;
assert(battleID != BattleID::NONE);
}
};
@ -1640,6 +1647,7 @@ struct DLL_LINKAGE BattleUnitsChanged : public CPackForClient
{
h & battleID;
h & changedStacks;
assert(battleID != BattleID::NONE);
}
};
@ -1693,6 +1701,7 @@ struct BattleStackAttacked
h & killedAmount;
h & damageAmount;
h & spellID;
assert(battleID != BattleID::NONE);
}
bool operator<(const BattleStackAttacked & b) const
{
@ -1758,6 +1767,7 @@ struct DLL_LINKAGE BattleAttack : public CPackForClient
h & tile;
h & spellID;
h & attackerChanges;
assert(battleID != BattleID::NONE);
}
};
@ -1780,6 +1790,7 @@ struct DLL_LINKAGE StartAction : public CPackForClient
{
h & battleID;
h & ba;
assert(battleID != BattleID::NONE);
}
};
@ -1826,6 +1837,7 @@ struct DLL_LINKAGE BattleSpellCast : public CPackForClient
h & casterStack;
h & castByHero;
h & activeCast;
assert(battleID != BattleID::NONE);
}
};
@ -1847,6 +1859,7 @@ struct DLL_LINKAGE SetStackEffect : public CPackForClient
h & toAdd;
h & toUpdate;
h & toRemove;
assert(battleID != BattleID::NONE);
}
};
@ -1864,6 +1877,7 @@ struct DLL_LINKAGE StacksInjured : public CPackForClient
{
h & battleID;
h & stacks;
assert(battleID != BattleID::NONE);
}
};
@ -1878,6 +1892,7 @@ struct DLL_LINKAGE BattleResultsApplied : public CPackForClient
h & battleID;
h & player1;
h & player2;
assert(battleID != BattleID::NONE);
}
};
@ -1895,6 +1910,7 @@ struct DLL_LINKAGE BattleObstaclesChanged : public CPackForClient
{
h & battleID;
h & changes;
assert(battleID != BattleID::NONE);
}
};
@ -1931,6 +1947,7 @@ struct DLL_LINKAGE CatapultAttack : public CPackForClient
h & battleID;
h & attackedParts;
h & attacker;
assert(battleID != BattleID::NONE);
}
};
@ -1953,6 +1970,7 @@ struct DLL_LINKAGE BattleSetStackProperty : public CPackForClient
h & which;
h & val;
h & absolute;
assert(battleID != BattleID::NONE);
}
protected:
@ -1977,6 +1995,7 @@ struct DLL_LINKAGE BattleTriggerEffect : public CPackForClient
h & effect;
h & val;
h & additionalInfo;
assert(battleID != BattleID::NONE);
}
protected:
@ -1993,6 +2012,7 @@ struct DLL_LINKAGE BattleUpdateGateState : public CPackForClient
{
h & battleID;
h & state;
assert(battleID != BattleID::NONE);
}
protected:

View File

@ -180,10 +180,10 @@ public:
DLL_LINKAGE static const QueryID NONE;
};
class BattleID : public Identifier<QueryID>
class BattleID : public Identifier<BattleID>
{
public:
using Identifier<QueryID>::Identifier;
using Identifier<BattleID>::Identifier;
DLL_LINKAGE static const BattleID NONE;
};
class ObjectInstanceID : public Identifier<ObjectInstanceID>

View File

@ -252,6 +252,7 @@ void BattleSpellMechanics::cast(ServerCallback * server, const Target & target)
sc.side = casterSide;
sc.spellID = getSpellId();
sc.battleID = battle()->getBattle()->getBattleID();
sc.tile = target.at(0).hexValue;
sc.castByHero = mode == Mode::HERO;
@ -299,6 +300,7 @@ void BattleSpellMechanics::cast(ServerCallback * server, const Target & target)
beforeCast(sc, *server->getRNG(), target);
BattleLogMessage castDescription;
castDescription.battleID = battle()->getBattle()->getBattleID();
switch (mode)
{
@ -344,8 +346,9 @@ void BattleSpellMechanics::cast(ServerCallback * server, const Target & target)
// send empty event to client
// temporary(?) workaround to force animations to trigger
StacksInjured fake_event;
server->apply(&fake_event);
StacksInjured fakeEvent;
fakeEvent.battleID = battle()->getBattle()->getBattleID();
server->apply(&fakeEvent);
}
void BattleSpellMechanics::beforeCast(BattleSpellCast & sc, vstd::RNG & rng, const Target & target)
@ -448,6 +451,7 @@ std::set<const battle::Unit *> BattleSpellMechanics::collectTargets() const
void BattleSpellMechanics::doRemoveEffects(ServerCallback * server, const std::vector<const battle::Unit *> & targets, const CSelector & selector)
{
SetStackEffect sse;
sse.battleID = battle()->getBattle()->getBattleID();
for(const auto * unit : targets)
{

View File

@ -73,7 +73,7 @@ private:
std::set<const battle::Unit *> collectTargets() const;
static void doRemoveEffects(ServerCallback * server, const std::vector<const battle::Unit *> & targets, const CSelector & selector);
void doRemoveEffects(ServerCallback * server, const std::vector<const battle::Unit *> & targets, const CSelector & selector);
std::set<BattleHex> spellRangeInHexes(BattleHex centralHex) const;

View File

@ -188,6 +188,7 @@ int Catapult::getRandomDamage (ServerCallback * server) const
void Catapult::removeTowerShooters(ServerCallback * server, const Mechanics * m) const
{
BattleUnitsChanged removeUnits;
removeUnits.battleID = m->battle()->getBattle()->getBattleID();
for (auto const wallPart : { EWallPart::KEEP, EWallPart::BOTTOM_TOWER, EWallPart::UPPER_TOWER })
{

View File

@ -14,6 +14,7 @@
#include "../ISpellMechanics.h"
#include "../../NetPacks.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/IBattleState.h"
#include "../../battle/CUnitState.h"
#include "../../serializer/JsonSerializeFormat.h"
@ -60,6 +61,7 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
info.summoned = true;
BattleUnitsChanged pack;
pack.battleID = m->battle()->getBattle()->getBattleID();
pack.changedStacks.emplace_back(info.id, UnitChanges::EOperation::ADD);
info.save(pack.changedStacks.back().data);
server->apply(&pack);
@ -67,6 +69,7 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
//TODO: use BattleUnitsChanged with UPDATE operation
BattleUnitsChanged cloneFlags;
cloneFlags.battleID = m->battle()->getBattle()->getBattleID();
const auto *cloneUnit = m->battle()->battleGetUnitByID(unitId);
@ -89,6 +92,8 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
server->apply(&cloneFlags);
SetStackEffect sse;
sse.battleID = m->battle()->getBattle()->getBattleID();
Bonus lifeTimeMarker(BonusDuration::N_TURNS, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, SpellID::CLONE); //TODO: use special bonus type
lifeTimeMarker.turnsRemain = m->getEffectDuration();
std::vector<Bonus> buffer;

View File

@ -34,6 +34,9 @@ void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTar
{
StacksInjured stacksInjured;
BattleLogMessage blm;
stacksInjured.battleID = m->battle()->getBattle()->getBattleID();
blm.battleID = m->battle()->getBattle()->getBattleID();
size_t targetIndex = 0;
const battle::Unit * firstTarget = nullptr;
const bool describe = server->describeChanges();
@ -48,6 +51,7 @@ void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTar
if(unit && unit->alive())
{
BattleStackAttacked bsa;
bsa.battleID = m->battle()->getBattle()->getBattleID();
bsa.damageAmount = damageForTarget(targetIndex, m, unit);
bsa.stackAttacked = unit->unitId();
bsa.attackerID = -1;

View File

@ -14,6 +14,7 @@
#include "../ISpellMechanics.h"
#include "../../NetPacks.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/BattleInfo.h"
#include "../../battle/CUnitState.h"
#include "../../serializer/JsonSerializeFormat.h"
@ -27,6 +28,7 @@ namespace effects
void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{
BattleUnitsChanged pack;
pack.battleID = m->battle()->getBattle()->getBattleID();
for(const Destination & dest : target)
{

View File

@ -18,6 +18,7 @@
#include "../../NetPacks.h"
#include "../../battle/IBattleState.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/Unit.h"
#include "../../serializer/JsonSerializeFormat.h"
@ -33,6 +34,8 @@ void Dispel::apply(ServerCallback * server, const Mechanics * m, const EffectTar
const bool describe = server->describeChanges();
SetStackEffect sse;
BattleLogMessage blm;
blm.battleID = m->battle()->getBattle()->getBattleID();
sse.battleID = m->battle()->getBattle()->getBattleID();
for(const auto & t : target)
{

View File

@ -35,7 +35,11 @@ void Heal::apply(ServerCallback * server, const Mechanics * m, const EffectTarge
void Heal::apply(int64_t value, ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{
BattleLogMessage logMessage;
logMessage.battleID = m->battle()->getBattle()->getBattleID();
BattleUnitsChanged pack;
pack.battleID = m->battle()->getBattle()->getBattleID();
prepareHealEffect(value, pack, logMessage, *server->getRNG(), m, target);
if(!pack.changedStacks.empty())
server->apply(&pack);

View File

@ -123,6 +123,7 @@ void Sacrifice::apply(ServerCallback * server, const Mechanics * m, const Effect
Heal::apply(calculateHealEffectValue(m, victim), server, m, healTarget);
BattleUnitsChanged removeUnits;
removeUnits.battleID = m->battle()->getBattle()->getBattleID();
removeUnits.changedStacks.emplace_back(victim->unitId(), UnitChanges::EOperation::REMOVE);
server->apply(&removeUnits);
}

View File

@ -14,6 +14,7 @@
#include "../ISpellMechanics.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/BattleInfo.h"
#include "../../battle/Unit.h"
#include "../../NetPacks.h"
#include "../../serializer/JsonSerializeFormat.h"
@ -87,6 +88,7 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
auto valueWithBonus = m->applySpecificSpellBonus(m->calculateRawEffectValue(0, m->getEffectPower()));//TODO: consider use base power too
BattleUnitsChanged pack;
pack.battleID = m->battle()->getBattle()->getBattleID();
for(const auto & dest : target)
{

View File

@ -15,6 +15,7 @@
#include "../../NetPacks.h"
#include "../../battle/IBattleState.h"
#include "../../battle/CBattleInfoCallback.h"
#include "../../battle/Unit.h"
#include "../../serializer/JsonSerializeFormat.h"
@ -116,6 +117,8 @@ void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
SetStackEffect sse;
BattleLogMessage blm;
blm.battleID = m->battle()->getBattle()->getBattleID();
sse.battleID = m->battle()->getBattle()->getBattleID();
for(const auto & t : target)
{

View File

@ -160,6 +160,8 @@ bool BattleActionProcessor::doDefendAction(const CBattleInfoCallback & battle, c
//defensive stance, TODO: filter out spell boosts from bonus (stone skin etc.)
SetStackEffect sse;
sse.battleID = battle.getBattle()->getBattleID();
Bonus defenseBonusToAdd(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 20, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
@ -188,6 +190,7 @@ bool BattleActionProcessor::doDefendAction(const CBattleInfoCallback & battle, c
gameHandler->sendAndApply(&sse);
BattleLogMessage message;
message.battleID = battle.getBattle()->getBattleID();
MetaString text;
stack->addText(text, EMetaText::GENERAL_TXT, 120);
@ -541,6 +544,7 @@ bool BattleActionProcessor::makeBattleActionImpl(const CBattleInfoCallback & bat
if (!ba.isBattleEndAction())
{
StartAction startAction(ba);
startAction.battleID = battle.getBattle()->getBattleID();
gameHandler->sendAndApply(&startAction);
}
@ -549,6 +553,7 @@ bool BattleActionProcessor::makeBattleActionImpl(const CBattleInfoCallback & bat
if (!ba.isBattleEndAction())
{
EndAction endAction;
endAction.battleID = battle.getBattle()->getBattleID();
gameHandler->sendAndApply(&endAction);
}
@ -658,12 +663,14 @@ int BattleActionProcessor::moveStack(const CBattleInfoCallback & battle, int sta
occupyGateDrawbridgeHex(dest))
{
BattleUpdateGateState db;
db.battleID = battle.getBattle()->getBattleID();
db.state = EGateState::OPENED;
gameHandler->sendAndApply(&db);
}
//inform clients about move
BattleStackMoved sm;
sm.battleID = battle.getBattle()->getBattleID();
sm.stack = curStack->unitId();
std::vector<BattleHex> tiles;
tiles.push_back(path.first[0]);
@ -793,6 +800,7 @@ int BattleActionProcessor::moveStack(const CBattleInfoCallback & battle, int sta
{
//commit movement
BattleStackMoved sm;
sm.battleID = battle.getBattle()->getBattleID();
sm.stack = curStack->unitId();
sm.distance = path.second;
sm.teleporting = false;
@ -820,6 +828,7 @@ int BattleActionProcessor::moveStack(const CBattleInfoCallback & battle, int sta
if (curStack->alive())
{
BattleUpdateGateState db;
db.battleID = battle.getBattle()->getBattleID();
db.state = EGateState::OPENED;
gameHandler->sendAndApply(&db);
}
@ -857,6 +866,9 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
FireShieldInfo fireShield;
BattleAttack bat;
BattleLogMessage blm;
blm.battleID = battle.getBattle()->getBattleID();
bat.battleID = battle.getBattle()->getBattleID();
bat.attackerChanges.battleID = battle.getBattle()->getBattleID();
bat.stackAttacking = attacker->unitId();
bat.tile = targetHex;
@ -966,6 +978,9 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
if (drainedLife > 0)
bat.flags |= BattleAttack::LIFE_DRAIN;
for (BattleStackAttacked & bsa : bat.bsa)
bsa.battleID = battle.getBattle()->getBattleID();
gameHandler->sendAndApply(&bat);
{
@ -1032,6 +1047,7 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
{
BattleStackAttacked bsa;
bsa.battleID = battle.getBattle()->getBattleID();
bsa.flags |= BattleStackAttacked::FIRE_SHIELD;
bsa.stackAttacked = attacker->unitId(); //invert
bsa.attackerID = defender->unitId();
@ -1039,6 +1055,7 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
attacker->prepareAttacked(bsa, gameHandler->getRandomGenerator());
StacksInjured pack;
pack.battleID = battle.getBattle()->getBattleID();
pack.stacks.push_back(bsa);
gameHandler->sendAndApply(&pack);
@ -1240,10 +1257,12 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
return; //wrong subtype
BattleUnitsChanged addUnits;
addUnits.battleID = battle.getBattle()->getBattleID();
addUnits.changedStacks.emplace_back(resurrectInfo.id, UnitChanges::EOperation::ADD);
resurrectInfo.save(addUnits.changedStacks.back().data);
BattleUnitsChanged removeUnits;
removeUnits.battleID = battle.getBattle()->getBattleID();
removeUnits.changedStacks.emplace_back(defender->unitId(), UnitChanges::EOperation::REMOVE);
gameHandler->sendAndApply(&removeUnits);
gameHandler->sendAndApply(&addUnits);
@ -1280,10 +1299,11 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
defender->prepareAttacked(bsa, gameHandler->getRandomGenerator());
StacksInjured si;
si.battleID = battle.getBattle()->getBattleID();
si.stacks.push_back(bsa);
gameHandler->sendAndApply(&si);
sendGenericKilledLog(defender, bsa.killedAmount, false);
sendGenericKilledLog(battle, defender, bsa.killedAmount, false);
}
}
@ -1354,11 +1374,12 @@ int64_t BattleActionProcessor::applyBattleEffects(const CBattleInfoCallback & ba
return drainedLife;
}
void BattleActionProcessor::sendGenericKilledLog(const CStack * defender, int32_t killed, bool multiple)
void BattleActionProcessor::sendGenericKilledLog(const CBattleInfoCallback & battle, const CStack * defender, int32_t killed, bool multiple)
{
if(killed > 0)
{
BattleLogMessage blm;
blm.battleID = battle.getBattle()->getBattleID();
addGenericKilledLog(blm, defender, killed, multiple);
gameHandler->sendAndApply(&blm);
}

View File

@ -49,7 +49,7 @@ class BattleActionProcessor : boost::noncopyable
// damage, drain life & fire shield; returns amount of drained life
int64_t applyBattleEffects(const CBattleInfoCallback & battle, BattleAttack & bat, std::shared_ptr<battle::CUnitState> attackerState, FireShieldInfo & fireShield, const CStack * def, int distance, bool secondary);
void sendGenericKilledLog(const CStack * defender, int32_t killed, bool multiple);
void sendGenericKilledLog(const CBattleInfoCallback & battle, const CStack * defender, int32_t killed, bool multiple);
void addGenericKilledLog(BattleLogMessage & blm, const CStack * defender, int32_t killed, bool multiple);
bool canStackAct(const CBattleInfoCallback & battle, const CStack * stack);

View File

@ -171,6 +171,7 @@ void BattleFlowProcessor::trySummonGuardians(const CBattleInfoCallback & battle,
info.summoned = true;
BattleUnitsChanged pack;
pack.battleID = battle.getBattle()->getBattleID();
pack.changedStacks.emplace_back(info.id, UnitChanges::EOperation::ADD);
info.save(pack.changedStacks.back().data);
gameHandler->sendAndApply(&pack);
@ -227,6 +228,7 @@ void BattleFlowProcessor::onTacticsEnded(const CBattleInfoCallback & battle)
void BattleFlowProcessor::startNextRound(const CBattleInfoCallback & battle, bool isFirstRound)
{
BattleNextRound bnr;
bnr.battleID = battle.getBattle()->getBattleID();
logGlobal->debug("Next round starts");
gameHandler->sendAndApply(&bnr);
@ -265,6 +267,7 @@ const CStack * BattleFlowProcessor::getNextStack(const CBattleInfoCallback & bat
if(stack && stack->alive() && !stack->waiting)
{
BattleTriggerEffect bte;
bte.battleID = battle.getBattle()->getBattleID();
bte.stackID = stack->unitId();
bte.effect = vstd::to_underlying(BonusType::HP_REGENERATION);
@ -303,6 +306,7 @@ void BattleFlowProcessor::activateNextStack(const CBattleInfoCallback & battle)
}
BattleUnitsChanged removeGhosts;
removeGhosts.battleID = battle.getBattle()->getBattleID();
auto pendingGhosts = battle.battleGetStacksIf([](const CStack * stack){
return stack->ghostPending;
@ -487,6 +491,7 @@ bool BattleFlowProcessor::rollGoodMorale(const CBattleInfoCallback & battle, con
if(diceSize.size() > 0 && gameHandler->getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
{
BattleTriggerEffect bte;
bte.battleID = battle.getBattle()->getBattleID();
bte.stackID = next->unitId();
bte.effect = vstd::to_underlying(BonusType::MORALE);
bte.val = 1;
@ -558,6 +563,7 @@ void BattleFlowProcessor::makeStackDoNothing(const CBattleInfoCallback & battle,
bool BattleFlowProcessor::makeAutomaticAction(const CBattleInfoCallback & battle, const CStack *stack, BattleAction &ba)
{
BattleSetActiveStack bsa;
bsa.battleID = battle.getBattle()->getBattleID();
bsa.stack = stack->unitId();
bsa.askPlayerInterface = false;
gameHandler->sendAndApply(&bsa);
@ -601,6 +607,7 @@ void BattleFlowProcessor::stackEnchantedTrigger(const CBattleInfoCallback & batt
void BattleFlowProcessor::removeObstacle(const CBattleInfoCallback & battle, const CObstacleInstance & obstacle)
{
BattleObstaclesChanged obsRem;
obsRem.battleID = battle.getBattle()->getBattleID();
obsRem.changes.emplace_back(obstacle.uniqueID, ObstacleChanges::EOperation::REMOVE);
gameHandler->sendAndApply(&obsRem);
}
@ -608,6 +615,7 @@ void BattleFlowProcessor::removeObstacle(const CBattleInfoCallback & battle, con
void BattleFlowProcessor::stackTurnTrigger(const CBattleInfoCallback & battle, const CStack *st)
{
BattleTriggerEffect bte;
bte.battleID = battle.getBattle()->getBattleID();
bte.stackID = st->unitId();
bte.effect = -1;
bte.val = 0;
@ -640,6 +648,7 @@ void BattleFlowProcessor::stackTurnTrigger(const CBattleInfoCallback & battle, c
if (unbind)
{
BattleSetStackProperty ssp;
ssp.battleID = battle.getBattle()->getBattleID();
ssp.which = BattleSetStackProperty::UNBIND;
ssp.stackID = st->unitId();
gameHandler->sendAndApply(&ssp);
@ -721,6 +730,7 @@ void BattleFlowProcessor::stackTurnTrigger(const CBattleInfoCallback & battle, c
int cooldown = bonus->additionalInfo[0];
BattleSetStackProperty ssp;
ssp.battleID = battle.getBattle()->getBattleID();
ssp.which = BattleSetStackProperty::ENCHANTER_COUNTER;
ssp.absolute = false;
ssp.val = cooldown;
@ -737,6 +747,7 @@ void BattleFlowProcessor::setActiveStack(const CBattleInfoCallback & battle, con
assert(stack);
BattleSetActiveStack sas;
sas.battleID = battle.getBattle()->getBattleID();
sas.stack = stack->unitId();
gameHandler->sendAndApply(&sas);
}

View File

@ -89,7 +89,7 @@ void BattleProcessor::startBattlePrimary(const CArmedInstance *army1, const CArm
}
}
lastBattleQuery->bi = battle;
lastBattleQuery->battleID = battle->getBattleID();
lastBattleQuery->result = std::nullopt;
lastBattleQuery->belligerents[0] = battle->sides[0].armyObject;
lastBattleQuery->belligerents[1] = battle->sides[1].armyObject;
@ -261,13 +261,7 @@ void BattleProcessor::endBattleConfirm(const BattleID & battleID)
void BattleProcessor::battleAfterLevelUp(const BattleID & battleID, const BattleResult &result)
{
auto battle = gameHandler->gameState()->getBattle(battleID);
assert(battle);
if (!battle)
return;
resultProcessor->battleAfterLevelUp(*battle, result);
resultProcessor->battleAfterLevelUp(battleID, result);
}
void BattleProcessor::setGameHandler(CGameHandler * newGameHandler)

View File

@ -180,26 +180,21 @@ void CasualtiesAfterBattle::updateArmy(CGameHandler *gh)
}
}
FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int remainingBattleQueriesCount)
FinishingBattleHelper::FinishingBattleHelper(const CBattleInfoCallback & info, const BattleResult & result, int remainingBattleQueriesCount)
{
assert(Query->result);
assert(Query->bi);
auto &result = *Query->result;
auto &info = *Query->bi;
if (result.winner == BattleSide::ATTACKER)
{
winnerHero = info.getSideHero(BattleSide::ATTACKER);
loserHero = info.getSideHero(BattleSide::DEFENDER);
victor = info.getSidePlayer(BattleSide::ATTACKER);
loser = info.getSidePlayer(BattleSide::DEFENDER);
winnerHero = info.getBattle()->getSideHero(BattleSide::ATTACKER);
loserHero = info.getBattle()->getSideHero(BattleSide::DEFENDER);
victor = info.getBattle()->getSidePlayer(BattleSide::ATTACKER);
loser = info.getBattle()->getSidePlayer(BattleSide::DEFENDER);
}
else
{
winnerHero = info.getSideHero(BattleSide::DEFENDER);
loserHero = info.getSideHero(BattleSide::ATTACKER);
victor = info.getSidePlayer(BattleSide::DEFENDER);
loser = info.getSidePlayer(BattleSide::ATTACKER);
winnerHero = info.getBattle()->getSideHero(BattleSide::DEFENDER);
loserHero = info.getBattle()->getSideHero(BattleSide::ATTACKER);
victor = info.getBattle()->getSidePlayer(BattleSide::DEFENDER);
loser = info.getBattle()->getSidePlayer(BattleSide::ATTACKER);
}
winnerSide = result.winner;
@ -207,12 +202,12 @@ FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const CBattleQuery>
this->remainingBattleQueriesCount = remainingBattleQueriesCount;
}
FinishingBattleHelper::FinishingBattleHelper()
{
winnerHero = loserHero = nullptr;
winnerSide = 0;
remainingBattleQueriesCount = 0;
}
//FinishingBattleHelper::FinishingBattleHelper()
//{
// winnerHero = loserHero = nullptr;
// winnerSide = 0;
// remainingBattleQueriesCount = 0;
//}
void BattleResultProcessor::endBattle(const CBattleInfoCallback & battle)
{
@ -267,7 +262,7 @@ void BattleResultProcessor::endBattle(const CBattleInfoCallback & battle)
const int queriedPlayers = battleQuery ? (int)boost::count(gameHandler->queries->allQueries(), battleQuery) : 0;
assert(finishingBattles.count(battle.getBattle()->getBattleID()) == 0);
finishingBattles[battle.getBattle()->getBattleID()] = std::make_unique<FinishingBattleHelper>(battleQuery, queriedPlayers);
finishingBattles[battle.getBattle()->getBattleID()] = std::make_unique<FinishingBattleHelper>(battle, *battleResult, queriedPlayers);
// in battles against neutrals, 1st player can ask to replay battle manually
if (!battle.sideToPlayer(1).isValidPlayer())
@ -490,6 +485,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
gameHandler->changePrimSkill(finishingBattle->winnerHero, PrimarySkill::EXPERIENCE, battleResult->exp[finishingBattle->winnerSide]);
BattleResultAccepted raccepted;
raccepted.battleID = battle.getBattle()->getBattleID();
raccepted.heroResult[0].army = const_cast<CArmedInstance*>(battle.battleGetArmyObject(0));
raccepted.heroResult[1].army = const_cast<CArmedInstance*>(battle.battleGetArmyObject(1));
raccepted.heroResult[0].hero = const_cast<CGHeroInstance*>(battle.battleGetFightingHero(0));
@ -503,15 +499,15 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
//--> continuation (battleAfterLevelUp) occurs after level-up gameHandler->queries are handled or on removing query
}
void BattleResultProcessor::battleAfterLevelUp(const CBattleInfoCallback & battle, const BattleResult & result)
void BattleResultProcessor::battleAfterLevelUp(const BattleID & battleID, const BattleResult & result)
{
LOG_TRACE(logGlobal);
assert(finishingBattles.count(battle.getBattle()->getBattleID()) != 0);
if(finishingBattles.count(battle.getBattle()->getBattleID()) == 0)
assert(finishingBattles.count(battleID) != 0);
if(finishingBattles.count(battleID) == 0)
return;
auto & finishingBattle = finishingBattles[battle.getBattle()->getBattleID()];
auto & finishingBattle = finishingBattles[battleID];
finishingBattle->remainingBattleQueriesCount--;
logGlobal->trace("Decremented gameHandler->queries count to %d", finishingBattle->remainingBattleQueriesCount);
@ -537,6 +533,7 @@ void BattleResultProcessor::battleAfterLevelUp(const CBattleInfoCallback & battl
}
BattleResultsApplied resultsApplied;
resultsApplied.battleID = battleID;
resultsApplied.player1 = finishingBattle->victor;
resultsApplied.player2 = finishingBattle->loser;
gameHandler->sendAndApply(&resultsApplied);
@ -561,8 +558,8 @@ void BattleResultProcessor::battleAfterLevelUp(const CBattleInfoCallback & battl
gameHandler->heroPool->onHeroEscaped(finishingBattle->victor, finishingBattle->winnerHero);
}
finishingBattles.erase(battle.getBattle()->getBattleID());
battleResults.erase(battle.getBattle()->getBattleID());
finishingBattles.erase(battleID);
battleResults.erase(battleID);
}
void BattleResultProcessor::setBattleResult(const CBattleInfoCallback & battle, EBattleResult resultType, int victoriusSide)
@ -572,6 +569,7 @@ void BattleResultProcessor::setBattleResult(const CBattleInfoCallback & battle,
battleResults[battle.getBattle()->getBattleID()] = std::make_unique<BattleResult>();
auto & battleResult = battleResults[battle.getBattle()->getBattleID()];
battleResult->battleID = battle.getBattle()->getBattleID();
battleResult->result = resultType;
battleResult->winner = victoriusSide; //surrendering side loses

View File

@ -37,8 +37,8 @@ struct CasualtiesAfterBattle
struct FinishingBattleHelper
{
FinishingBattleHelper();
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
// FinishingBattleHelper();
FinishingBattleHelper(const CBattleInfoCallback & battle, const BattleResult & result, int RemainingBattleQueriesCount);
inline bool isDraw() const {return winnerSide == 2;}
@ -76,5 +76,5 @@ public:
void setBattleResult(const CBattleInfoCallback & battle, EBattleResult resultType, int victoriusSide);
void endBattle(const CBattleInfoCallback & battle); //ends battle
void endBattleConfirm(const CBattleInfoCallback & battle);
void battleAfterLevelUp(const CBattleInfoCallback & battle, const BattleResult & result);
void battleAfterLevelUp(const BattleID & battleID, const BattleResult & result);
};

View File

@ -24,7 +24,7 @@ void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisi
CBattleQuery::CBattleQuery(CGameHandler * owner, const IBattleInfo * bi):
CGhQuery(owner),
bi(bi)
battleID(bi->getBattleID())
{
belligerents[0] = bi->getSideArmy(0);
belligerents[1] = bi->getSideArmy(1);
@ -34,7 +34,7 @@ CBattleQuery::CBattleQuery(CGameHandler * owner, const IBattleInfo * bi):
}
CBattleQuery::CBattleQuery(CGameHandler * owner):
CGhQuery(owner), bi(nullptr)
CGhQuery(owner)
{
belligerents[0] = belligerents[1] = nullptr;
}
@ -48,7 +48,7 @@ bool CBattleQuery::blocksPack(const CPack * pack) const
void CBattleQuery::onRemoval(PlayerColor color)
{
if(result)
gh->battles->battleAfterLevelUp(bi->getBattleID(), *result);
gh->battles->battleAfterLevelUp(battleID, *result);
}
CBattleDialogQuery::CBattleDialogQuery(CGameHandler * owner, const IBattleInfo * bi):

View File

@ -23,7 +23,7 @@ public:
std::array<const CArmedInstance *,2> belligerents;
std::array<int, 2> initialHeroMana;
const IBattleInfo *bi;
BattleID battleID;
std::optional<BattleResult> result;
CBattleQuery(CGameHandler * owner);