File: StartInfo.h

package info (click to toggle)
vcmi 0.99%2Bdfsg%2Bgit20190113.f06c8a87-2
  • links: PTS, VCS
  • area: contrib
  • in suites: bullseye
  • size: 11,136 kB
  • sloc: cpp: 142,615; sh: 315; objc: 248; makefile: 32; ansic: 28; python: 13
file content (192 lines) | stat: -rw-r--r-- 5,038 bytes parent folder | download | duplicates (2)
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
/*
 * StartInfo.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 "GameConstants.h"

class CMapGenOptions;
class CCampaignState;
class CMapInfo;
struct PlayerInfo;
class PlayerColor;
class SharedMemory;

/// Struct which describes the name, the color, the starting bonus of a player
struct DLL_LINKAGE PlayerSettings
{
	enum { PLAYER_AI = 0 }; // for use in playerID

	enum Ebonus {
		NONE     = -2,
		RANDOM   = -1,
		ARTIFACT =  0,
		GOLD     =  1,
		RESOURCE =  2
	};

	Ebonus bonus;
	si16 castle;
	si32 hero,
		 heroPortrait; //-1 if default, else ID

	std::string heroName;
	PlayerColor color; //from 0 -
	enum EHandicap {NO_HANDICAP, MILD, SEVERE};
	EHandicap handicap;//0-no, 1-mild, 2-severe
	TeamID team;

	std::string name;
	std::set<ui8> connectedPlayerIDs; //Empty - AI, or connectrd player ids
	bool compOnly; //true if this player is a computer only player; required for RMG
	template <typename Handler>
	void serialize(Handler &h, const int version)
	{
		h & castle;
		h & hero;
		h & heroPortrait;
		h & heroName;
		h & bonus;
		h & color;
		h & handicap;
		h & name;
		if(version < 787)
		{
			ui8 oldConnectedId = 0;
			h & oldConnectedId;
			if(oldConnectedId)
			{
				connectedPlayerIDs.insert(oldConnectedId);
			}
		}
		else
		{
			h & connectedPlayerIDs;
		}
		h & team;
		h & compOnly;
	}

	PlayerSettings();
	bool isControlledByAI() const;
	bool isControlledByHuman() const;
};

/// Struct which describes the difficulty, the turn time,.. of a heroes match.
struct DLL_LINKAGE StartInfo
{
	enum EMode {NEW_GAME, LOAD_GAME, CAMPAIGN, INVALID = 255};

	EMode mode;
	ui8 difficulty; //0=easy; 4=impossible

	typedef std::map<PlayerColor, PlayerSettings> TPlayerInfos;
	TPlayerInfos playerInfos; //color indexed

	ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack)
	ui32 seedPostInit; //so we know that game is correctly synced at the start; 0 if not known yet
	ui32 mapfileChecksum; //0 if not relevant
	ui8 turnTime; //in minutes, 0=unlimited
	std::string mapname; // empty for random map, otherwise name of the map or savegame
	bool createRandomMap() const { return mapGenOptions.get() != nullptr; }
	std::shared_ptr<CMapGenOptions> mapGenOptions;

	std::shared_ptr<CCampaignState> campState;

	PlayerSettings & getIthPlayersSettings(PlayerColor no);
	const PlayerSettings & getIthPlayersSettings(PlayerColor no) const;
	PlayerSettings * getPlayersSettings(const ui8 connectedPlayerId);

	// TODO: Must be client-side
	std::string getCampaignName() const;

	template <typename Handler>
	void serialize(Handler &h, const int version)
	{
		h & mode;
		h & difficulty;
		h & playerInfos;
		h & seedToBeUsed;
		h & seedPostInit;
		h & mapfileChecksum;
		h & turnTime;
		h & mapname;
		h & mapGenOptions;
		h & campState;
	}

	StartInfo() : mode(INVALID), difficulty(0), seedToBeUsed(0), seedPostInit(0),
		mapfileChecksum(0), turnTime(0)
	{

	}
};

struct ClientPlayer
{
	int connection;
	std::string name;

	template <typename Handler> void serialize(Handler &h, const int version)
	{
		h & connection;
		h & name;
	}
};

struct DLL_LINKAGE LobbyState
{
	std::shared_ptr<StartInfo> si;
	std::shared_ptr<CMapInfo> mi;
	std::map<ui8, ClientPlayer> playerNames; // id of player <-> player name; 0 is reserved as ID of AI "players"
	int hostClientId;
	// TODO: Campaign-only and we don't really need either of them.
	// Before start both go into CCampaignState that is part of StartInfo
	int campaignMap;
	int campaignBonus;

	LobbyState() : si(new StartInfo()), hostClientId(-1), campaignMap(-1), campaignBonus(-1) {}

	template <typename Handler> void serialize(Handler &h, const int version)
	{
		h & si;
		h & mi;
		h & playerNames;
		h & hostClientId;
		h & campaignMap;
		h & campaignBonus;
	}
};

struct DLL_LINKAGE LobbyInfo : public LobbyState
{
	boost::mutex stateMutex;
	std::string uuid;
	std::shared_ptr<SharedMemory> shm;

	LobbyInfo() {}

	void verifyStateBeforeStart(bool ignoreNoHuman = false) const;

	bool isClientHost(int clientId) const;
	std::set<PlayerColor> getAllClientPlayers(int clientId);
	std::vector<ui8> getConnectedPlayerIdsForClient(int clientId) const;

	// Helpers for lobby state access
	std::set<PlayerColor> clientHumanColors(int clientId);
	PlayerColor clientFirstColor(int clientId) const;
	bool isClientColor(int clientId, PlayerColor color) const;
	ui8 clientFirstId(int clientId) const; // Used by chat only!
	PlayerInfo & getPlayerInfo(int color);
	TeamID getPlayerTeamId(PlayerColor color);
};

class ExceptionMapMissing : public std::exception {};
class ExceptionNoHuman : public std::exception {};
class ExceptionNoTemplate : public std::exception {};