23 #include "player_gui.h" |
23 #include "player_gui.h" |
24 #include "settings_type.h" |
24 #include "settings_type.h" |
25 |
25 |
26 #include "table/strings.h" |
26 #include "table/strings.h" |
27 |
27 |
28 /** Change the player's face. |
28 /** Change the company manager's face. |
29 * @param tile unused |
29 * @param tile unused |
30 * @param flags operation to perform |
30 * @param flags operation to perform |
31 * @param p1 unused |
31 * @param p1 unused |
32 * @param p2 face bitmasked |
32 * @param p2 face bitmasked |
33 */ |
33 */ |
34 CommandCost CmdSetPlayerFace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
34 CommandCost CmdSetCompanyManagerFace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
35 { |
35 { |
36 PlayerFace pf = (PlayerFace)p2; |
36 CompanyManagerFace cmf = (CompanyManagerFace)p2; |
37 |
37 |
38 if (!IsValidPlayerIDFace(pf)) return CMD_ERROR; |
38 if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR; |
39 |
39 |
40 if (flags & DC_EXEC) { |
40 if (flags & DC_EXEC) { |
41 GetPlayer(_current_player)->face = pf; |
41 GetCompany(_current_company)->face = cmf; |
42 MarkWholeScreenDirty(); |
42 MarkWholeScreenDirty(); |
43 } |
43 } |
44 return CommandCost(); |
44 return CommandCost(); |
45 } |
45 } |
46 |
46 |
47 /** Change the player's company-colour |
47 /** Change the company's company-colour |
48 * @param tile unused |
48 * @param tile unused |
49 * @param flags operation to perform |
49 * @param flags operation to perform |
50 * @param p1 bitstuffed: |
50 * @param p1 bitstuffed: |
51 * p1 bits 0-7 scheme to set |
51 * p1 bits 0-7 scheme to set |
52 * p1 bits 8-9 set in use state or first/second colour |
52 * p1 bits 8-9 set in use state or first/second colour |
53 * @param p2 new colour for vehicles, property, etc. |
53 * @param p2 new colour for vehicles, property, etc. |
54 */ |
54 */ |
55 CommandCost CmdSetPlayerColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
55 CommandCost CmdSetCompanyColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
56 { |
56 { |
57 if (p2 >= 16) return CMD_ERROR; // max 16 colours |
57 if (p2 >= 16) return CMD_ERROR; // max 16 colours |
58 |
58 |
59 byte colour = p2; |
59 byte colour = p2; |
60 |
60 |
61 LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8); |
61 LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8); |
62 byte state = GB(p1, 8, 2); |
62 byte state = GB(p1, 8, 2); |
63 |
63 |
64 if (scheme >= LS_END || state >= 3) return CMD_ERROR; |
64 if (scheme >= LS_END || state >= 3) return CMD_ERROR; |
65 |
65 |
66 Player *p = GetPlayer(_current_player); |
66 Company *c = GetCompany(_current_company); |
67 |
67 |
68 /* Ensure no two companies have the same primary colour */ |
68 /* Ensure no two companies have the same primary colour */ |
69 if (scheme == LS_DEFAULT && state == 0) { |
69 if (scheme == LS_DEFAULT && state == 0) { |
70 const Player *pp; |
70 const Company *cc; |
71 FOR_ALL_PLAYERS(pp) { |
71 FOR_ALL_COMPANIES(cc) { |
72 if (pp != p && pp->player_color == colour) return CMD_ERROR; |
72 if (cc != c && cc->colour == colour) return CMD_ERROR; |
73 } |
73 } |
74 } |
74 } |
75 |
75 |
76 if (flags & DC_EXEC) { |
76 if (flags & DC_EXEC) { |
77 switch (state) { |
77 switch (state) { |
78 case 0: |
78 case 0: |
79 p->livery[scheme].colour1 = colour; |
79 c->livery[scheme].colour1 = colour; |
80 |
80 |
81 /* If setting the first colour of the default scheme, adjust the |
81 /* If setting the first colour of the default scheme, adjust the |
82 * original and cached player colours too. */ |
82 * original and cached company colours too. */ |
83 if (scheme == LS_DEFAULT) { |
83 if (scheme == LS_DEFAULT) { |
84 _player_colors[_current_player] = colour; |
84 _company_colours[_current_company] = colour; |
85 p->player_color = colour; |
85 c->colour = colour; |
86 } |
86 } |
87 break; |
87 break; |
88 |
88 |
89 case 1: |
89 case 1: |
90 p->livery[scheme].colour2 = colour; |
90 c->livery[scheme].colour2 = colour; |
91 break; |
91 break; |
92 |
92 |
93 case 2: |
93 case 2: |
94 p->livery[scheme].in_use = colour != 0; |
94 c->livery[scheme].in_use = colour != 0; |
95 |
95 |
96 /* Now handle setting the default scheme's in_use flag. |
96 /* Now handle setting the default scheme's in_use flag. |
97 * This is different to the other schemes, as it signifies if any |
97 * This is different to the other schemes, as it signifies if any |
98 * scheme is active at all. If this flag is not set, then no |
98 * scheme is active at all. If this flag is not set, then no |
99 * processing of vehicle types occurs at all, and only the default |
99 * processing of vehicle types occurs at all, and only the default |
100 * colours will be used. */ |
100 * colours will be used. */ |
101 |
101 |
102 /* If enabling a scheme, set the default scheme to be in use too */ |
102 /* If enabling a scheme, set the default scheme to be in use too */ |
103 if (colour != 0) { |
103 if (colour != 0) { |
104 p->livery[LS_DEFAULT].in_use = true; |
104 c->livery[LS_DEFAULT].in_use = true; |
105 break; |
105 break; |
106 } |
106 } |
107 |
107 |
108 /* Else loop through all schemes to see if any are left enabled. |
108 /* Else loop through all schemes to see if any are left enabled. |
109 * If not, disable the default scheme too. */ |
109 * If not, disable the default scheme too. */ |
110 p->livery[LS_DEFAULT].in_use = false; |
110 c->livery[LS_DEFAULT].in_use = false; |
111 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { |
111 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { |
112 if (p->livery[scheme].in_use) { |
112 if (c->livery[scheme].in_use) { |
113 p->livery[LS_DEFAULT].in_use = true; |
113 c->livery[LS_DEFAULT].in_use = true; |
114 break; |
114 break; |
115 } |
115 } |
116 } |
116 } |
117 break; |
117 break; |
118 |
118 |
132 * @param p2 when 0: loans LOAN_INTERVAL |
132 * @param p2 when 0: loans LOAN_INTERVAL |
133 * when 1: loans the maximum loan permitting money (press CTRL), |
133 * when 1: loans the maximum loan permitting money (press CTRL), |
134 */ |
134 */ |
135 CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
135 CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
136 { |
136 { |
137 Player *p = GetPlayer(_current_player); |
137 Company *c = GetCompany(_current_company); |
138 |
138 |
139 if (p->current_loan >= _economy.max_loan) { |
139 if (c->current_loan >= _economy.max_loan) { |
140 SetDParam(0, _economy.max_loan); |
140 SetDParam(0, _economy.max_loan); |
141 return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN); |
141 return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN); |
142 } |
142 } |
143 |
143 |
144 Money loan; |
144 Money loan; |
145 switch (p2) { |
145 switch (p2) { |
146 default: return CMD_ERROR; // Invalid method |
146 default: return CMD_ERROR; // Invalid method |
147 case 0: // Take some extra loan |
147 case 0: // Take some extra loan |
148 loan = (IsHumanPlayer(_current_player) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI; |
148 loan = (IsHumanCompany(_current_company) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI; |
149 break; |
149 break; |
150 case 1: // Take a loan as big as possible |
150 case 1: // Take a loan as big as possible |
151 loan = _economy.max_loan - p->current_loan; |
151 loan = _economy.max_loan - c->current_loan; |
152 break; |
152 break; |
153 } |
153 } |
154 |
154 |
155 /* Overflow protection */ |
155 /* Overflow protection */ |
156 if (p->player_money + p->current_loan + loan < p->player_money) return CMD_ERROR; |
156 if (c->money + c->current_loan + loan < c->money) return CMD_ERROR; |
157 |
157 |
158 if (flags & DC_EXEC) { |
158 if (flags & DC_EXEC) { |
159 p->player_money += loan; |
159 c->money += loan; |
160 p->current_loan += loan; |
160 c->current_loan += loan; |
161 InvalidatePlayerWindows(p); |
161 InvalidateCompanyWindows(c); |
162 } |
162 } |
163 |
163 |
164 return CommandCost(EXPENSES_OTHER); |
164 return CommandCost(EXPENSES_OTHER); |
165 } |
165 } |
166 |
166 |
171 * @param p2 when 0: pays back LOAN_INTERVAL |
171 * @param p2 when 0: pays back LOAN_INTERVAL |
172 * when 1: pays back the maximum loan permitting money (press CTRL), |
172 * when 1: pays back the maximum loan permitting money (press CTRL), |
173 */ |
173 */ |
174 CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
174 CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
175 { |
175 { |
176 Player *p = GetPlayer(_current_player); |
176 Company *c = GetCompany(_current_company); |
177 |
177 |
178 if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED); |
178 if (c->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED); |
179 |
179 |
180 Money loan; |
180 Money loan; |
181 switch (p2) { |
181 switch (p2) { |
182 default: return CMD_ERROR; // Invalid method |
182 default: return CMD_ERROR; // Invalid method |
183 case 0: // Pay back one step |
183 case 0: // Pay back one step |
184 loan = min(p->current_loan, (Money)(IsHumanPlayer(_current_player) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI); |
184 loan = min(c->current_loan, (Money)(IsHumanCompany(_current_company) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI); |
185 break; |
185 break; |
186 case 1: // Pay back as much as possible |
186 case 1: // Pay back as much as possible |
187 loan = max(min(p->current_loan, p->player_money), (Money)LOAN_INTERVAL); |
187 loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL); |
188 loan -= loan % LOAN_INTERVAL; |
188 loan -= loan % LOAN_INTERVAL; |
189 break; |
189 break; |
190 } |
190 } |
191 |
191 |
192 if (p->player_money < loan) { |
192 if (c->money < loan) { |
193 SetDParam(0, loan); |
193 SetDParam(0, loan); |
194 return_cmd_error(STR_702E_REQUIRED); |
194 return_cmd_error(STR_702E_REQUIRED); |
195 } |
195 } |
196 |
196 |
197 if (flags & DC_EXEC) { |
197 if (flags & DC_EXEC) { |
198 p->player_money -= loan; |
198 c->money -= loan; |
199 p->current_loan -= loan; |
199 c->current_loan -= loan; |
200 InvalidatePlayerWindows(p); |
200 InvalidateCompanyWindows(c); |
201 } |
201 } |
202 return CommandCost(); |
202 return CommandCost(); |
203 } |
203 } |
204 |
204 |
205 static bool IsUniqueCompanyName(const char *name) |
205 static bool IsUniqueCompanyName(const char *name) |
206 { |
206 { |
207 const Player *p; |
207 const Company *c; |
208 char buf[512]; |
208 char buf[512]; |
209 |
209 |
210 FOR_ALL_PLAYERS(p) { |
210 FOR_ALL_COMPANIES(c) { |
211 SetDParam(0, p->index); |
211 SetDParam(0, c->index); |
212 GetString(buf, STR_COMPANY_NAME, lastof(buf)); |
212 GetString(buf, STR_COMPANY_NAME, lastof(buf)); |
213 if (strcmp(buf, name) == 0) return false; |
213 if (strcmp(buf, name) == 0) return false; |
214 } |
214 } |
215 |
215 |
216 return true; |
216 return true; |
230 if (strlen(_cmd_text) >= MAX_LENGTH_COMPANY_NAME_BYTES) return CMD_ERROR; |
230 if (strlen(_cmd_text) >= MAX_LENGTH_COMPANY_NAME_BYTES) return CMD_ERROR; |
231 if (!IsUniqueCompanyName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE); |
231 if (!IsUniqueCompanyName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE); |
232 } |
232 } |
233 |
233 |
234 if (flags & DC_EXEC) { |
234 if (flags & DC_EXEC) { |
235 Player *p = GetPlayer(_current_player); |
235 Company *c = GetCompany(_current_company); |
236 free(p->name); |
236 free(c->name); |
237 p->name = reset ? NULL : strdup(_cmd_text); |
237 c->name = reset ? NULL : strdup(_cmd_text); |
238 MarkWholeScreenDirty(); |
238 MarkWholeScreenDirty(); |
239 } |
239 } |
240 |
240 |
241 return CommandCost(); |
241 return CommandCost(); |
242 } |
242 } |
243 |
243 |
244 static bool IsUniquePresidentName(const char *name) |
244 static bool IsUniquePresidentName(const char *name) |
245 { |
245 { |
246 const Player *p; |
246 const Company *c; |
247 char buf[512]; |
247 char buf[512]; |
248 |
248 |
249 FOR_ALL_PLAYERS(p) { |
249 FOR_ALL_COMPANIES(c) { |
250 SetDParam(0, p->index); |
250 SetDParam(0, c->index); |
251 GetString(buf, STR_PLAYER_NAME, lastof(buf)); |
251 GetString(buf, STR_PLAYER_NAME, lastof(buf)); |
252 if (strcmp(buf, name) == 0) return false; |
252 if (strcmp(buf, name) == 0) return false; |
253 } |
253 } |
254 |
254 |
255 return true; |
255 return true; |
269 if (strlen(_cmd_text) >= MAX_LENGTH_PRESIDENT_NAME_BYTES) return CMD_ERROR; |
269 if (strlen(_cmd_text) >= MAX_LENGTH_PRESIDENT_NAME_BYTES) return CMD_ERROR; |
270 if (!IsUniquePresidentName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE); |
270 if (!IsUniquePresidentName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE); |
271 } |
271 } |
272 |
272 |
273 if (flags & DC_EXEC) { |
273 if (flags & DC_EXEC) { |
274 Player *p = GetPlayer(_current_player); |
274 Company *c = GetCompany(_current_company); |
275 free(p->president_name); |
275 free(c->president_name); |
276 |
276 |
277 if (reset) { |
277 if (reset) { |
278 p->president_name = NULL; |
278 c->president_name = NULL; |
279 } else { |
279 } else { |
280 p->president_name = strdup(_cmd_text); |
280 c->president_name = strdup(_cmd_text); |
281 |
281 |
282 if (p->name_1 == STR_SV_UNNAMED && p->name == NULL) { |
282 if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) { |
283 char buf[80]; |
283 char buf[80]; |
284 |
284 |
285 snprintf(buf, lengthof(buf), "%s Transport", _cmd_text); |
285 snprintf(buf, lengthof(buf), "%s Transport", _cmd_text); |
286 _cmd_text = buf; |
286 _cmd_text = buf; |
287 DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY); |
287 DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY); |
356 if (_networking) return CMD_ERROR; |
356 if (_networking) return CMD_ERROR; |
357 #endif |
357 #endif |
358 return CommandCost(EXPENSES_OTHER, -(int32)p1); |
358 return CommandCost(EXPENSES_OTHER, -(int32)p1); |
359 } |
359 } |
360 |
360 |
361 /** Transfer funds (money) from one player to another. |
361 /** Transfer funds (money) from one company to another. |
362 * To prevent abuse in multiplayer games you can only send money to other |
362 * To prevent abuse in multiplayer games you can only send money to other |
363 * players if you have paid off your loan (either explicitely, or implicitely |
363 * companies if you have paid off your loan (either explicitely, or implicitely |
364 * given the fact that you have more money than loan). |
364 * given the fact that you have more money than loan). |
365 * @param tile unused |
365 * @param tile unused |
366 * @param flags operation to perform |
366 * @param flags operation to perform |
367 * @param p1 the amount of money to transfer; max 20.000.000 |
367 * @param p1 the amount of money to transfer; max 20.000.000 |
368 * @param p2 the player to transfer the money to |
368 * @param p2 the company to transfer the money to |
369 */ |
369 */ |
370 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
370 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
371 { |
371 { |
372 if (!_settings_game.economy.give_money) return CMD_ERROR; |
372 if (!_settings_game.economy.give_money) return CMD_ERROR; |
373 |
373 |
374 const Player *p = GetPlayer(_current_player); |
374 const Company *c = GetCompany(_current_company); |
375 CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL)); |
375 CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL)); |
376 |
376 |
377 /* You can only transfer funds that is in excess of your loan */ |
377 /* You can only transfer funds that is in excess of your loan */ |
378 if (p->player_money - p->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR; |
378 if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR; |
379 if (!_networking || !IsValidPlayerID((PlayerID)p2)) return CMD_ERROR; |
379 if (!_networking || !IsValidCompanyID((CompanyID)p2)) return CMD_ERROR; |
380 |
380 |
381 if (flags & DC_EXEC) { |
381 if (flags & DC_EXEC) { |
382 /* Add money to player */ |
382 /* Add money to company */ |
383 PlayerID old_cp = _current_player; |
383 CompanyID old_company = _current_company; |
384 _current_player = (PlayerID)p2; |
384 _current_company = (CompanyID)p2; |
385 SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, -amount.GetCost())); |
385 SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost())); |
386 _current_player = old_cp; |
386 _current_company = old_company; |
387 } |
387 } |
388 |
388 |
389 /* Subtract money from local-player */ |
389 /* Subtract money from local-company */ |
390 return amount; |
390 return amount; |
391 } |
391 } |