1 /* $Id$ */ |
|
2 |
|
3 /** @file player.h */ |
|
4 |
|
5 #ifndef PLAYER_H |
|
6 #define PLAYER_H |
|
7 |
|
8 #include "road_func.h" |
|
9 #include "date_type.h" |
|
10 #include "engine.h" |
|
11 #include "livery.h" |
|
12 #include "genworld.h" |
|
13 #include "autoreplace_type.h" |
|
14 |
|
15 struct PlayerEconomyEntry { |
|
16 Money income; |
|
17 Money expenses; |
|
18 int32 delivered_cargo; |
|
19 int32 performance_history; ///< player score (scale 0-1000) |
|
20 Money company_value; |
|
21 }; |
|
22 |
|
23 /* The "steps" in loan size, in British Pounds! */ |
|
24 enum { |
|
25 LOAN_INTERVAL = 10000, |
|
26 }; |
|
27 |
|
28 struct Player { |
|
29 uint32 name_2; |
|
30 uint16 name_1; |
|
31 |
|
32 uint16 president_name_1; |
|
33 uint32 president_name_2; |
|
34 |
|
35 PlayerFace face; |
|
36 |
|
37 Money player_money; |
|
38 Money current_loan; |
|
39 |
|
40 byte player_color; |
|
41 Livery livery[LS_END]; |
|
42 byte player_money_fraction; |
|
43 byte avail_railtypes; |
|
44 byte avail_roadtypes; |
|
45 byte block_preview; |
|
46 PlayerByte index; |
|
47 |
|
48 uint16 cargo_types; ///< which cargo types were transported the last year |
|
49 |
|
50 TileIndex location_of_house; |
|
51 TileIndex last_build_coordinate; |
|
52 |
|
53 PlayerByte share_owners[4]; |
|
54 |
|
55 Year inaugurated_year; |
|
56 byte num_valid_stat_ent; |
|
57 |
|
58 byte quarters_of_bankrupcy; |
|
59 byte bankrupt_asked; ///< which players were asked about buying it? |
|
60 int16 bankrupt_timeout; |
|
61 Money bankrupt_value; |
|
62 |
|
63 bool is_active; |
|
64 bool is_ai; |
|
65 bool is_noai; ///< This is a NoAI player (for loading old savegames properly). Part of the NoAI 'hack' to retain savegame compatability with trunk. |
|
66 |
|
67 Money yearly_expenses[3][13]; |
|
68 PlayerEconomyEntry cur_economy; |
|
69 PlayerEconomyEntry old_economy[24]; |
|
70 EngineRenewList engine_renew_list; ///< Defined later |
|
71 bool engine_renew; |
|
72 bool renew_keep_length; |
|
73 int16 engine_renew_months; |
|
74 uint32 engine_renew_money; |
|
75 uint16 num_engines[TOTAL_NUM_ENGINES]; ///< caches the number of engines of each type the player owns (no need to save this) |
|
76 }; |
|
77 |
|
78 uint16 GetDrawStringPlayerColor(PlayerID player); |
|
79 |
|
80 void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player); |
|
81 void GetNameOfOwner(Owner owner, TileIndex tile); |
|
82 Money CalculateCompanyValue(const Player *p); |
|
83 void InvalidatePlayerWindows(const Player *p); |
|
84 void SetLocalPlayer(PlayerID new_player); |
|
85 #define FOR_ALL_PLAYERS(p) for (p = _players; p != endof(_players); p++) |
|
86 |
|
87 VARDEF PlayerByte _local_player; |
|
88 VARDEF PlayerByte _current_player; |
|
89 |
|
90 VARDEF Player _players[MAX_PLAYERS]; |
|
91 /* NOSAVE: can be determined from player structs */ |
|
92 VARDEF byte _player_colors[MAX_PLAYERS]; |
|
93 |
|
94 static inline byte ActivePlayerCount() |
|
95 { |
|
96 const Player *p; |
|
97 byte count = 0; |
|
98 |
|
99 FOR_ALL_PLAYERS(p) { |
|
100 if (p->is_active) count++; |
|
101 } |
|
102 |
|
103 return count; |
|
104 } |
|
105 |
|
106 static inline Player *GetPlayer(PlayerID i) |
|
107 { |
|
108 assert(IsInsideBS(i, PLAYER_FIRST, lengthof(_players))); |
|
109 return &_players[i]; |
|
110 } |
|
111 |
|
112 static inline bool IsLocalPlayer() |
|
113 { |
|
114 return _local_player == _current_player; |
|
115 } |
|
116 |
|
117 static inline bool IsValidPlayer(PlayerID pi) |
|
118 { |
|
119 return IsInsideBS(pi, PLAYER_FIRST, MAX_PLAYERS); |
|
120 } |
|
121 |
|
122 byte GetPlayerRailtypes(PlayerID p); |
|
123 byte GetPlayerRoadtypes(PlayerID p); |
|
124 |
|
125 /** Finds out if a Player has a certain railtype available |
|
126 * @param p Player in question |
|
127 * @param Railtype requested RailType |
|
128 * @return true if player has requested RailType available |
|
129 */ |
|
130 static inline bool HasRailtypeAvail(const Player *p, const RailType Railtype) |
|
131 { |
|
132 return HasBit(p->avail_railtypes, Railtype); |
|
133 } |
|
134 |
|
135 /** Finds out, whether given player has all given RoadTypes available |
|
136 * @param PlayerID ID of player |
|
137 * @param rts RoadTypes to test |
|
138 * @return true if player has all requested RoadTypes available |
|
139 */ |
|
140 static inline bool HasRoadTypesAvail(const PlayerID p, const RoadTypes rts) |
|
141 { |
|
142 RoadTypes avail_roadtypes; |
|
143 |
|
144 if (p == OWNER_TOWN || _game_mode == GM_EDITOR || IsGeneratingWorld()) { |
|
145 avail_roadtypes = ROADTYPES_ROAD; |
|
146 } else { |
|
147 if (!IsValidPlayer(p)) return false; |
|
148 avail_roadtypes = (RoadTypes)GetPlayer(p)->avail_roadtypes | ROADTYPES_ROAD; // road is available for always for everybody |
|
149 } |
|
150 return (rts & ~avail_roadtypes) == 0; |
|
151 } |
|
152 |
|
153 static inline bool IsHumanPlayer(PlayerID pi) |
|
154 { |
|
155 return !GetPlayer(pi)->is_ai; |
|
156 } |
|
157 |
|
158 static inline bool IsInteractivePlayer(PlayerID pi) |
|
159 { |
|
160 return pi == _local_player; |
|
161 } |
|
162 |
|
163 void DrawPlayerIcon(PlayerID p, int x, int y); |
|
164 |
|
165 /* Validate functions for rail building */ |
|
166 static inline bool ValParamRailtype(const uint32 rail) { return HasBit(GetPlayer(_current_player)->avail_railtypes, rail);} |
|
167 |
|
168 /* Validate functions for road building */ |
|
169 static inline bool ValParamRoadType(const RoadType rt) { return HasRoadTypesAvail(_current_player, RoadTypeToRoadTypes(rt));} |
|
170 |
|
171 /** Returns the "best" railtype a player can build. |
|
172 * As the AI doesn't know what the BEST one is, we have our own priority list |
|
173 * here. When adding new railtypes, modify this function |
|
174 * @param p the player "in action" |
|
175 * @return The "best" railtype a player has available |
|
176 */ |
|
177 static inline RailType GetBestRailtype(const Player *p) |
|
178 { |
|
179 if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV; |
|
180 if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO; |
|
181 if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC; |
|
182 return RAILTYPE_RAIL; |
|
183 } |
|
184 |
|
185 struct HighScore { |
|
186 char company[100]; |
|
187 StringID title; ///< NO_SAVE, has troubles with changing string-numbers. |
|
188 uint16 score; ///< do NOT change type, will break hs.dat |
|
189 }; |
|
190 |
|
191 VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5 |
|
192 void SaveToHighScore(); |
|
193 void LoadFromHighScore(); |
|
194 int8 SaveHighScoreValue(const Player *p); |
|
195 int8 SaveHighScoreValueNetwork(); |
|
196 |
|
197 /** |
|
198 * Reset the livery schemes to the player's primary colour. |
|
199 * This is used on loading games without livery information and on new player start up. |
|
200 * @param p Player to reset. |
|
201 */ |
|
202 void ResetPlayerLivery(Player *p); |
|
203 |
|
204 #endif /* PLAYER_H */ |
|