|
1 /* $Id$ */ |
|
2 |
|
3 #include "stdafx.h" |
|
4 #include "openttd.h" |
|
5 #include "table/sprites.h" |
|
6 #include "table/strings.h" |
|
7 #include "functions.h" |
|
8 #include "window.h" |
|
9 #include "gui.h" |
|
10 #include "viewport.h" |
|
11 #include "gfx.h" |
|
12 #include "player.h" |
|
13 #include "command.h" |
|
14 #include "vehicle.h" |
|
15 #include "economy.h" |
|
16 #include "network/network.h" |
|
17 #include "variables.h" |
|
18 #include "train.h" |
|
19 #include "date.h" |
|
20 #include "newgrf.h" |
|
21 #include "network/network_data.h" |
|
22 #include "network/network_client.h" |
|
23 |
|
24 static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied); |
|
25 |
|
26 static void DrawPlayerEconomyStats(const Player *p, byte mode) |
|
27 { |
|
28 int x,y,i,j,year; |
|
29 const int64 (*tbl)[13]; |
|
30 int64 sum, cost; |
|
31 StringID str; |
|
32 |
|
33 if (!(mode & 1)) { // normal sized economics window (mode&1) is minimized status |
|
34 /* draw categories */ |
|
35 DrawStringCenterUnderline(61, 15, STR_700F_EXPENDITURE_INCOME, 0); |
|
36 for (i = 0; i != 13; i++) |
|
37 DrawString(2, 27 + i*10, STR_7011_CONSTRUCTION + i, 0); |
|
38 DrawStringRightAligned(111, 27 + 10*13 + 2, STR_7020_TOTAL, 0); |
|
39 |
|
40 /* draw the price columns */ |
|
41 year = _cur_year - 2; |
|
42 j = 3; |
|
43 x = 215; |
|
44 tbl = p->yearly_expenses + 2; |
|
45 do { |
|
46 if (year >= p->inaugurated_year) { |
|
47 SetDParam(0, year); |
|
48 DrawStringRightAlignedUnderline(x, 15, STR_7010, 0); |
|
49 sum = 0; |
|
50 for (i = 0; i != 13; i++) { |
|
51 /* draw one row in the price column */ |
|
52 cost = (*tbl)[i]; |
|
53 if (cost != 0) { |
|
54 sum += cost; |
|
55 |
|
56 str = STR_701E; |
|
57 if (cost < 0) { cost = -cost; str++; } |
|
58 SetDParam64(0, cost); |
|
59 DrawStringRightAligned(x, 27+i*10, str, 0); |
|
60 } |
|
61 } |
|
62 |
|
63 str = STR_701E; |
|
64 if (sum < 0) { sum = -sum; str++; } |
|
65 SetDParam64(0, sum); |
|
66 DrawStringRightAligned(x, 27 + 13*10 + 2, str, 0); |
|
67 |
|
68 GfxFillRect(x - 75, 27 + 10*13, x, 27 + 10*13, 215); |
|
69 x += 95; |
|
70 } |
|
71 year++; |
|
72 tbl--; |
|
73 } while (--j != 0); |
|
74 |
|
75 y = 171; |
|
76 |
|
77 // draw max loan aligned to loan below (y += 10) |
|
78 SetDParam64(0, (uint64)_economy.max_loan); |
|
79 DrawString(202, y+10, STR_MAX_LOAN, 0); |
|
80 } else { |
|
81 y = 15; |
|
82 } |
|
83 |
|
84 DrawString(2, y, STR_7026_BANK_BALANCE, 0); |
|
85 SetDParam64(0, p->money64); |
|
86 DrawStringRightAligned(182, y, STR_7028, 0); |
|
87 |
|
88 y += 10; |
|
89 |
|
90 DrawString(2, y, STR_7027_LOAN, 0); |
|
91 SetDParam64(0, p->current_loan); |
|
92 DrawStringRightAligned(182, y, STR_7028, 0); |
|
93 |
|
94 y += 12; |
|
95 |
|
96 GfxFillRect(182 - 75, y-2, 182, y-2, 215); |
|
97 |
|
98 SetDParam64(0, p->money64 - p->current_loan); |
|
99 DrawStringRightAligned(182, y, STR_7028, 0); |
|
100 } |
|
101 |
|
102 static const Widget _player_finances_widgets[] = { |
|
103 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
104 { WWT_CAPTION, RESIZE_NONE, 14, 11, 379, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
105 { WWT_IMGBTN, RESIZE_NONE, 14, 380, 394, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW}, |
|
106 { WWT_STICKYBOX, RESIZE_NONE, 14, 395, 406, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
107 { WWT_PANEL, RESIZE_NONE, 14, 0, 406, 14, 169, 0x0, STR_NULL}, |
|
108 { WWT_PANEL, RESIZE_NONE, 14, 0, 406, 170, 203, 0x0, STR_NULL}, |
|
109 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 202, 204, 215, STR_7029_BORROW, STR_7035_INCREASE_SIZE_OF_LOAN}, |
|
110 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 203, 406, 204, 215, STR_702A_REPAY, STR_7036_REPAY_PART_OF_LOAN}, |
|
111 { WIDGETS_END}, |
|
112 }; |
|
113 |
|
114 static const Widget _other_player_finances_widgets[] = { |
|
115 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
116 { WWT_CAPTION, RESIZE_NONE, 14, 11, 379, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
117 { WWT_IMGBTN, RESIZE_NONE, 14, 380, 394, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW}, |
|
118 { WWT_STICKYBOX, RESIZE_NONE, 14, 395, 406, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
119 { WWT_PANEL, RESIZE_NONE, 14, 0, 406, 14, 169, 0x0, STR_NULL}, |
|
120 { WWT_PANEL, RESIZE_NONE, 14, 0, 406, 170, 203, 0x0, STR_NULL}, |
|
121 { WIDGETS_END}, |
|
122 }; |
|
123 |
|
124 static const Widget _other_player_finances_small_widgets[] = { |
|
125 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
126 { WWT_CAPTION, RESIZE_NONE, 14, 11, 253, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
127 { WWT_IMGBTN, RESIZE_NONE, 14, 254, 267, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW}, |
|
128 { WWT_STICKYBOX, RESIZE_NONE, 14, 268, 279, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
129 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
130 { WWT_PANEL, RESIZE_NONE, 14, 0, 279, 14, 47, 0x0, STR_NULL}, |
|
131 { WIDGETS_END}, |
|
132 }; |
|
133 |
|
134 static const Widget _player_finances_small_widgets[] = { |
|
135 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
136 { WWT_CAPTION, RESIZE_NONE, 14, 11, 253, 0, 13, STR_700E_FINANCES, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
137 { WWT_IMGBTN, RESIZE_NONE, 14, 254, 267, 0, 13, SPR_LARGE_SMALL_WINDOW, STR_7075_TOGGLE_LARGE_SMALL_WINDOW}, |
|
138 { WWT_STICKYBOX, RESIZE_NONE, 14, 268, 279, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
139 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
140 { WWT_PANEL, RESIZE_NONE, 14, 0, 279, 14, 47, STR_NULL, STR_NULL}, |
|
141 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 139, 48, 59, STR_7029_BORROW, STR_7035_INCREASE_SIZE_OF_LOAN}, |
|
142 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 140, 279, 48, 59, STR_702A_REPAY, STR_7036_REPAY_PART_OF_LOAN}, |
|
143 { WIDGETS_END}, |
|
144 }; |
|
145 |
|
146 |
|
147 static void PlayerFinancesWndProc(Window *w, WindowEvent *e) |
|
148 { |
|
149 switch (e->event) { |
|
150 case WE_PAINT: { |
|
151 PlayerID player = w->window_number; |
|
152 const Player *p = GetPlayer(player); |
|
153 |
|
154 if (player == _local_player) { |
|
155 /* borrow/repay buttons only exist for local player */ |
|
156 SetWindowWidgetDisabledState(w, 7, p->current_loan == 0); |
|
157 } |
|
158 |
|
159 SetDParam(0, p->name_1); |
|
160 SetDParam(1, p->name_2); |
|
161 SetDParam(2, GetPlayerNameString(player, 3)); |
|
162 SetDParam(4, 10000); |
|
163 DrawWindowWidgets(w); |
|
164 |
|
165 DrawPlayerEconomyStats(p, (byte)WP(w,def_d).data_1); |
|
166 } break; |
|
167 |
|
168 case WE_CLICK: |
|
169 switch (e->we.click.widget) { |
|
170 case 2: {/* toggle size */ |
|
171 byte mode = (byte)WP(w,def_d).data_1; |
|
172 bool stickied = !!(w->flags4 & WF_STICKY); |
|
173 PlayerID player = w->window_number; |
|
174 DeleteWindow(w); |
|
175 DoShowPlayerFinances(player, !HASBIT(mode, 0), stickied); |
|
176 } break; |
|
177 |
|
178 case 6: /* increase loan */ |
|
179 DoCommandP(0, 0, _ctrl_pressed, NULL, CMD_INCREASE_LOAN | CMD_MSG(STR_702C_CAN_T_BORROW_ANY_MORE_MONEY)); |
|
180 break; |
|
181 |
|
182 case 7: /* repay loan */ |
|
183 DoCommandP(0, 0, _ctrl_pressed, NULL, CMD_DECREASE_LOAN | CMD_MSG(STR_702F_CAN_T_REPAY_LOAN)); |
|
184 break; |
|
185 } |
|
186 break; |
|
187 } |
|
188 } |
|
189 |
|
190 static const WindowDesc _player_finances_desc = { |
|
191 WDP_AUTO, WDP_AUTO, 407, 216, |
|
192 WC_FINANCES,0, |
|
193 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, |
|
194 _player_finances_widgets, |
|
195 PlayerFinancesWndProc |
|
196 }; |
|
197 |
|
198 static const WindowDesc _player_finances_small_desc = { |
|
199 WDP_AUTO, WDP_AUTO, 280, 60, |
|
200 WC_FINANCES,0, |
|
201 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, |
|
202 _player_finances_small_widgets, |
|
203 PlayerFinancesWndProc |
|
204 }; |
|
205 |
|
206 static const WindowDesc _other_player_finances_desc = { |
|
207 WDP_AUTO, WDP_AUTO, 407, 204, |
|
208 WC_FINANCES,0, |
|
209 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, |
|
210 _other_player_finances_widgets, |
|
211 PlayerFinancesWndProc |
|
212 }; |
|
213 |
|
214 static const WindowDesc _other_player_finances_small_desc = { |
|
215 WDP_AUTO, WDP_AUTO, 280, 48, |
|
216 WC_FINANCES,0, |
|
217 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, |
|
218 _other_player_finances_small_widgets, |
|
219 PlayerFinancesWndProc |
|
220 }; |
|
221 |
|
222 static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied) |
|
223 { |
|
224 Window *w; |
|
225 int mode; |
|
226 |
|
227 static const WindowDesc * const desc_table[2 * 2] = { |
|
228 &_player_finances_desc, &_player_finances_small_desc, |
|
229 &_other_player_finances_desc, &_other_player_finances_small_desc, |
|
230 }; |
|
231 |
|
232 if (!IsValidPlayer(player)) return; |
|
233 |
|
234 mode = (player != _local_player) * 2 + show_small; |
|
235 w = AllocateWindowDescFront(desc_table[mode], player); |
|
236 if (w != NULL) { |
|
237 w->caption_color = w->window_number; |
|
238 WP(w,def_d).data_1 = mode; |
|
239 if (show_stickied) w->flags4 |= WF_STICKY; |
|
240 } |
|
241 } |
|
242 |
|
243 void ShowPlayerFinances(PlayerID player) |
|
244 { |
|
245 DoShowPlayerFinances(player, false, false); |
|
246 } |
|
247 |
|
248 /* List of colours for the livery window */ |
|
249 static const StringID _colour_dropdown[] = { |
|
250 STR_00D1_DARK_BLUE, |
|
251 STR_00D2_PALE_GREEN, |
|
252 STR_00D3_PINK, |
|
253 STR_00D4_YELLOW, |
|
254 STR_00D5_RED, |
|
255 STR_00D6_LIGHT_BLUE, |
|
256 STR_00D7_GREEN, |
|
257 STR_00D8_DARK_GREEN, |
|
258 STR_00D9_BLUE, |
|
259 STR_00DA_CREAM, |
|
260 STR_00DB_MAUVE, |
|
261 STR_00DC_PURPLE, |
|
262 STR_00DD_ORANGE, |
|
263 STR_00DE_BROWN, |
|
264 STR_00DF_GREY, |
|
265 STR_00E0_WHITE, |
|
266 INVALID_STRING_ID |
|
267 }; |
|
268 |
|
269 /* Association of liveries to livery classes */ |
|
270 static const LiveryClass livery_class[LS_END] = { |
|
271 LC_OTHER, |
|
272 LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, |
|
273 LC_ROAD, LC_ROAD, |
|
274 LC_SHIP, LC_SHIP, |
|
275 LC_AIRCRAFT, LC_AIRCRAFT, LC_AIRCRAFT, |
|
276 }; |
|
277 |
|
278 /* Number of liveries in each class, used to determine the height of the livery window */ |
|
279 static const byte livery_height[] = { |
|
280 1, |
|
281 11, |
|
282 2, |
|
283 2, |
|
284 3, |
|
285 }; |
|
286 |
|
287 typedef struct livery_d { |
|
288 uint32 sel; |
|
289 LiveryClass livery_class; |
|
290 } livery_d; |
|
291 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(livery_d)); |
|
292 |
|
293 static void ShowColourDropDownMenu(Window *w, uint32 widget) |
|
294 { |
|
295 uint32 used_colours = 0; |
|
296 const Livery *livery; |
|
297 LiveryScheme scheme; |
|
298 |
|
299 /* Disallow other player colours for the primary colour */ |
|
300 if (HASBIT(WP(w, livery_d).sel, LS_DEFAULT) && widget == 10) { |
|
301 const Player *p; |
|
302 FOR_ALL_PLAYERS(p) { |
|
303 if (p->is_active && p->index != _local_player) SETBIT(used_colours, p->player_color); |
|
304 } |
|
305 } |
|
306 |
|
307 /* Get the first selected livery to use as the default dropdown item */ |
|
308 for (scheme = 0; scheme < LS_END; scheme++) { |
|
309 if (HASBIT(WP(w, livery_d).sel, scheme)) break; |
|
310 } |
|
311 if (scheme == LS_END) scheme = LS_DEFAULT; |
|
312 livery = &GetPlayer(w->window_number)->livery[scheme]; |
|
313 |
|
314 ShowDropDownMenu(w, _colour_dropdown, widget == 10 ? livery->colour1 : livery->colour2, widget, used_colours, 0); |
|
315 } |
|
316 |
|
317 static void SelectPlayerLiveryWndProc(Window *w, WindowEvent *e) |
|
318 { |
|
319 switch (e->event) { |
|
320 case WE_CREATE: |
|
321 LowerWindowWidget(w, WP(w, livery_d).livery_class + 2); |
|
322 if (!_have_2cc) { |
|
323 HideWindowWidget(w, 11); |
|
324 HideWindowWidget(w, 12); |
|
325 } |
|
326 break; |
|
327 |
|
328 case WE_PAINT: { |
|
329 const Player *p = GetPlayer(w->window_number); |
|
330 LiveryScheme scheme = LS_DEFAULT; |
|
331 int y = 51; |
|
332 |
|
333 /* Disable dropdown controls if no scheme is selected */ |
|
334 SetWindowWidgetDisabledState(w, 9, (WP(w, livery_d).sel == 0)); |
|
335 SetWindowWidgetDisabledState(w, 10, (WP(w, livery_d).sel == 0)); |
|
336 SetWindowWidgetDisabledState(w, 11, (WP(w, livery_d).sel == 0)); |
|
337 SetWindowWidgetDisabledState(w, 12, (WP(w, livery_d).sel == 0)); |
|
338 |
|
339 if (!(WP(w, livery_d).sel == 0)) { |
|
340 for (scheme = 0; scheme < LS_END; scheme++) { |
|
341 if (HASBIT(WP(w, livery_d).sel, scheme)) break; |
|
342 } |
|
343 if (scheme == LS_END) scheme = LS_DEFAULT; |
|
344 } |
|
345 |
|
346 SetDParam(0, STR_00D1_DARK_BLUE + p->livery[scheme].colour1); |
|
347 SetDParam(1, STR_00D1_DARK_BLUE + p->livery[scheme].colour2); |
|
348 |
|
349 DrawWindowWidgets(w); |
|
350 |
|
351 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { |
|
352 if (livery_class[scheme] == WP(w, livery_d).livery_class) { |
|
353 bool sel = HASBIT(WP(w, livery_d).sel, scheme) != 0; |
|
354 |
|
355 if (scheme != LS_DEFAULT) { |
|
356 DrawSprite(p->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, 2, y); |
|
357 } |
|
358 |
|
359 DrawString(15, y, STR_LIVERY_DEFAULT + scheme, sel ? 0xC : 0x10); |
|
360 |
|
361 DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour1) | PALETTE_MODIFIER_COLOR, 152, y); |
|
362 DrawString(165, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour1, sel ? 0xC : 2); |
|
363 |
|
364 if (_have_2cc) { |
|
365 DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour2) | PALETTE_MODIFIER_COLOR, 277, y); |
|
366 DrawString(290, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour2, sel ? 0xC : 2); |
|
367 } |
|
368 |
|
369 y += 14; |
|
370 } |
|
371 } |
|
372 break; |
|
373 } |
|
374 |
|
375 case WE_CLICK: { |
|
376 switch (e->we.click.widget) { |
|
377 /* Livery Class buttons */ |
|
378 case 2: |
|
379 case 3: |
|
380 case 4: |
|
381 case 5: |
|
382 case 6: { |
|
383 LiveryScheme scheme; |
|
384 |
|
385 RaiseWindowWidget(w, WP(w, livery_d).livery_class + 2); |
|
386 WP(w, livery_d).livery_class = e->we.click.widget - 2; |
|
387 WP(w, livery_d).sel = 0; |
|
388 LowerWindowWidget(w, WP(w, livery_d).livery_class + 2); |
|
389 |
|
390 /* Select the first item in the list */ |
|
391 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { |
|
392 if (livery_class[scheme] == WP(w, livery_d).livery_class) { |
|
393 WP(w, livery_d).sel = 1 << scheme; |
|
394 break; |
|
395 } |
|
396 } |
|
397 w->height = 49 + livery_height[WP(w, livery_d).livery_class] * 14; |
|
398 w->widget[13].bottom = w->height - 1; |
|
399 w->widget[13].data = livery_height[WP(w, livery_d).livery_class] << 8 | 1; |
|
400 MarkWholeScreenDirty(); |
|
401 break; |
|
402 } |
|
403 |
|
404 case 9: |
|
405 case 10: // First colour dropdown |
|
406 ShowColourDropDownMenu(w, 10); |
|
407 break; |
|
408 |
|
409 case 11: |
|
410 case 12: // Second colour dropdown |
|
411 ShowColourDropDownMenu(w, 12); |
|
412 break; |
|
413 |
|
414 case 13: { |
|
415 LiveryScheme scheme; |
|
416 LiveryScheme j = (e->we.click.pt.y - 48) / 14; |
|
417 |
|
418 for (scheme = 0; scheme <= j; scheme++) { |
|
419 if (livery_class[scheme] != WP(w, livery_d).livery_class) j++; |
|
420 if (scheme >= LS_END) return; |
|
421 } |
|
422 if (j >= LS_END) return; |
|
423 |
|
424 /* If clicking on the left edge, toggle using the livery */ |
|
425 if (e->we.click.pt.x < 10) { |
|
426 DoCommandP(0, j | (2 << 8), !GetPlayer(w->window_number)->livery[j].in_use, NULL, CMD_SET_PLAYER_COLOR); |
|
427 } |
|
428 |
|
429 if (_ctrl_pressed) { |
|
430 TOGGLEBIT(WP(w, livery_d).sel, j); |
|
431 } else { |
|
432 WP(w, livery_d).sel = 1 << j; |
|
433 } |
|
434 SetWindowDirty(w); |
|
435 break; |
|
436 } |
|
437 } |
|
438 break; |
|
439 } |
|
440 |
|
441 case WE_DROPDOWN_SELECT: { |
|
442 LiveryScheme scheme; |
|
443 |
|
444 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { |
|
445 if (HASBIT(WP(w, livery_d).sel, scheme)) { |
|
446 DoCommandP(0, scheme | (e->we.dropdown.button == 10 ? 0 : 256), e->we.dropdown.index, NULL, CMD_SET_PLAYER_COLOR); |
|
447 } |
|
448 } |
|
449 break; |
|
450 } |
|
451 } |
|
452 } |
|
453 |
|
454 static const Widget _select_player_livery_2cc_widgets[] = { |
|
455 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW }, |
|
456 { WWT_CAPTION, RESIZE_NONE, 14, 11, 399, 0, 13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS }, |
|
457 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 14, 35, SPR_IMG_COMPANY_GENERAL, STR_LIVERY_GENERAL_TIP }, |
|
458 { WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 14, 35, SPR_IMG_TRAINLIST, STR_LIVERY_TRAIN_TIP }, |
|
459 { WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 14, 35, SPR_IMG_TRUCKLIST, STR_LIVERY_ROADVEH_TIP }, |
|
460 { WWT_IMGBTN, RESIZE_NONE, 14, 66, 87, 14, 35, SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TIP }, |
|
461 { WWT_IMGBTN, RESIZE_NONE, 14, 88, 109, 14, 35, SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TIP }, |
|
462 { WWT_PANEL, RESIZE_NONE, 14, 110, 399, 14, 35, 0x0, STR_NULL }, |
|
463 { WWT_PANEL, RESIZE_NONE, 14, 0, 149, 36, 47, 0x0, STR_NULL }, |
|
464 { WWT_TEXTBTN, RESIZE_NONE, 14, 150, 262, 36, 47, STR_02BD, STR_LIVERY_PRIMARY_TIP }, |
|
465 { WWT_TEXTBTN, RESIZE_NONE, 14, 263, 274, 36, 47, STR_0225, STR_LIVERY_PRIMARY_TIP }, |
|
466 { WWT_TEXTBTN, RESIZE_NONE, 14, 275, 387, 36, 47, STR_02E1, STR_LIVERY_SECONDARY_TIP }, |
|
467 { WWT_TEXTBTN, RESIZE_NONE, 14, 388, 399, 36, 47, STR_0225, STR_LIVERY_SECONDARY_TIP }, |
|
468 { WWT_MATRIX, RESIZE_NONE, 14, 0, 399, 48, 48 + 1 * 14, (1 << 8) | 1, STR_LIVERY_PANEL_TIP }, |
|
469 { WIDGETS_END }, |
|
470 }; |
|
471 |
|
472 static const WindowDesc _select_player_livery_2cc_desc = { |
|
473 WDP_AUTO, WDP_AUTO, 400, 49 + 1 * 14, |
|
474 WC_PLAYER_COLOR, 0, |
|
475 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
476 _select_player_livery_2cc_widgets, |
|
477 SelectPlayerLiveryWndProc |
|
478 }; |
|
479 |
|
480 |
|
481 static const Widget _select_player_livery_widgets[] = { |
|
482 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW }, |
|
483 { WWT_CAPTION, RESIZE_NONE, 14, 11, 274, 0, 13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS }, |
|
484 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 21, 14, 35, SPR_IMG_COMPANY_GENERAL, STR_LIVERY_GENERAL_TIP }, |
|
485 { WWT_IMGBTN, RESIZE_NONE, 14, 22, 43, 14, 35, SPR_IMG_TRAINLIST, STR_LIVERY_TRAIN_TIP }, |
|
486 { WWT_IMGBTN, RESIZE_NONE, 14, 44, 65, 14, 35, SPR_IMG_TRUCKLIST, STR_LIVERY_ROADVEH_TIP }, |
|
487 { WWT_IMGBTN, RESIZE_NONE, 14, 66, 87, 14, 35, SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TIP }, |
|
488 { WWT_IMGBTN, RESIZE_NONE, 14, 88, 109, 14, 35, SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TIP }, |
|
489 { WWT_PANEL, RESIZE_NONE, 14, 110, 274, 14, 35, 0x0, STR_NULL }, |
|
490 { WWT_PANEL, RESIZE_NONE, 14, 0, 149, 36, 47, 0x0, STR_NULL }, |
|
491 { WWT_TEXTBTN, RESIZE_NONE, 14, 150, 262, 36, 47, STR_02BD, STR_LIVERY_PRIMARY_TIP }, |
|
492 { WWT_TEXTBTN, RESIZE_NONE, 14, 263, 274, 36, 47, STR_0225, STR_LIVERY_PRIMARY_TIP }, |
|
493 { WWT_TEXTBTN, RESIZE_NONE, 14, 275, 275, 36, 47, STR_02E1, STR_LIVERY_SECONDARY_TIP }, |
|
494 { WWT_TEXTBTN, RESIZE_NONE, 14, 275, 275, 36, 47, STR_0225, STR_LIVERY_SECONDARY_TIP }, |
|
495 { WWT_MATRIX, RESIZE_NONE, 14, 0, 274, 48, 48 + 1 * 14, (1 << 8) | 1, STR_LIVERY_PANEL_TIP }, |
|
496 { WIDGETS_END }, |
|
497 }; |
|
498 |
|
499 static const WindowDesc _select_player_livery_desc = { |
|
500 WDP_AUTO, WDP_AUTO, 275, 49 + 1 * 14, |
|
501 WC_PLAYER_COLOR, 0, |
|
502 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
503 _select_player_livery_widgets, |
|
504 SelectPlayerLiveryWndProc |
|
505 }; |
|
506 |
|
507 static void SelectPlayerFaceWndProc(Window *w, WindowEvent *e) |
|
508 { |
|
509 switch (e->event) { |
|
510 case WE_PAINT: { |
|
511 Player *p; |
|
512 LowerWindowWidget(w, WP(w, facesel_d).gender + 5); |
|
513 DrawWindowWidgets(w); |
|
514 p = GetPlayer(w->window_number); |
|
515 DrawPlayerFace(WP(w,facesel_d).face, p->player_color, 2, 16); |
|
516 } break; |
|
517 |
|
518 case WE_CLICK: |
|
519 switch (e->we.click.widget) { |
|
520 case 3: DeleteWindow(w); break; |
|
521 case 4: /* ok click */ |
|
522 DoCommandP(0, 0, WP(w,facesel_d).face, NULL, CMD_SET_PLAYER_FACE); |
|
523 DeleteWindow(w); |
|
524 break; |
|
525 case 5: /* male click */ |
|
526 case 6: /* female click */ |
|
527 RaiseWindowWidget(w, WP(w, facesel_d).gender + 5); |
|
528 WP(w, facesel_d).gender = e->we.click.widget - 5; |
|
529 LowerWindowWidget(w, WP(w, facesel_d).gender + 5); |
|
530 SetWindowDirty(w); |
|
531 break; |
|
532 case 7: |
|
533 WP(w,facesel_d).face = (WP(w,facesel_d).gender << 31) + GB(InteractiveRandom(), 0, 31); |
|
534 SetWindowDirty(w); |
|
535 break; |
|
536 } |
|
537 break; |
|
538 } |
|
539 } |
|
540 |
|
541 static const Widget _select_player_face_widgets[] = { |
|
542 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
543 { WWT_CAPTION, RESIZE_NONE, 14, 11, 189, 0, 13, STR_7043_FACE_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
544 { WWT_PANEL, RESIZE_NONE, 14, 0, 189, 14, 136, 0x0, STR_NULL}, |
|
545 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 94, 137, 148, STR_012E_CANCEL, STR_7047_CANCEL_NEW_FACE_SELECTION}, |
|
546 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 95, 189, 137, 148, STR_012F_OK, STR_7048_ACCEPT_NEW_FACE_SELECTION}, |
|
547 { WWT_TEXTBTN, RESIZE_NONE, 14, 95, 187, 25, 36, STR_7044_MALE, STR_7049_SELECT_MALE_FACES}, |
|
548 { WWT_TEXTBTN, RESIZE_NONE, 14, 95, 187, 37, 48, STR_7045_FEMALE, STR_704A_SELECT_FEMALE_FACES}, |
|
549 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 95, 187, 79, 90, STR_7046_NEW_FACE, STR_704B_GENERATE_RANDOM_NEW_FACE}, |
|
550 { WIDGETS_END}, |
|
551 }; |
|
552 |
|
553 static const WindowDesc _select_player_face_desc = { |
|
554 WDP_AUTO, WDP_AUTO, 190, 149, |
|
555 WC_PLAYER_FACE,0, |
|
556 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
557 _select_player_face_widgets, |
|
558 SelectPlayerFaceWndProc |
|
559 }; |
|
560 |
|
561 /* Names of the widgets. Keep them in the same order as in the widget array */ |
|
562 enum PlayerCompanyWindowWidgets { |
|
563 PCW_WIDGET_CLOSEBOX = 0, |
|
564 PCW_WIDGET_CAPTION, |
|
565 PCW_WIDGET_FACE, |
|
566 PCW_WIDGET_NEW_FACE, |
|
567 PCW_WIDGET_COLOR_SCHEME, |
|
568 PCW_WIDGET_PRESIDENT_NAME, |
|
569 PCW_WIDGET_COMPANY_NAME, |
|
570 PCW_WIDGET_BUILD_VIEW_HQ, |
|
571 PCW_WIDGET_RELOCATE_HQ, |
|
572 PCW_WIDGET_BUY_SHARE, |
|
573 PCW_WIDGET_SELL_SHARE, |
|
574 PCW_WIDGET_COMPANY_PASSWORD, |
|
575 }; |
|
576 |
|
577 static const Widget _player_company_widgets[] = { |
|
578 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
579 { WWT_CAPTION, RESIZE_NONE, 14, 11, 359, 0, 13, STR_7001, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
580 { WWT_PANEL, RESIZE_NONE, 14, 0, 359, 14, 157, 0x0, STR_NULL}, |
|
581 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 89, 158, 169, STR_7004_NEW_FACE, STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT}, |
|
582 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 90, 179, 158, 169, STR_7005_COLOR_SCHEME, STR_7031_CHANGE_THE_COMPANY_VEHICLE}, |
|
583 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 180, 269, 158, 169, STR_7009_PRESIDENT_NAME, STR_7032_CHANGE_THE_PRESIDENT_S}, |
|
584 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 270, 359, 158, 169, STR_7008_COMPANY_NAME, STR_7033_CHANGE_THE_COMPANY_NAME}, |
|
585 { WWT_TEXTBTN, RESIZE_NONE, 14, 266, 355, 18, 29, STR_7072_VIEW_HQ, STR_7070_BUILD_COMPANY_HEADQUARTERS}, |
|
586 { WWT_TEXTBTN, RESIZE_NONE, 14, 266, 355, 32, 43, STR_RELOCATE_HQ, STR_RELOCATE_COMPANY_HEADQUARTERS}, |
|
587 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 179, 158, 169, STR_7077_BUY_25_SHARE_IN_COMPANY, STR_7079_BUY_25_SHARE_IN_THIS_COMPANY}, |
|
588 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 180, 359, 158, 169, STR_7078_SELL_25_SHARE_IN_COMPANY, STR_707A_SELL_25_SHARE_IN_THIS_COMPANY}, |
|
589 { WWT_PUSHTXTBTN, RESIZE_NONE, 14, 266, 355, 138, 149, STR_COMPANY_PASSWORD, STR_COMPANY_PASSWORD_TOOLTIP}, |
|
590 { WIDGETS_END}, |
|
591 }; |
|
592 |
|
593 static void DrawPlayerVehiclesAmount(PlayerID player) |
|
594 { |
|
595 const int x = 110; |
|
596 int y = 72; |
|
597 const Vehicle *v; |
|
598 uint train = 0; |
|
599 uint road = 0; |
|
600 uint air = 0; |
|
601 uint ship = 0; |
|
602 |
|
603 DrawString(x, y, STR_7039_VEHICLES, 0); |
|
604 |
|
605 FOR_ALL_VEHICLES(v) { |
|
606 if (v->owner == player) { |
|
607 switch (v->type) { |
|
608 case VEH_Train: if (IsFrontEngine(v)) train++; break; |
|
609 case VEH_Road: road++; break; |
|
610 case VEH_Aircraft: if (v->subtype <= 2) air++; break; |
|
611 case VEH_Ship: ship++; break; |
|
612 default: break; |
|
613 } |
|
614 } |
|
615 } |
|
616 |
|
617 if (train+road+air+ship == 0) { |
|
618 DrawString(x+70, y, STR_7042_NONE, 0); |
|
619 } else { |
|
620 if (train != 0) { |
|
621 SetDParam(0, train); |
|
622 DrawString(x + 70, y, STR_TRAINS, 0); |
|
623 y += 10; |
|
624 } |
|
625 |
|
626 if (road != 0) { |
|
627 SetDParam(0, road); |
|
628 DrawString(x + 70, y, STR_ROAD_VEHICLES, 0); |
|
629 y += 10; |
|
630 } |
|
631 |
|
632 if (air != 0) { |
|
633 SetDParam(0, air); |
|
634 DrawString(x + 70, y, STR_AIRCRAFT, 0); |
|
635 y += 10; |
|
636 } |
|
637 |
|
638 if (ship != 0) { |
|
639 SetDParam(0, ship); |
|
640 DrawString(x + 70, y, STR_SHIPS, 0); |
|
641 } |
|
642 } |
|
643 } |
|
644 |
|
645 int GetAmountOwnedBy(const Player *p, PlayerID owner) |
|
646 { |
|
647 return (p->share_owners[0] == owner) + |
|
648 (p->share_owners[1] == owner) + |
|
649 (p->share_owners[2] == owner) + |
|
650 (p->share_owners[3] == owner); |
|
651 } |
|
652 |
|
653 static void DrawCompanyOwnerText(const Player *p) |
|
654 { |
|
655 const Player *p2; |
|
656 int num = -1; |
|
657 |
|
658 FOR_ALL_PLAYERS(p2) { |
|
659 uint amt = GetAmountOwnedBy(p, p2->index); |
|
660 if (amt != 0) { |
|
661 num++; |
|
662 |
|
663 SetDParam(num * 3 + 0, amt * 25); |
|
664 SetDParam(num * 3 + 1, p2->name_1); |
|
665 SetDParam(num * 3 + 2, p2->name_2); |
|
666 |
|
667 if (num != 0) break; |
|
668 } |
|
669 } |
|
670 |
|
671 if (num >= 0) DrawString(120, 124, STR_707D_OWNED_BY + num, 0); |
|
672 } |
|
673 |
|
674 static void PlayerCompanyWndProc(Window *w, WindowEvent *e) |
|
675 { |
|
676 switch (e->event) { |
|
677 case WE_PAINT: { |
|
678 const Player *p = GetPlayer(w->window_number); |
|
679 bool local = w->window_number == _local_player; |
|
680 |
|
681 SetWindowWidgetHiddenState(w, PCW_WIDGET_NEW_FACE, !local); |
|
682 SetWindowWidgetHiddenState(w, PCW_WIDGET_COLOR_SCHEME, !local); |
|
683 SetWindowWidgetHiddenState(w, PCW_WIDGET_PRESIDENT_NAME, !local); |
|
684 SetWindowWidgetHiddenState(w, PCW_WIDGET_COMPANY_NAME, !local); |
|
685 w->widget[PCW_WIDGET_BUILD_VIEW_HQ].data = (local && p->location_of_house == 0) ? STR_706F_BUILD_HQ : STR_7072_VIEW_HQ; |
|
686 if (local && p->location_of_house != 0) w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; //HQ is already built. |
|
687 SetWindowWidgetDisabledState(w, PCW_WIDGET_BUILD_VIEW_HQ, !local && p->location_of_house == 0); |
|
688 SetWindowWidgetHiddenState(w, PCW_WIDGET_RELOCATE_HQ, !local || p->location_of_house == 0); |
|
689 SetWindowWidgetHiddenState(w, PCW_WIDGET_BUY_SHARE, local); |
|
690 SetWindowWidgetHiddenState(w, PCW_WIDGET_SELL_SHARE, local); |
|
691 SetWindowWidgetHiddenState(w, PCW_WIDGET_COMPANY_PASSWORD, !local || !_networking); |
|
692 |
|
693 if (!local) { |
|
694 if (_patches.allow_shares) { // Shares are allowed |
|
695 /* If all shares are owned by someone (none by nobody), disable buy button */ |
|
696 SetWindowWidgetDisabledState(w, PCW_WIDGET_BUY_SHARE, GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0 || |
|
697 /* Only 25% left to buy. If the player is human, disable buying it up.. TODO issues! */ |
|
698 (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) || |
|
699 /* Spectators cannot do anything of course */ |
|
700 _local_player == PLAYER_SPECTATOR); |
|
701 |
|
702 /* If the player doesn't own any shares, disable sell button */ |
|
703 SetWindowWidgetDisabledState(w, PCW_WIDGET_SELL_SHARE, (GetAmountOwnedBy(p, _local_player) == 0) || |
|
704 /* Spectators cannot do anything of course */ |
|
705 _local_player == PLAYER_SPECTATOR); |
|
706 } else { // Shares are not allowed, disable buy/sell buttons |
|
707 DisableWindowWidget(w, PCW_WIDGET_BUY_SHARE); |
|
708 DisableWindowWidget(w, PCW_WIDGET_SELL_SHARE); |
|
709 } |
|
710 } |
|
711 |
|
712 SetDParam(0, p->name_1); |
|
713 SetDParam(1, p->name_2); |
|
714 SetDParam(2, GetPlayerNameString((byte)w->window_number, 3)); |
|
715 |
|
716 DrawWindowWidgets(w); |
|
717 |
|
718 SetDParam(0, p->inaugurated_year); |
|
719 DrawString(110, 25, STR_7038_INAUGURATED, 0); |
|
720 |
|
721 DrawPlayerVehiclesAmount(w->window_number); |
|
722 |
|
723 DrawString(110,48, STR_7006_COLOR_SCHEME, 0); |
|
724 // Draw company-colour bus |
|
725 DrawSprite(PLAYER_SPRITE_COLOR(p->index) + SPRITE_PALETTE(SPR_VEH_BUS_SW_VIEW), 215, 49); |
|
726 |
|
727 DrawPlayerFace(p->face, p->player_color, 2, 16); |
|
728 |
|
729 SetDParam(0, p->president_name_1); |
|
730 SetDParam(1, p->president_name_2); |
|
731 DrawStringMultiCenter(48, 141, STR_7037_PRESIDENT, 94); |
|
732 |
|
733 SetDParam64(0, CalculateCompanyValue(p)); |
|
734 DrawString(110, 114, STR_7076_COMPANY_VALUE, 0); |
|
735 |
|
736 DrawCompanyOwnerText(p); |
|
737 |
|
738 break; |
|
739 } |
|
740 |
|
741 case WE_CLICK: |
|
742 switch (e->we.click.widget) { |
|
743 case PCW_WIDGET_NEW_FACE: { |
|
744 Window *wf = AllocateWindowDescFront(&_select_player_face_desc, w->window_number); |
|
745 if (wf != NULL) { |
|
746 wf->caption_color = w->window_number; |
|
747 WP(wf,facesel_d).face = GetPlayer(wf->window_number)->face; |
|
748 WP(wf,facesel_d).gender = 0; |
|
749 } |
|
750 break; |
|
751 } |
|
752 |
|
753 case PCW_WIDGET_COLOR_SCHEME: { |
|
754 Window *wf = AllocateWindowDescFront(_have_2cc ? &_select_player_livery_2cc_desc : &_select_player_livery_desc, w->window_number); |
|
755 if (wf != NULL) { |
|
756 wf->caption_color = wf->window_number; |
|
757 WP(wf,livery_d).livery_class = LC_OTHER; |
|
758 WP(wf,livery_d).sel = 1; |
|
759 LowerWindowWidget(wf, 2); |
|
760 } |
|
761 break; |
|
762 } |
|
763 |
|
764 case PCW_WIDGET_PRESIDENT_NAME: { |
|
765 const Player *p = GetPlayer(w->window_number); |
|
766 WP(w, def_d).byte_1 = 0; |
|
767 SetDParam(0, p->president_name_2); |
|
768 ShowQueryString(p->president_name_1, STR_700B_PRESIDENT_S_NAME, 31, 94, w, CS_ALPHANUMERAL); |
|
769 break; |
|
770 } |
|
771 |
|
772 case PCW_WIDGET_COMPANY_NAME: { |
|
773 Player *p = GetPlayer(w->window_number); |
|
774 WP(w,def_d).byte_1 = 1; |
|
775 SetDParam(0, p->name_2); |
|
776 ShowQueryString(p->name_1, STR_700A_COMPANY_NAME, 31, 150, w, CS_ALPHANUMERAL); |
|
777 break; |
|
778 } |
|
779 |
|
780 case PCW_WIDGET_BUILD_VIEW_HQ: { |
|
781 TileIndex tile = GetPlayer(w->window_number)->location_of_house; |
|
782 if (tile == 0) { |
|
783 if ((byte)w->window_number != _local_player) |
|
784 return; |
|
785 SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w); |
|
786 SetTileSelectSize(2, 2); |
|
787 LowerWindowWidget(w, PCW_WIDGET_BUILD_VIEW_HQ); |
|
788 InvalidateWidget(w, PCW_WIDGET_BUILD_VIEW_HQ); |
|
789 } else { |
|
790 ScrollMainWindowToTile(tile); |
|
791 } |
|
792 break; |
|
793 } |
|
794 |
|
795 case PCW_WIDGET_RELOCATE_HQ: |
|
796 SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w); |
|
797 SetTileSelectSize(2, 2); |
|
798 LowerWindowWidget(w, PCW_WIDGET_RELOCATE_HQ); |
|
799 InvalidateWidget(w, PCW_WIDGET_RELOCATE_HQ); |
|
800 break; |
|
801 |
|
802 case PCW_WIDGET_BUY_SHARE: |
|
803 DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_707B_CAN_T_BUY_25_SHARE_IN_THIS)); |
|
804 break; |
|
805 |
|
806 case PCW_WIDGET_SELL_SHARE: |
|
807 DoCommandP(0, w->window_number, 0, NULL, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_707C_CAN_T_SELL_25_SHARE_IN)); |
|
808 break; |
|
809 |
|
810 #ifdef ENABLE_NETWORK |
|
811 case PCW_WIDGET_COMPANY_PASSWORD: |
|
812 if (w->window_number == _local_player) { |
|
813 WP(w,def_d).byte_1 = 2; |
|
814 ShowQueryString(BindCString(_network_player_info[_local_player].password), |
|
815 STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w, CS_ALPHANUMERAL); |
|
816 } |
|
817 break; |
|
818 #endif /* ENABLE_NETWORK */ |
|
819 } |
|
820 break; |
|
821 |
|
822 case WE_MOUSELOOP: |
|
823 /* redraw the window every now and then */ |
|
824 if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w); |
|
825 break; |
|
826 |
|
827 case WE_PLACE_OBJ: |
|
828 if (DoCommandP(e->we.place.tile, 0, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS))) |
|
829 ResetObjectToPlace(); |
|
830 w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; // this button can now behave as a normal push button |
|
831 RaiseWindowButtons(w); |
|
832 break; |
|
833 |
|
834 case WE_ABORT_PLACE_OBJ: |
|
835 RaiseWindowButtons(w); |
|
836 break; |
|
837 |
|
838 case WE_DESTROY: |
|
839 DeleteWindowById(WC_PLAYER_FACE, w->window_number); |
|
840 break; |
|
841 |
|
842 case WE_ON_EDIT_TEXT: { |
|
843 char *b = e->we.edittext.str; |
|
844 |
|
845 // empty string is allowed for password |
|
846 if (*b == '\0' && WP(w,def_d).byte_1 != 2) return; |
|
847 |
|
848 _cmd_text = b; |
|
849 switch (WP(w,def_d).byte_1) { |
|
850 case 0: /* Change president name */ |
|
851 DoCommandP(0, 0, 0, NULL, CMD_CHANGE_PRESIDENT_NAME | CMD_MSG(STR_700D_CAN_T_CHANGE_PRESIDENT)); |
|
852 break; |
|
853 case 1: /* Change company name */ |
|
854 DoCommandP(0, 0, 0, NULL, CMD_CHANGE_COMPANY_NAME | CMD_MSG(STR_700C_CAN_T_CHANGE_COMPANY_NAME)); |
|
855 break; |
|
856 #ifdef ENABLE_NETWORK |
|
857 case 2: /* Change company password */ |
|
858 if (*b == '\0') *b = '*'; // empty password is a '*' because of console argument |
|
859 NetworkChangeCompanyPassword(1, &b); |
|
860 break; |
|
861 #endif /* ENABLE_NETWORK */ |
|
862 } |
|
863 break; |
|
864 } |
|
865 } |
|
866 } |
|
867 |
|
868 |
|
869 static const WindowDesc _player_company_desc = { |
|
870 WDP_AUTO, WDP_AUTO, 360, 170, |
|
871 WC_COMPANY, 0, |
|
872 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
873 _player_company_widgets, |
|
874 PlayerCompanyWndProc |
|
875 }; |
|
876 |
|
877 void ShowPlayerCompany(PlayerID player) |
|
878 { |
|
879 Window *w; |
|
880 |
|
881 if (!IsValidPlayer(player)) return; |
|
882 |
|
883 w = AllocateWindowDescFront(&_player_company_desc, player); |
|
884 if (w != NULL) w->caption_color = w->window_number; |
|
885 } |
|
886 |
|
887 |
|
888 |
|
889 static void BuyCompanyWndProc(Window *w, WindowEvent *e) |
|
890 { |
|
891 switch (e->event) { |
|
892 case WE_PAINT: { |
|
893 Player *p = GetPlayer(w->window_number); |
|
894 SetDParam(0, p->name_1); |
|
895 SetDParam(1, p->name_2); |
|
896 DrawWindowWidgets(w); |
|
897 |
|
898 DrawPlayerFace(p->face, p->player_color, 2, 16); |
|
899 |
|
900 SetDParam(0, p->name_1); |
|
901 SetDParam(1, p->name_2); |
|
902 SetDParam(2, p->bankrupt_value); |
|
903 DrawStringMultiCenter(214, 65, STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT, 238); |
|
904 break; |
|
905 } |
|
906 |
|
907 case WE_CLICK: |
|
908 switch (e->we.click.widget) { |
|
909 case 3: |
|
910 DeleteWindow(w); |
|
911 break; |
|
912 case 4: { |
|
913 DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_COMPANY | CMD_MSG(STR_7060_CAN_T_BUY_COMPANY)); |
|
914 break; |
|
915 } |
|
916 } |
|
917 break; |
|
918 } |
|
919 } |
|
920 |
|
921 static const Widget _buy_company_widgets[] = { |
|
922 { WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
923 { WWT_CAPTION, RESIZE_NONE, 5, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
924 { WWT_PANEL, RESIZE_NONE, 5, 0, 333, 14, 136, 0x0, STR_NULL}, |
|
925 { WWT_TEXTBTN, RESIZE_NONE, 5, 148, 207, 117, 128, STR_00C9_NO, STR_NULL}, |
|
926 { WWT_TEXTBTN, RESIZE_NONE, 5, 218, 277, 117, 128, STR_00C8_YES, STR_NULL}, |
|
927 { WIDGETS_END}, |
|
928 }; |
|
929 |
|
930 static const WindowDesc _buy_company_desc = { |
|
931 153, 171, 334, 137, |
|
932 WC_BUY_COMPANY,0, |
|
933 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
934 _buy_company_widgets, |
|
935 BuyCompanyWndProc |
|
936 }; |
|
937 |
|
938 |
|
939 void ShowBuyCompanyDialog(uint player) |
|
940 { |
|
941 AllocateWindowDescFront(&_buy_company_desc, player); |
|
942 } |
|
943 |
|
944 /********** HIGHSCORE and ENDGAME windows */ |
|
945 |
|
946 /* Always draw a maximized window and within there the centered background */ |
|
947 static void SetupHighScoreEndWindow(Window *w, uint *x, uint *y) |
|
948 { |
|
949 uint i; |
|
950 // resize window to "full-screen" |
|
951 w->width = _screen.width; |
|
952 w->height = _screen.height; |
|
953 w->widget[0].right = w->width - 1; |
|
954 w->widget[0].bottom = w->height - 1; |
|
955 |
|
956 DrawWindowWidgets(w); |
|
957 |
|
958 /* Center Highscore/Endscreen background */ |
|
959 *x = max(0, (_screen.width / 2) - (640 / 2)); |
|
960 *y = max(0, (_screen.height / 2) - (480 / 2)); |
|
961 for (i = 0; i < 10; i++) // the image is split into 10 50px high parts |
|
962 DrawSprite(WP(w, highscore_d).background_img + i, *x, *y + (i * 50)); |
|
963 } |
|
964 |
|
965 extern StringID EndGameGetPerformanceTitleFromValue(uint value); |
|
966 |
|
967 /* End game window shown at the end of the game */ |
|
968 static void EndGameWndProc(Window *w, WindowEvent *e) |
|
969 { |
|
970 switch (e->event) { |
|
971 case WE_PAINT: { |
|
972 const Player *p; |
|
973 uint x, y; |
|
974 |
|
975 SetupHighScoreEndWindow(w, &x, &y); |
|
976 |
|
977 if (!IsValidPlayer(_local_player)) break; |
|
978 |
|
979 p = GetPlayer(_local_player); |
|
980 /* We need to get performance from last year because the image is shown |
|
981 * at the start of the new year when these things have already been copied */ |
|
982 if (WP(w, highscore_d).background_img == SPR_TYCOON_IMG2_BEGIN) { // Tycoon of the century \o/ |
|
983 SetDParam(0, p->president_name_1); |
|
984 SetDParam(1, p->president_name_2); |
|
985 SetDParam(2, p->name_1); |
|
986 SetDParam(3, p->name_2); |
|
987 SetDParam(4, EndGameGetPerformanceTitleFromValue(p->old_economy[0].performance_history)); |
|
988 DrawStringMultiCenter(x + (640 / 2), y + 107, STR_021C_OF_ACHIEVES_STATUS, 640); |
|
989 } else { |
|
990 SetDParam(0, p->name_1); |
|
991 SetDParam(1, p->name_2); |
|
992 SetDParam(2, EndGameGetPerformanceTitleFromValue(p->old_economy[0].performance_history)); |
|
993 DrawStringMultiCenter(x + (640 / 2), y + 157, STR_021B_ACHIEVES_STATUS, 640); |
|
994 } |
|
995 } break; |
|
996 case WE_CLICK: /* Close the window (and show the highscore window) */ |
|
997 DeleteWindow(w); |
|
998 break; |
|
999 case WE_DESTROY: /* Show the highscore window when this one is closed */ |
|
1000 if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause |
|
1001 ShowHighscoreTable(w->window_number, WP(w, highscore_d).rank); |
|
1002 break; |
|
1003 } |
|
1004 } |
|
1005 |
|
1006 static void HighScoreWndProc(Window *w, WindowEvent *e) |
|
1007 { |
|
1008 switch (e->event) { |
|
1009 case WE_PAINT: { |
|
1010 const HighScore *hs = _highscore_table[w->window_number]; |
|
1011 uint x, y; |
|
1012 uint8 i; |
|
1013 |
|
1014 SetupHighScoreEndWindow(w, &x, &y); |
|
1015 |
|
1016 SetDParam(0, _patches.ending_year); |
|
1017 SetDParam(1, w->window_number + STR_6801_EASY); |
|
1018 DrawStringMultiCenter(x + (640 / 2), y + 62, !_networking ? STR_0211_TOP_COMPANIES_WHO_REACHED : STR_TOP_COMPANIES_NETWORK_GAME, 500); |
|
1019 |
|
1020 /* Draw Highscore peepz */ |
|
1021 for (i = 0; i < lengthof(_highscore_table[0]); i++) { |
|
1022 SetDParam(0, i + 1); |
|
1023 DrawString(x + 40, y + 140 + (i * 55), STR_0212, 0x10); |
|
1024 |
|
1025 if (hs[i].company[0] != '\0') { |
|
1026 uint16 colour = (WP(w, highscore_d).rank == (int8)i) ? 0x3 : 0x10; // draw new highscore in red |
|
1027 |
|
1028 DoDrawString(hs[i].company, x + 71, y + 140 + (i * 55), colour); |
|
1029 SetDParam(0, hs[i].title); |
|
1030 SetDParam(1, hs[i].score); |
|
1031 DrawString(x + 71, y + 160 + (i * 55), STR_HIGHSCORE_STATS, colour); |
|
1032 } |
|
1033 } |
|
1034 } break; |
|
1035 |
|
1036 case WE_CLICK: /* Onclick to close window, and in destroy event handle the rest */ |
|
1037 DeleteWindow(w); |
|
1038 break; |
|
1039 |
|
1040 case WE_DESTROY: /* Get back all the hidden windows */ |
|
1041 if (_game_mode != GM_MENU) ShowVitalWindows(); |
|
1042 |
|
1043 if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause |
|
1044 break; |
|
1045 } |
|
1046 } |
|
1047 |
|
1048 static const Widget _highscore_widgets[] = { |
|
1049 { WWT_PANEL, RESIZE_NONE, 16, 0, 640, 0, 480, 0x0, STR_NULL}, |
|
1050 { WIDGETS_END}, |
|
1051 }; |
|
1052 |
|
1053 static const WindowDesc _highscore_desc = { |
|
1054 0, 0, 641, 481, |
|
1055 WC_HIGHSCORE,0, |
|
1056 0, |
|
1057 _highscore_widgets, |
|
1058 HighScoreWndProc |
|
1059 }; |
|
1060 |
|
1061 static const WindowDesc _endgame_desc = { |
|
1062 0, 0, 641, 481, |
|
1063 WC_ENDSCREEN,0, |
|
1064 0, |
|
1065 _highscore_widgets, |
|
1066 EndGameWndProc |
|
1067 }; |
|
1068 |
|
1069 /* Show the highscore table for a given difficulty. When called from |
|
1070 * endgame ranking is set to the top5 element that was newly added |
|
1071 * and is thus highlighted */ |
|
1072 void ShowHighscoreTable(int difficulty, int8 ranking) |
|
1073 { |
|
1074 Window *w; |
|
1075 |
|
1076 // pause game to show the chart |
|
1077 if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE); |
|
1078 |
|
1079 /* Close all always on-top windows to get a clean screen */ |
|
1080 if (_game_mode != GM_MENU) HideVitalWindows(); |
|
1081 |
|
1082 DeleteWindowByClass(WC_HIGHSCORE); |
|
1083 w = AllocateWindowDesc(&_highscore_desc); |
|
1084 |
|
1085 if (w != NULL) { |
|
1086 MarkWholeScreenDirty(); |
|
1087 w->window_number = difficulty; // show highscore chart for difficulty... |
|
1088 WP(w, highscore_d).background_img = SPR_HIGHSCORE_CHART_BEGIN; // which background to show |
|
1089 WP(w, highscore_d).rank = ranking; |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 /* Show the endgame victory screen in 2050. Update the new highscore |
|
1094 * if it was high enough */ |
|
1095 void ShowEndGameChart(void) |
|
1096 { |
|
1097 Window *w; |
|
1098 |
|
1099 /* Dedicated server doesn't need the highscore window */ |
|
1100 if (_network_dedicated) return; |
|
1101 /* Pause in single-player to have a look at the highscore at your own leisure */ |
|
1102 if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE); |
|
1103 |
|
1104 HideVitalWindows(); |
|
1105 DeleteWindowByClass(WC_ENDSCREEN); |
|
1106 w = AllocateWindowDesc(&_endgame_desc); |
|
1107 |
|
1108 if (w != NULL) { |
|
1109 MarkWholeScreenDirty(); |
|
1110 |
|
1111 WP(w, highscore_d).background_img = SPR_TYCOON_IMG1_BEGIN; |
|
1112 |
|
1113 if (_local_player != PLAYER_SPECTATOR) { |
|
1114 const Player *p = GetPlayer(_local_player); |
|
1115 if (p->old_economy[0].performance_history == SCORE_MAX) |
|
1116 WP(w, highscore_d).background_img = SPR_TYCOON_IMG2_BEGIN; |
|
1117 } |
|
1118 |
|
1119 /* In a network game show the endscores of the custom difficulty 'network' which is the last one |
|
1120 * as well as generate a TOP5 of that game, and not an all-time top5. */ |
|
1121 if (_networking) { |
|
1122 w->window_number = lengthof(_highscore_table) - 1; |
|
1123 WP(w, highscore_d).rank = SaveHighScoreValueNetwork(); |
|
1124 } else { |
|
1125 // in single player _local player is always valid |
|
1126 const Player *p = GetPlayer(_local_player); |
|
1127 w->window_number = _opt.diff_level; |
|
1128 WP(w, highscore_d).rank = SaveHighScoreValue(p); |
|
1129 } |
|
1130 } |
|
1131 } |