1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
* CStack.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "bonuses/Bonus.h"
#include "bonuses/CBonusSystemNode.h"
#include "CCreatureHandler.h" //todo: remove
#include "battle/BattleHex.h"
#include "mapObjects/CGHeroInstance.h" // for commander serialization
#include "battle/CUnitState.h"
VCMI_LIB_NAMESPACE_BEGIN
struct BattleStackAttacked;
class BattleInfo;
//Represents STACK_BATTLE nodes
class DLL_LINKAGE CStack final : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment
{
private:
ui32 ID = -1; //unique ID of stack
CreatureID typeID;
TerrainId nativeTerrain; //tmp variable to save native terrain value on battle init
ui32 baseAmount = -1;
PlayerColor owner; //owner - player color (255 for neutrals)
BattleSide side = BattleSide::NONE;
SlotID slot; //slot - position in garrison (may be 255 for neutrals/called creatures)
bool doubleWideCached = false;
void postDeserialize(const CArmedInstance * army, const SlotID & extSlot);
public:
const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
BattleHex initialPosition; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
CStack(const CStackInstance * base, const PlayerColor & O, int I, BattleSide Side, const SlotID & S);
CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I, BattleSide Side, const SlotID & S = SlotID(255));
CStack();
~CStack();
std::string nodeName() const override;
void localInit(BattleInfo * battleInfo);
std::string getName() const; //plural or singular
bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
bool isOnNativeTerrain() const;
bool isOnTerrain(TerrainId terrain) const;
ui32 level() const;
si32 magicResistance() const override; //include aura of resistance
std::vector<SpellID> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
const CGHeroInstance * getMyHero() const; //if stack belongs to hero (directly or was by him summoned) returns hero, nullptr otherwise
static BattleHexArray meleeAttackHexes(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos = BattleHex::INVALID, BattleHex defenderPos = BattleHex::INVALID);
static bool isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos = BattleHex::INVALID, BattleHex defenderPos = BattleHex::INVALID);
BattleHex::EDir destShiftDir() const;
void prepareAttacked(BattleStackAttacked & bsa, vstd::RNG & rand) const; //requires bsa.damageAmount filled
static void prepareAttacked(BattleStackAttacked & bsa,
vstd::RNG & rand,
const std::shared_ptr<battle::CUnitState> & customState); //requires bsa.damageAmount filled
const CCreature * unitType() const override;
int32_t unitBaseAmount() const override;
uint32_t unitId() const override;
BattleSide unitSide() const override;
PlayerColor unitOwner() const override;
SlotID unitSlot() const override;
bool doubleWide() const override { return doubleWideCached;};
std::string getDescription() const override;
bool unitHasAmmoCart(const battle::Unit * unit) const override;
PlayerColor unitEffectiveOwner(const battle::Unit * unit) const override;
void spendMana(ServerCallback * server, const int spellCost) const override;
const IBonusBearer* getBonusBearer() const override;
PlayerColor getOwner() const override
{
return this->owner;
}
template <typename Handler> void serialize(Handler & h)
{
//this assumes that stack objects is newly created
//stackState is not serialized here
assert(isIndependentNode());
h & static_cast<CBonusSystemNode&>(*this);
h & typeID;
h & ID;
h & baseAmount;
h & owner;
h & slot;
h & side;
h & initialPosition;
const CArmedInstance * army = (base ? base->armyObj : nullptr);
SlotID extSlot = (base ? base->armyObj->findStack(base) : SlotID());
if(h.saving)
{
h & army;
h & extSlot;
}
else
{
h & army;
h & extSlot;
postDeserialize(army, extSlot);
}
}
private:
const BattleInfo * battle; //do not serialize
};
VCMI_LIB_NAMESPACE_END
|