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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
/*
* CGameState.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/CBonusSystemNode.h"
#include "../IGameCallback.h"
#include "../LoadProgress.h"
#include "../ConstTransitivePtr.h"
#include "RumorState.h"
#include "GameStatistics.h"
namespace boost
{
class shared_mutex;
}
VCMI_LIB_NAMESPACE_BEGIN
class EVictoryLossCheckResult;
class Services;
class IMapService;
class CMap;
struct CPack;
class CHeroClass;
struct EventCondition;
struct CampaignTravel;
class CStackInstance;
class CGameStateCampaign;
class TavernHeroesPool;
struct SThievesGuildInfo;
class CRandomGenerator;
class GameSettings;
class BattleInfo;
class UpgradeInfo;
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult);
class DLL_LINKAGE CGameState : public CNonConstInfoCallback, public Serializeable
{
friend class CGameStateCampaign;
public:
/// Stores number of times each artifact was placed on map via randomization
std::map<ArtifactID, int> allocatedArtifacts;
/// List of currently ongoing battles
std::vector<std::unique_ptr<BattleInfo>> currentBattles;
/// ID that can be allocated to next battle
BattleID nextBattleID = BattleID(0);
//we have here all heroes available on this map that are not hired
std::unique_ptr<TavernHeroesPool> heroesPool;
/// list of players currently making turn. Usually - just one, except for simturns
std::set<PlayerColor> actingPlayers;
IGameCallback * callback;
CGameState();
virtual ~CGameState();
void preInit(Services * services, IGameCallback * callback);
void init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator &, bool allowSavingRandomMap = true);
void updateOnLoad(StartInfo * si);
ConstTransitivePtr<StartInfo> scenarioOps;
ConstTransitivePtr<StartInfo> initialOpts; //copy of settings received from pregame (not randomized)
ui32 day; //total number of days in game
ConstTransitivePtr<CMap> map;
std::map<PlayerColor, PlayerState> players;
std::map<TeamID, TeamState> teams;
CBonusSystemNode globalEffects;
RumorState currentRumor;
StatisticDataSet statistic;
static boost::shared_mutex mutex;
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
bool giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid);
/// picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
HeroTypeID pickNextHeroType(const PlayerColor & owner);
void apply(CPackForClient & pack);
BattleField battleGetBattlefieldType(int3 tile, vstd::RNG & rand);
void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const override;
PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const override;
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const override;
int3 guardingCreaturePosition (int3 pos) const override;
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags);
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> filtered);
/// Returns battle in which selected player is engaged, or nullptr if none.
/// Can NOT be used with neutral player, use battle by ID instead
const BattleInfo * getBattle(const PlayerColor & player) const;
/// Returns battle by its unique identifier, or nullptr if not found
const BattleInfo * getBattle(const BattleID & battle) const;
BattleInfo * getBattle(const BattleID & battle);
// ----- victory, loss condition checks -----
EVictoryLossCheckResult checkForVictoryAndLoss(const PlayerColor & player) const;
bool checkForVictory(const PlayerColor & player, const EventCondition & condition) const; //checks if given player is winner
PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
bool checkForStandardLoss(const PlayerColor & player) const; //checks if given player lost the game
void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild
const IGameSettings & getSettings() const;
bool isVisible(int3 pos, const std::optional<PlayerColor> & player) const override;
bool isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & player) const override;
static int getDate(int day, Date mode);
int getDate(Date mode=Date::DAY) const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
// ----- getters, setters -----
/// This RNG should only be used inside GS or CPackForClient-derived applyGs
/// If this doesn't work for your code that mean you need a new netpack
///
/// Client-side must use vstd::RNG::getDefault which is not serialized
///
/// CGameHandler have it's own getter for vstd::RNG::getDefault
/// Any server-side code outside of GH must use vstd::RNG::getDefault
vstd::RNG & getRandomGenerator();
template <typename Handler> void serialize(Handler &h)
{
h & scenarioOps;
h & initialOpts;
h & actingPlayers;
h & day;
h & map;
h & players;
if (h.version < Handler::Version::PLAYER_STATE_OWNED_OBJECTS)
generateOwnedObjectsAfterDeserialize();
h & teams;
h & heroesPool;
h & globalEffects;
if (h.version < Handler::Version::REMOVE_LIB_RNG)
{
std::string oldStateOfRNG;
h & oldStateOfRNG;
}
h & currentRumor;
h & campaign;
h & allocatedArtifacts;
if (h.version >= Handler::Version::STATISTICS)
h & statistic;
BONUS_TREE_DESERIALIZATION_FIX
}
private:
// ----- initialization -----
void initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking);
void initGlobalBonuses();
void initGrailPosition();
void initRandomFactionsForPlayers();
void initOwnedObjects();
void randomizeMapObjects();
void initPlayerStates();
void placeStartingHeroes();
void placeStartingHero(const PlayerColor & playerColor, const HeroTypeID & heroTypeId, int3 townPos);
void removeHeroPlaceholders();
void initDifficulty();
void initHeroes();
void placeHeroesInTowns();
void initFogOfWar();
void initStartingBonus();
void initTowns();
void initTownNames();
void initMapObjects();
void initVisitingAndGarrisonedHeroes();
void initCampaign();
void generateOwnedObjectsAfterDeserialize();
// ----- bonus system handling -----
void buildBonusSystemTree();
void attachArmedObjects();
void buildGlobalTeamPlayerTree();
void deserializationFix();
// ---- misc helpers -----
CGHeroInstance * getUsedHero(const HeroTypeID & hid) const;
bool isUsedHero(const HeroTypeID & hid) const; //looks in heroes and prisons
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
HeroTypeID pickUnusedHeroTypeRandomly(const PlayerColor & owner); // picks a unused hero type randomly
UpgradeInfo fillUpgradeInfo(const CStackInstance &stack) const;
// ---- data -----
Services * services;
/// Pointer to campaign state manager. Nullptr for single scenarios
std::unique_ptr<CGameStateCampaign> campaign;
friend class IGameCallback;
friend class CMapHandler;
friend class CGameHandler;
};
VCMI_LIB_NAMESPACE_END
|