/* * BattleInfo.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 "../int3.h" #include "../bonuses/Bonus.h" #include "../bonuses/CBonusSystemNode.h" #include "CBattleInfoCallback.h" #include "IBattleState.h" #include "SiegeInfo.h" #include "SideInBattle.h" VCMI_LIB_NAMESPACE_BEGIN class CStack; class CStackInstance; class CStackBasicDescriptor; class BattleField; class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState { public: BattleID battleID = BattleID(0); enum BattleSide { ATTACKER = 0, DEFENDER }; std::array sides; //sides[0] - attacker, sides[1] - defender si32 round, activeStack; const CGTownInstance * town; //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 creatureBank; //auxilary field, do not serialize bool replayAllowed; std::vector stacks; std::vector > obstacles; SiegeInfo si; BattleField battlefieldType; //like !!BA:B TerrainId terrainType; //used for some stack nativity checks (not the bonus limiters though that have their own copy) ui8 tacticsSide; //which side is requested to play tactics phase ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line) template void serialize(Handler &h, const int version) { h & battleID; h & sides; h & round; h & activeStack; h & town; h & tile; h & stacks; h & obstacles; h & si; h & battlefieldType; h & terrainType; h & tacticsSide; h & tacticDistance; h & static_cast(*this); if (version > 824) h & replayAllowed; else replayAllowed = false; } ////////////////////////////////////////////////////////////////////////// BattleInfo(); virtual ~BattleInfo(); const IBattleInfo * getBattle() const override; std::optional getPlayerID() const override; ////////////////////////////////////////////////////////////////////////// // IBattleInfo BattleID getBattleID() const override; int32_t getActiveStackID() const override; TStacks getStacksIf(TStackFilter predicate) const override; battle::Units getUnitsIf(battle::UnitFilter predicate) const override; BattleField getBattlefieldType() const override; TerrainId getTerrainType() const override; ObstacleCList getAllObstacles() const override; PlayerColor getSidePlayer(ui8 side) const override; const CArmedInstance * getSideArmy(ui8 side) const override; const CGHeroInstance * getSideHero(ui8 side) const override; ui8 getTacticDist() const override; ui8 getTacticsSide() const override; const CGTownInstance * getDefendedTown() const override; EWallState getWallState(EWallPart partOfWall) const override; EGateState getGateState() const override; uint32_t getCastSpells(ui8 side) const override; int32_t getEnchanterCounter(ui8 side) const override; const IBonusBearer * getBonusBearer() const override; uint32_t nextUnitId() const override; int64_t getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const override; int3 getLocation() const override; bool isCreatureBank() const override; std::vector getUsedSpells(ui8 side) const override; ////////////////////////////////////////////////////////////////////////// // IBattleState void nextRound() override; void nextTurn(uint32_t unitId) override; void addUnit(uint32_t id, const JsonNode & data) override; void moveUnit(uint32_t id, BattleHex destination) override; void setUnitState(uint32_t id, const JsonNode & data, int64_t healthDelta) override; void removeUnit(uint32_t id) override; void updateUnit(uint32_t id, const JsonNode & data) override; void addUnitBonus(uint32_t id, const std::vector & bonus) override; void updateUnitBonus(uint32_t id, const std::vector & bonus) override; void removeUnitBonus(uint32_t id, const std::vector & bonus) override; void setWallState(EWallPart partOfWall, EWallState state) override; void addObstacle(const ObstacleChanges & changes) override; void updateObstacle(const ObstacleChanges& changes) override; void removeObstacle(uint32_t id) override; static void addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool forceAdd); ////////////////////////////////////////////////////////////////////////// CStack * getStack(int stackID, bool onlyAlive = true); using CBattleInfoEssentials::battleGetArmyObject; CArmedInstance * battleGetArmyObject(ui8 side) const; using CBattleInfoEssentials::battleGetFightingHero; CGHeroInstance * battleGetFightingHero(ui8 side) const; CStack * generateNewStack(uint32_t id, const CStackInstance & base, ui8 side, const SlotID & slot, BattleHex position); CStack * generateNewStack(uint32_t id, const CStackBasicDescriptor & base, ui8 side, const SlotID & slot, BattleHex position); const CGHeroInstance * getHero(const PlayerColor & player) const; //returns fighting hero that belongs to given player void localInit(); static BattleInfo * setupBattle(const int3 & tile, TerrainId, const BattleField & battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town); ui8 whatSide(const PlayerColor & player) const; protected: #if SCRIPTING_ENABLED scripting::Pool * getContextPool() const override; #endif }; class DLL_LINKAGE CMP_stack { int phase; //rules of which phase will be used int turn; uint8_t side; public: bool operator()(const battle::Unit * a, const battle::Unit * b) const; CMP_stack(int Phase = 1, int Turn = 0, uint8_t Side = BattleSide::ATTACKER); }; VCMI_LIB_NAMESPACE_END