File: CGameState.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (221 lines) | stat: -rw-r--r-- 7,881 bytes parent folder | download
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