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