mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Battle Info uses ObjectInstanceID's instead of pointers
This commit is contained in:
@@ -388,7 +388,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
auto callBattleStart = [&](PlayerColor color, BattleSide side)
|
||||
{
|
||||
if(vstd::contains(battleints, color))
|
||||
battleints[color]->battleStart(info->battleID, leftSide.armyObject, rightSide.armyObject, info->tile, leftSide.hero, rightSide.hero, side, info->replayAllowed);
|
||||
battleints[color]->battleStart(info->battleID, leftSide.getArmy(), rightSide.getArmy(), info->tile, leftSide.getHero(), rightSide.getHero(), side, info->replayAllowed);
|
||||
};
|
||||
|
||||
callBattleStart(leftSide.color, BattleSide::LEFT_SIDE);
|
||||
@@ -433,14 +433,14 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
{
|
||||
if(att || def)
|
||||
{
|
||||
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def);
|
||||
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.getArmy(), rightSide.getArmy(), leftSide.getHero(), rightSide.getHero(), att, def);
|
||||
}
|
||||
else if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
||||
{
|
||||
//TODO: This certainly need improvement
|
||||
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
|
||||
spectratorInt->cb->onBattleStarted(info);
|
||||
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt);
|
||||
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(info->getBattleID(), leftSide.getArmy(), rightSide.getArmy(), leftSide.getHero(), rightSide.getHero(), att, def, spectratorInt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -745,11 +745,11 @@ void ApplyFirstClientNetPackVisitor::visitBattleStart(BattleStart & pack)
|
||||
{
|
||||
// Cannot use the usual code because curB is not set yet
|
||||
callOnlyThatBattleInterface(cl, pack.info->getSide(BattleSide::ATTACKER).color, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->getSideArmy(BattleSide::ATTACKER), pack.info->getSideArmy(BattleSide::DEFENDER),
|
||||
pack.info->tile, pack.info->getSide(BattleSide::ATTACKER).hero, pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
pack.info->tile, pack.info->getSideHero(BattleSide::ATTACKER), pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
callOnlyThatBattleInterface(cl, pack.info->getSide(BattleSide::DEFENDER).color, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->getSideArmy(BattleSide::ATTACKER), pack.info->getSideArmy(BattleSide::DEFENDER),
|
||||
pack.info->tile, pack.info->getSide(BattleSide::ATTACKER).hero, pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
pack.info->tile, pack.info->getSideHero(BattleSide::ATTACKER), pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, &IBattleEventsReceiver::battleStartBefore, pack.battleID, pack.info->getSideArmy(BattleSide::ATTACKER), pack.info->getSideArmy(BattleSide::DEFENDER),
|
||||
pack.info->tile, pack.info->getSide(BattleSide::ATTACKER).hero, pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
pack.info->tile, pack.info->getSideHero(BattleSide::ATTACKER), pack.info->getSideHero(BattleSide::DEFENDER));
|
||||
}
|
||||
|
||||
void ApplyClientNetPackVisitor::visitBattleStart(BattleStart & pack)
|
||||
|
||||
@@ -157,10 +157,10 @@ struct RangeGenerator
|
||||
std::function<int()> myRand;
|
||||
};
|
||||
|
||||
std::unique_ptr<BattleInfo> BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town)
|
||||
std::unique_ptr<BattleInfo> BattleInfo::setupBattle(IGameCallback *cb, const int3 & tile, TerrainId terrain, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town)
|
||||
{
|
||||
CMP_stack cmpst;
|
||||
auto currentBattle = std::make_unique<BattleInfo>(layout);
|
||||
auto currentBattle = std::make_unique<BattleInfo>(cb, layout);
|
||||
|
||||
for(auto i : { BattleSide::LEFT_SIDE, BattleSide::RIGHT_SIDE})
|
||||
currentBattle->sides[i].init(heroes[i], armies[i]);
|
||||
@@ -171,7 +171,8 @@ std::unique_ptr<BattleInfo> BattleInfo::setupBattle(const int3 & tile, TerrainId
|
||||
currentBattle->round = -2;
|
||||
currentBattle->activeStack = -1;
|
||||
currentBattle->replayAllowed = false;
|
||||
currentBattle->town = town;
|
||||
if (town)
|
||||
currentBattle->townID = town->id;
|
||||
|
||||
//setting up siege obstacles
|
||||
if (town && town->fortificationsLevel().wallsHealth != 0)
|
||||
@@ -354,15 +355,15 @@ std::unique_ptr<BattleInfo> BattleInfo::setupBattle(const int3 & tile, TerrainId
|
||||
}
|
||||
}
|
||||
|
||||
if (currentBattle->town)
|
||||
if (currentBattle->townID.hasValue())
|
||||
{
|
||||
if (currentBattle->town->fortificationsLevel().citadelHealth != 0)
|
||||
if (currentBattle->getTown()->fortificationsLevel().citadelHealth != 0)
|
||||
currentBattle->generateNewStack(currentBattle->nextUnitId(), CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), BattleSide::DEFENDER, SlotID::ARROW_TOWERS_SLOT, BattleHex::CASTLE_CENTRAL_TOWER);
|
||||
|
||||
if (currentBattle->town->fortificationsLevel().upperTowerHealth != 0)
|
||||
if (currentBattle->getTown()->fortificationsLevel().upperTowerHealth != 0)
|
||||
currentBattle->generateNewStack(currentBattle->nextUnitId(), CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), BattleSide::DEFENDER, SlotID::ARROW_TOWERS_SLOT, BattleHex::CASTLE_UPPER_TOWER);
|
||||
|
||||
if (currentBattle->town->fortificationsLevel().lowerTowerHealth != 0)
|
||||
if (currentBattle->getTown()->fortificationsLevel().lowerTowerHealth != 0)
|
||||
currentBattle->generateNewStack(currentBattle->nextUnitId(), CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), BattleSide::DEFENDER, SlotID::ARROW_TOWERS_SLOT, BattleHex::CASTLE_BOTTOM_TOWER);
|
||||
|
||||
//Moat generating is done on server
|
||||
@@ -437,7 +438,7 @@ const CGHeroInstance * BattleInfo::getHero(const PlayerColor & player) const
|
||||
{
|
||||
for(const auto & side : sides)
|
||||
if(side.color == player)
|
||||
return side.hero;
|
||||
return side.getHero();
|
||||
|
||||
logGlobal->error("Player %s is not in battle!", player.toString());
|
||||
return nullptr;
|
||||
@@ -458,17 +459,18 @@ CStack * BattleInfo::getStack(int stackID, bool onlyAlive)
|
||||
return const_cast<CStack *>(battleGetStackByID(stackID, onlyAlive));
|
||||
}
|
||||
|
||||
BattleInfo::BattleInfo(const BattleLayout & layout):
|
||||
BattleInfo()
|
||||
BattleInfo::BattleInfo(IGameCallback *cb, const BattleLayout & layout):
|
||||
BattleInfo(cb)
|
||||
{
|
||||
*this->layout = layout;
|
||||
}
|
||||
|
||||
BattleInfo::BattleInfo():
|
||||
BattleInfo::BattleInfo(IGameCallback *cb)
|
||||
:GameCallbackHolder(cb),
|
||||
sides({SideInBattle(cb), SideInBattle(cb)}),
|
||||
layout(std::make_unique<BattleLayout>()),
|
||||
round(-1),
|
||||
activeStack(-1),
|
||||
town(nullptr),
|
||||
tile(-1,-1,-1),
|
||||
battlefieldType(BattleField::NONE),
|
||||
tacticsSide(BattleSide::NONE),
|
||||
@@ -557,12 +559,19 @@ PlayerColor BattleInfo::getSidePlayer(BattleSide side) const
|
||||
|
||||
const CArmedInstance * BattleInfo::getSideArmy(BattleSide side) const
|
||||
{
|
||||
return getSide(side).armyObject;
|
||||
return getSide(side).getArmy();
|
||||
}
|
||||
|
||||
const CGHeroInstance * BattleInfo::getSideHero(BattleSide side) const
|
||||
{
|
||||
return getSide(side).hero;
|
||||
return getSide(side).getHero();
|
||||
}
|
||||
|
||||
const CGTownInstance * BattleInfo::getTown() const
|
||||
{
|
||||
if (townID.hasValue())
|
||||
return cb->getTown(townID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t BattleInfo::getTacticDist() const
|
||||
@@ -577,7 +586,9 @@ BattleSide BattleInfo::getTacticsSide() const
|
||||
|
||||
const CGTownInstance * BattleInfo::getDefendedTown() const
|
||||
{
|
||||
return town;
|
||||
if (townID.hasValue())
|
||||
return cb->getTown(townID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EWallState BattleInfo::getWallState(EWallPart partOfWall) const
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "../int3.h"
|
||||
#include "../bonuses/Bonus.h"
|
||||
#include "../bonuses/CBonusSystemNode.h"
|
||||
|
||||
#include "CBattleInfoCallback.h"
|
||||
#include "IBattleState.h"
|
||||
#include "SiegeInfo.h"
|
||||
#include "SideInBattle.h"
|
||||
#include "SiegeInfo.h"
|
||||
|
||||
#include "../GameCallbackHolder.h"
|
||||
#include "../bonuses/Bonus.h"
|
||||
#include "../bonuses/CBonusSystemNode.h"
|
||||
#include "../int3.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -24,7 +27,7 @@ class CStackBasicDescriptor;
|
||||
class BattleField;
|
||||
struct BattleLayout;
|
||||
|
||||
class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState
|
||||
class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState, public GameCallbackHolder
|
||||
{
|
||||
BattleSideArray<SideInBattle> sides; //sides[0] - attacker, sides[1] - defender
|
||||
std::unique_ptr<BattleLayout> layout;
|
||||
@@ -33,7 +36,7 @@ public:
|
||||
|
||||
si32 round;
|
||||
si32 activeStack;
|
||||
const CGTownInstance * town; //used during town siege, nullptr if this is not a siege (note that fortless town IS also a siege)
|
||||
ObjectInstanceID townID; //used during town siege, nullptr if this is not a siege (note that fortless town IS also a siege)
|
||||
int3 tile; //for background and bonuses
|
||||
bool replayAllowed;
|
||||
std::vector<std::unique_ptr<CStack>> stacks;
|
||||
@@ -52,7 +55,7 @@ public:
|
||||
h & sides;
|
||||
h & round;
|
||||
h & activeStack;
|
||||
h & town;
|
||||
h & townID;
|
||||
h & tile;
|
||||
h & stacks;
|
||||
h & obstacles;
|
||||
@@ -66,8 +69,8 @@ public:
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BattleInfo(const BattleLayout & layout);
|
||||
BattleInfo();
|
||||
BattleInfo(IGameCallback *cb, const BattleLayout & layout);
|
||||
BattleInfo(IGameCallback *cb);
|
||||
virtual ~BattleInfo();
|
||||
|
||||
const IBattleInfo * getBattle() const override;
|
||||
@@ -93,6 +96,8 @@ public:
|
||||
const CArmedInstance * getSideArmy(BattleSide side) const override;
|
||||
const CGHeroInstance * getSideHero(BattleSide side) const override;
|
||||
|
||||
const CGTownInstance * getTown() const;
|
||||
|
||||
ui8 getTacticDist() const override;
|
||||
BattleSide getTacticsSide() const override;
|
||||
|
||||
@@ -154,7 +159,7 @@ public:
|
||||
const CGHeroInstance * getHero(const PlayerColor & player) const; //returns fighting hero that belongs to given player
|
||||
|
||||
void localInit();
|
||||
static std::unique_ptr<BattleInfo> setupBattle(const int3 & tile, TerrainId, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town);
|
||||
static std::unique_ptr<BattleInfo> setupBattle(IGameCallback *cb, const int3 & tile, TerrainId, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town);
|
||||
|
||||
BattleSide whatSide(const PlayerColor & player) const;
|
||||
|
||||
|
||||
@@ -9,16 +9,19 @@
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "SideInBattle.h"
|
||||
#include "../mapObjects/CArmedInstance.h"
|
||||
|
||||
#include "../IGameCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void SideInBattle::init(const CGHeroInstance * Hero, const CArmedInstance * Army)
|
||||
{
|
||||
hero = Hero;
|
||||
armyObject = Army;
|
||||
armyObjectID = Army->id;
|
||||
if (Hero)
|
||||
heroID = Hero->id;
|
||||
|
||||
switch(armyObject->ID.toEnum())
|
||||
switch(Army->ID.toEnum())
|
||||
{
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR2:
|
||||
@@ -27,11 +30,25 @@ void SideInBattle::init(const CGHeroInstance * Hero, const CArmedInstance * Army
|
||||
color = PlayerColor::NEUTRAL;
|
||||
break;
|
||||
default:
|
||||
color = armyObject->getOwner();
|
||||
color = Army->getOwner();
|
||||
}
|
||||
|
||||
if(color == PlayerColor::UNFLAGGABLE)
|
||||
color = PlayerColor::NEUTRAL;
|
||||
}
|
||||
|
||||
const CArmedInstance * SideInBattle::getArmy() const
|
||||
{
|
||||
if (armyObjectID.hasValue())
|
||||
return dynamic_cast<const CArmedInstance*>(cb->getObjInstance(armyObjectID));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CGHeroInstance * SideInBattle::getHero() const
|
||||
{
|
||||
if (heroID.hasValue())
|
||||
return cb->getHero(heroID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
@@ -8,31 +8,36 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../GameConstants.h"
|
||||
#include "../GameCallbackHolder.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGHeroInstance;
|
||||
class CArmedInstance;
|
||||
|
||||
struct DLL_LINKAGE SideInBattle
|
||||
struct DLL_LINKAGE SideInBattle : public GameCallbackHolder
|
||||
{
|
||||
using GameCallbackHolder::GameCallbackHolder;
|
||||
|
||||
PlayerColor color = PlayerColor::CANNOT_DETERMINE;
|
||||
const CGHeroInstance * hero = nullptr; //may be NULL if army is not commanded by hero
|
||||
const CArmedInstance * armyObject = nullptr; //adv. map object with army that participates in battle; may be same as hero
|
||||
ObjectInstanceID heroID; //may be empty if army is not commanded by hero
|
||||
ObjectInstanceID armyObjectID; //adv. map object with army that participates in battle; may be same as hero
|
||||
|
||||
uint32_t castSpellsCount = 0; //how many spells each side has been cast this turn
|
||||
std::vector<SpellID> usedSpellsHistory; //every time hero casts spell, it's inserted here -> eagle eye skill
|
||||
int32_t enchanterCounter = 0; //tends to pass through 0, so sign is needed
|
||||
|
||||
void init(const CGHeroInstance * Hero, const CArmedInstance * Army);
|
||||
|
||||
const CArmedInstance * getArmy() const;
|
||||
const CGHeroInstance * getHero() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & color;
|
||||
h & hero;
|
||||
h & armyObject;
|
||||
h & heroID;
|
||||
h & armyObjectID;
|
||||
h & castSpellsCount;
|
||||
h & usedSpellsHistory;
|
||||
h & enchanterCounter;
|
||||
|
||||
@@ -175,7 +175,7 @@ BattleID BattleProcessor::setupBattle(int3 tile, BattleSideArray<const CArmedIns
|
||||
|
||||
//send info about battles
|
||||
BattleStart bs;
|
||||
bs.info = BattleInfo::setupBattle(tile, terrain, battlefieldType, armies, heroes, layout, town);
|
||||
bs.info = BattleInfo::setupBattle(gameHandler->gameState()->callback, tile, terrain, battlefieldType, armies, heroes, layout, town);
|
||||
bs.battleID = gameHandler->gameState()->nextBattleID;
|
||||
|
||||
engageIntoBattle(bs.info->getSide(BattleSide::ATTACKER).color);
|
||||
|
||||
@@ -200,7 +200,7 @@ public:
|
||||
|
||||
//send info about battles
|
||||
|
||||
auto battle = BattleInfo::setupBattle(tile, terrain, terType, armedInstancies, heroes, layout, nullptr);
|
||||
auto battle = BattleInfo::setupBattle(gameState->callback, tile, terrain, terType, armedInstancies, heroes, layout, nullptr);
|
||||
|
||||
BattleStart bs;
|
||||
bs.info = std::move(battle);
|
||||
|
||||
Reference in New Issue
Block a user