1 //       _________ __                 __
2 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
3 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
5 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6 //             \/                  \/          \//_____/            \/
7 //  ______________________                           ______________________
8 //                        T H E   W A R   B E G I N S
9 //         Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name player.h - The player headerfile. */
12 //
13 //      (c) Copyright 1998-2005 by Lutz Sammer and Jimmy Salmon
14 //
15 //      This program is free software; you can redistribute it and/or modify
16 //      it under the terms of the GNU General Public License as published by
17 //      the Free Software Foundation; only version 2 of the License.
18 //
19 //      This program is distributed in the hope that it will be useful,
20 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //      GNU General Public License for more details.
23 //
24 //      You should have received a copy of the GNU General Public License
25 //      along with this program; if not, write to the Free Software
26 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 //      02111-1307, USA.
28 //
29 
30 #ifndef __PLAYER_H__
31 #define __PLAYER_H__
32 
33 //@{
34 
35 /*----------------------------------------------------------------------------
36 --  Includes
37 ----------------------------------------------------------------------------*/
38 
39 #include <set>
40 #include <string>
41 #include <vector>
42 
43 #include "color.h"
44 #include "upgrade_structs.h"
45 
46 #include "vec2i.h"
47 
48 class CGraphic;
49 
50 /*----------------------------------------------------------------------------
51 --  Definitons
52 ----------------------------------------------------------------------------*/
53 
54 #define STORE_OVERALL 0
55 #define STORE_BUILDING 1
56 #define STORE_BOTH 2
57 
58 #define SPEEDUP_FACTOR 100
59 /*----------------------------------------------------------------------------
60 --  Declarations
61 ----------------------------------------------------------------------------*/
62 
63 class CUnit;
64 class CUnitType;
65 class PlayerAi;
66 class CFile;
67 struct lua_State;
68 
69 /*----------------------------------------------------------------------------
70 --  Player type
71 ----------------------------------------------------------------------------*/
72 
73 enum _diplomacy_ {
74 	DiplomacyAllied,   /// Ally with opponent
75 	DiplomacyNeutral,  /// Don't attack be neutral
76 	DiplomacyEnemy,    /// Attack opponent
77 	DiplomacyCrazy     /// Ally and attack opponent
78 }; /// Diplomacy states for CommandDiplomacy
79 
80 enum class RevealTypes
81 {
82 	cNoRevelation,
83 	cAllUnits,
84 	cBuildingsOnly
85 }; /// Revelation types
86 
87 ///  Player structure
88 class CPlayer
89 {
90 public:
91 	static inline RevealTypes RevelationFor { RevealTypes::cNoRevelation }; /// type of revelation (when player lost their last main facility)
92 
93 public:
94 	/// Check if relevation enabled
IsRevelationEnabled()95 	static const bool IsRevelationEnabled()
96 	{
97 		// By default there is no revelation. Can be changed in lua-script
98 		return CPlayer::RevelationFor != RevealTypes::cNoRevelation;
99 	}
100 	/// Change revelation type
101 	static void SetRevelationType(const RevealTypes type);
102 	/// Get revealed players list
GetRevealedPlayers()103 	static const std::vector<const CPlayer *> &GetRevealedPlayers()
104 	{
105 		return CPlayer::RevealedPlayers;
106 	}
107 
108 private:
109 	/// List of players revealed after losing their last Town Hall
110 	static inline std::vector<const CPlayer *> RevealedPlayers;
111 
112 public:
113 	int Index;          /// player as number
114 	std::string Name;   /// name of non computer
115 
116 	int   Type;         /// type of player (human,computer,...)
117 	int   Race;         /// race of player (orc,human,...)
118 	std::string AiName; /// AI for computer
119 
120 	// friend enemy detection
121 	int      Team;          /// team of player
122 
123 	Vec2i StartPos;  /// map tile start position
124 
SetStartView(const Vec2i & pos)125 	inline void SetStartView(const Vec2i &pos) { StartPos = pos; }
126 
127 	int Resources[MaxCosts];      /// resources in overall store
128 	int MaxResources[MaxCosts];   /// max resources can be stored
129 	int StoredResources[MaxCosts];/// resources in store buildings (can't exceed MaxResources)
130 	int LastResources[MaxCosts];  /// last values for revenue
131 	int Incomes[MaxCosts];        /// income of the resources
132 	int Revenue[MaxCosts];        /// income rate of the resources
133 
134 	int SpeedResourcesHarvest[MaxCosts]; /// speed factor for harvesting resources
135 	int SpeedResourcesReturn[MaxCosts];  /// speed factor for returning resources
136 	int SpeedBuild;                  /// speed factor for building
137 	int SpeedTrain;                  /// speed factor for training
138 	int SpeedUpgrade;                /// speed factor for upgrading
139 	int SpeedResearch;               /// speed factor for researching
140 
141 	// FIXME: shouldn't use the constant
142 	int UnitTypesCount[UnitTypeMax];  /// total units of unit-type
143 	int UnitTypesAiActiveCount[UnitTypeMax];  /// total units of unit-type that have their AI set to active
144 
145 	bool AiEnabled;        /// handle AI on local computer
146 	PlayerAi *Ai;          /// Ai structure pointer
147 
148 	int    NumBuildings;   /// # buildings
149 	int    Supply;         /// supply available/produced
150 	int    Demand;         /// demand of player
151 
152 	int    UnitLimit;       /// # food units allowed
153 	int    BuildingLimit;   /// # buildings allowed
154 	int    TotalUnitLimit;  /// # total unit number allowed
155 
156 	int    Score;           /// Points for killing ...
157 	int    TotalUnits;
158 	int    TotalBuildings;
159 	int    TotalResources[MaxCosts];
160 	int    TotalRazings;
161 	int    TotalKills;      /// How many unit killed
162 
163 	int 	LostMainFacilityTimer { 0 };/// The timer for when the player lost the last town hall
164 									/// (to make the player's units be revealed)
165 
166 	IntColor Color;           /// color of units on minimap
167 
168 	CUnitColors UnitColors; /// Unit colors for new units
169 
170 	std::vector<CUnit *> FreeWorkers;	/// Container for free workers
171 
172 	// Upgrades/Allows:
173 	CAllow Allow;                 /// Allowed for player
174 	CUpgradeTimers UpgradeTimers; /// Timer for the upgrades
175 
176 	/// Change player name
177 	void SetName(const std::string &name);
178 
179 	/// Clear turn related player data
180 	void Clear();
181 
182 	std::vector<CUnit *>::const_iterator UnitBegin() const;
183 	std::vector<CUnit *>::iterator UnitBegin();
184 	std::vector<CUnit *>::const_iterator UnitEnd() const;
185 	std::vector<CUnit *>::iterator UnitEnd();
186 
GetUnits()187 	const std::vector<CUnit *> &GetUnits() const {
188 		return this->Units;
189 	}
190 	CUnit &GetUnit(int index) const;
191 	int GetUnitCount() const;
192 
193 	void AddUnit(CUnit &unit);
194 	void RemoveUnit(CUnit &unit);
195 	void UpdateFreeWorkers();
196 
197 	/// Get a resource of the player
198 	int GetResource(const int resource, const int type);
199 	/// Adds/subtracts some resources to/from the player store
200 	void ChangeResource(const int resource, const int value, const bool store = false);
201 	/// Set a resource of the player
202 	void SetResource(const int resource, const int value, const int type = STORE_OVERALL);
203 	/// Check, if there enough resources for action.
204 	bool CheckResource(const int resource, const int value);
205 
206 	/// Returns count of specified unittype
207 	int GetUnitTotalCount(const CUnitType &type) const;
208 	/// Check if the unit-type didn't break any unit limits and supply/demand
209 	int CheckLimits(const CUnitType &type) const;
210 
211 	/// Check if enough resources are available for costs
212 	int CheckCosts(const int *costs, bool notify = true) const;
213 	/// Check if enough resources are available for a new unit-type
214 	int CheckUnitType(const CUnitType &type) const;
215 
216 	/// Add costs to the resources
217 	void AddCosts(const int *costs);
218 	/// Add costs for an unit-type to the resources
219 	void AddUnitType(const CUnitType &type);
220 	/// Add a factor of costs to the resources
221 	void AddCostsFactor(const int *costs, int factor);
222 	/// Remove costs from the resources
223 	void SubCosts(const int *costs);
224 	/// Remove costs for an unit-type from the resources
225 	void SubUnitType(const CUnitType &type);
226 	/// Remove a factor of costs from the resources
227 	void SubCostsFactor(const int *costs, int factor);
228 
229 	/// Does the player have units of that type
230 	int HaveUnitTypeByType(const CUnitType &type) const;
231 	/// Does the player have units of that type
232 	int HaveUnitTypeByIdent(const std::string &ident) const;
233 
234 	/// Notify player about a problem
235 	void Notify(int type, const Vec2i &pos, const char *fmt, ...) const PRINTF_VAARG_ATTRIBUTE(4, 5); // Don't forget to count this
236 	/// Notify player about a problem
237 	void Notify(const char *fmt, ...) const PRINTF_VAARG_ATTRIBUTE(2, 3); // Don't forget to count this
238 
239 
240 	/**
241 	**  Check if the player index is an enemy
242 	*/
IsEnemy(const int index)243 	bool IsEnemy(const int index) const
244 	{
245 		return (Index != index && (Enemy & (1 << index)) != 0);
246 	}
247 
248 	/**
249 	**  Check if the player index is an enemy
250 	*/
IsAllied(const int index)251 	bool IsAllied(const int index) const
252 	{
253 		return (Index != index && (Allied & (1 << index)) != 0);
254 	}
255 
256 	bool IsEnemy(const CPlayer &player) const;
257 	bool IsEnemy(const CUnit &unit) const;
258 	bool IsAllied(const CPlayer &player) const;
259 	bool IsAllied(const CUnit &unit) const;
260 	bool IsVisionSharing() const;
GetSharedVision()261 	const std::set<uint8_t> &GetSharedVision() const
262 	{
263 		return this->HasVisionFrom;
264 	}
GetGaveVisionTo()265 	const std::set<uint8_t> &GetGaveVisionTo() const
266 	{
267 		return this->GaveVisionTo;
268 	}
HasSharedVisionWith(const CPlayer & player)269 	bool HasSharedVisionWith(const CPlayer &player) const
270 	{
271 		return (this->GaveVisionTo.find(player.Index) != this->GaveVisionTo.end());
272 	}
273 	bool IsTeamed(const CPlayer &player) const;
274 	bool IsTeamed(const CUnit &unit) const;
275 
276 	void SetDiplomacyNeutralWith(const CPlayer &player);
277 	void SetDiplomacyAlliedWith(const CPlayer &player);
278 	void SetDiplomacyEnemyWith(const CPlayer &player);
279 	void SetDiplomacyCrazyWith(const CPlayer &player);
280 
281 	void ShareVisionWith(CPlayer &player);
282 	void EnableSharedVisionFrom(const CPlayer &player);
283 	void UnshareVisionWith(CPlayer &player);
284 	void DisableSharedVisionFrom(const CPlayer &player);
285 
286 	void Init(/* PlayerTypes */ int type);
287 	void Save(CFile &file) const;
288 	void Load(lua_State *l);
289 
IsRevealed()290 	bool IsRevealed() const
291 	{
292 		return this->isRevealed;
293 	}
294 	void SetRevealed(const bool revealed);
295 
296 private:
297 	std::vector<CUnit *> Units;        /// units of this player
298 	unsigned int Enemy;                /// enemy bit field for this player
299 	unsigned int Allied;               /// allied bit field for this player
300 	std::set<uint8_t> HasVisionFrom;   /// set of player indexes that have shared their vision with this player
301 	std::set<uint8_t> GaveVisionTo;    /// set of player indexes that this player has shared vision with
302 
303 	bool isRevealed { false }; 	/// whether the player has been revealed (i.e. after losing the last Town Hall)
304 
305 	friend void CleanPlayers();
306 };
307 
308 /**
309 **  Races for the player
310 **  Mapped with #PlayerRaces to a symbolic name.
311 */
312 class PlayerRace
313 {
314 public:
PlayerRace()315 	PlayerRace() : Count(0)
316 	{
317 		memset(Visible, 0, sizeof(Visible));
318 	}
319 
320 	void Clean();
321 	int GetRaceIndexByName(const char *raceName) const;
322 
323 public:
324 	bool Visible[MAX_RACES];        /// race should be visible in pulldown
325 	std::string Name[MAX_RACES];    /// race names
326 	std::string Display[MAX_RACES]; /// text to display in pulldown
327 	unsigned int Count;             /// number of races
328 };
329 
330 
331 enum PlayerRacesOld {
332 	PlayerRaceHuman = 0,  /// belongs to human
333 	PlayerRaceOrc  = 1    /// belongs to orc
334 };
335 
336 /**
337 **  Types for the player
338 **
339 **  #PlayerNeutral
340 **
341 **    This player is controlled by the computer doing nothing.
342 **
343 **  #PlayerNobody
344 **
345 **    This player is unused. Nobody controls this player.
346 **
347 **  #PlayerComputer
348 **
349 **    This player is controlled by the computer. CPlayer::AiNum
350 **    selects the AI strategy.
351 **
352 **  #PlayerPerson
353 **
354 **    This player is contolled by a person. This can be the player
355 **    sitting on the local computer or player playing over the
356 **    network.
357 **
358 **  #PlayerRescuePassive
359 **
360 **    This player does nothing, the game pieces just sit in the game
361 **    (being passive)... when a person player moves next to a
362 **    PassiveRescue unit/building, then it is "rescued" and becomes
363 **    part of that persons team. If the city center is rescued, than
364 **    all units of this player are rescued.
365 **
366 **  #PlayerRescueActive
367 **
368 **    This player is controlled by the computer. CPlayer::AiNum
369 **    selects the AI strategy. Until it is rescued it plays like
370 **    an ally. The first person which reaches units of this player,
371 **    can rescue them. If the city center is rescued, than all units
372 **    of this player are rescued.
373 */
374 enum PlayerTypes {
375 	PlayerNeutral = 2,        /// neutral
376 	PlayerNobody  = 3,        /// unused slot
377 	PlayerComputer = 4,       /// computer player
378 	PlayerPerson = 5,         /// human player
379 	PlayerRescuePassive = 6,  /// rescued passive
380 	PlayerRescueActive = 7    /// rescued  active
381 };
382 
383 #define PlayerNumNeutral (PlayerMax - 1)  /// this is the neutral player slot
384 
385 /**
386 **  Notify types. Noties are send to the player.
387 */
388 enum NotifyType {
389 	NotifyRed,     /// Red alram
390 	NotifyYellow,  /// Yellow alarm
391 	NotifyGreen    /// Green alarm
392 };
393 
394 /*----------------------------------------------------------------------------
395 --  Variables
396 ----------------------------------------------------------------------------*/
397 
398 extern int NumPlayers;             /// How many player slots used
399 extern CPlayer Players[PlayerMax];  /// All players
400 extern CPlayer *ThisPlayer;         /// Player on local computer
401 extern bool NoRescueCheck;          /// Disable rescue check
402 extern std::vector<CColor> PlayerColorsRGB[PlayerMax]; /// Player colors
403 extern std::vector<IntColor> PlayerColors[PlayerMax]; /// Player colors
404 extern std::string PlayerColorNames[PlayerMax];  /// Player color names
405 
406 extern PlayerRace PlayerRaces;  /// Player races
407 
408 /**
409 **  Which indexes to replace with player color
410 */
411 extern int PlayerColorIndexStart;
412 extern int PlayerColorIndexCount;
413 
414 /*----------------------------------------------------------------------------
415 --  Functions
416 ----------------------------------------------------------------------------*/
417 
418 /// Init players
419 extern void InitPlayers();
420 /// Clean up players
421 extern void CleanPlayers();
422 /// Save players
423 extern void SavePlayers(CFile &file);
424 
425 /// Create a new player
426 extern void CreatePlayer(int type);
427 
428 
429 /// Initialize the computer opponent AI
430 extern void PlayersInitAi();
431 /// Called each game cycle for player handlers (AI)
432 extern void PlayersEachCycle();
433 /// Called each second for a given player handler (AI)
434 extern void PlayersEachSecond(int player);
435 
436 /// Change current color set to new player of the sprite
437 extern void GraphicPlayerPixels(CPlayer &player, const CGraphic &sprite);
438 
439 /// Output debug information for players
440 extern void DebugPlayers();
441 
442 void FreePlayerColors();
443 
444 /// register ccl features
445 extern void PlayerCclRegister();
446 
447 /// Allowed to select multiple units, maybe not mine
CanSelectMultipleUnits(const CPlayer & player)448 inline bool CanSelectMultipleUnits(const CPlayer &player) { return &player == ThisPlayer || ThisPlayer->IsTeamed(player); }
449 
450 //@}
451 
452 #endif // !__PLAYER_H__
453