33 extern void GenerateWorld(int mode); |
40 extern void GenerateWorld(int mode); |
34 |
41 |
35 extern void GenerateIndustries(); |
42 extern void GenerateIndustries(); |
36 extern void GenerateTowns(); |
43 extern void GenerateTowns(); |
37 |
44 |
38 static void HandleOnEditText(WindowEvent *e) { |
45 extern uint GetCurrentCurrencyRate(); |
|
46 |
|
47 void HandleOnEditTextCancel() { |
|
48 switch(_rename_what) { |
|
49 #ifdef ENABLE_NETWORK |
|
50 case 4: |
|
51 NetworkDisconnect(); |
|
52 break; |
|
53 #endif /* ENABLE_NETWORK */ |
|
54 } |
|
55 } |
|
56 |
|
57 void HandleOnEditText(WindowEvent *e) { |
39 byte *b = e->edittext.str; |
58 byte *b = e->edittext.str; |
40 int id; |
59 int id; |
41 memcpy(_decode_parameters, b, 32); |
60 memcpy(_decode_parameters, b, 32); |
42 |
61 |
43 id = _rename_id; |
62 id = _rename_id; |
50 case 1: |
69 case 1: |
51 if(*b == 0) |
70 if(*b == 0) |
52 return; |
71 return; |
53 DoCommandP(0, id, 0, NULL, CMD_RENAME_WAYPOINT | CMD_MSG(STR_CANT_CHANGE_WAYPOINT_NAME)); |
72 DoCommandP(0, id, 0, NULL, CMD_RENAME_WAYPOINT | CMD_MSG(STR_CANT_CHANGE_WAYPOINT_NAME)); |
54 break; |
73 break; |
|
74 #ifdef ENABLE_NETWORK |
|
75 case 2: |
|
76 // Speak to.. |
|
77 if (!_network_server) |
|
78 SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT + (id & 0xFF), id & 0xFF, (id >> 8) & 0xFF, e->edittext.str); |
|
79 else |
|
80 NetworkServer_HandleChat(NETWORK_ACTION_CHAT + (id & 0xFF), id & 0xFF, (id >> 8) & 0xFF, e->edittext.str, NETWORK_SERVER_INDEX); |
|
81 break; |
|
82 case 3: { |
|
83 // Give money |
|
84 int32 money = atoi(e->edittext.str) / GetCurrentCurrencyRate(); |
|
85 char msg[100]; |
|
86 // Give 'id' the money, and substract it from ourself |
|
87 if (!DoCommandP(0, money, id, NULL, CMD_GIVE_MONEY)) break; |
|
88 |
|
89 // Inform the player of this action |
|
90 SetDParam(0, money); |
|
91 GetString(msg, STR_NETWORK_GIVE_MONEY); |
|
92 |
|
93 if (!_network_server) |
|
94 SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_PLAYER, id + 1, msg); |
|
95 else |
|
96 NetworkServer_HandleChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_PLAYER, id + 1, msg, NETWORK_SERVER_INDEX); |
|
97 break; |
|
98 } |
|
99 case 4: {// Game-Password and Company-Password |
|
100 SEND_COMMAND(PACKET_CLIENT_PASSWORD)(id, e->edittext.str); |
|
101 break; |
|
102 } |
|
103 #endif /* ENABLE_NETWORK */ |
55 } |
104 } |
56 } |
105 } |
57 |
106 |
58 // this code is shared for the majority of the pushbuttons |
107 // this code is shared for the majority of the pushbuttons |
59 bool HandlePlacePushButton(Window *w, int widget, uint32 cursor, int mode, PlaceProc *placeproc) |
108 bool HandlePlacePushButton(Window *w, int widget, uint32 cursor, int mode, PlaceProc *placeproc) |
86 |
135 |
87 typedef void ToolbarButtonProc(Window *w); |
136 typedef void ToolbarButtonProc(Window *w); |
88 |
137 |
89 static void ToolbarPauseClick(Window *w) |
138 static void ToolbarPauseClick(Window *w) |
90 { |
139 { |
91 if (_networking && !_networking_server) { return;} // only server can pause the game |
140 if (_networking && !_network_server) { return;} // only server can pause the game |
92 |
141 |
93 if (DoCommandP(0, _pause?0:1, 0, NULL, CMD_PAUSE | CMD_NET_INSTANT)) |
142 if (DoCommandP(0, _pause?0:1, 0, NULL, CMD_PAUSE)) |
94 SndPlayFx(SND_15_BEEP); |
143 SndPlayFx(SND_15_BEEP); |
95 } |
144 } |
96 |
145 |
97 static void ToolbarFastForwardClick(Window *w) |
146 static void ToolbarFastForwardClick(Window *w) |
98 { |
147 { |
109 switch(index) { |
158 switch(index) { |
110 case 0: ShowGameOptions(); return; |
159 case 0: ShowGameOptions(); return; |
111 case 1: ShowGameDifficulty(); return; |
160 case 1: ShowGameDifficulty(); return; |
112 case 2: ShowPatchesSelection(); return; |
161 case 2: ShowPatchesSelection(); return; |
113 case 3: ShowNewgrf(); return; |
162 case 3: ShowNewgrf(); return; |
114 |
163 |
115 case 5: _display_opt ^= DO_SHOW_TOWN_NAMES; MarkWholeScreenDirty(); return; |
164 case 5: _display_opt ^= DO_SHOW_TOWN_NAMES; MarkWholeScreenDirty(); return; |
116 case 6: _display_opt ^= DO_SHOW_STATION_NAMES; MarkWholeScreenDirty(); return; |
165 case 6: _display_opt ^= DO_SHOW_STATION_NAMES; MarkWholeScreenDirty(); return; |
117 case 7: _display_opt ^= DO_SHOW_SIGNS; MarkWholeScreenDirty(); return; |
166 case 7: _display_opt ^= DO_SHOW_SIGNS; MarkWholeScreenDirty(); return; |
118 case 8: _display_opt ^= DO_WAYPOINTS; MarkWholeScreenDirty(); return; |
167 case 8: _display_opt ^= DO_WAYPOINTS; MarkWholeScreenDirty(); return; |
119 case 9: _display_opt ^= DO_FULL_ANIMATION; MarkWholeScreenDirty(); return; |
168 case 9: _display_opt ^= DO_FULL_ANIMATION; MarkWholeScreenDirty(); return; |
192 static void MenuClickFinances(int index) |
241 static void MenuClickFinances(int index) |
193 { |
242 { |
194 ShowPlayerFinances(index); |
243 ShowPlayerFinances(index); |
195 } |
244 } |
196 |
245 |
|
246 #ifdef ENABLE_NETWORK |
|
247 extern void ShowClientList(); |
|
248 #endif /* ENABLE_NETWORK */ |
|
249 |
197 static void MenuClickCompany(int index) |
250 static void MenuClickCompany(int index) |
198 { |
251 { |
199 ShowPlayerCompany(index); |
252 if (_networking && index == 0) { |
|
253 #ifdef ENABLE_NETWORK |
|
254 ShowClientList(); |
|
255 #endif /* ENABLE_NETWORK */ |
|
256 } else { |
|
257 if (_networking) index--; |
|
258 ShowPlayerCompany(index); |
|
259 } |
200 } |
260 } |
201 |
261 |
202 |
262 |
203 static void MenuClickGraphs(int index) |
263 static void MenuClickGraphs(int index) |
204 { |
264 { |
268 static void MenuClickBuildAir(int index) |
328 static void MenuClickBuildAir(int index) |
269 { |
329 { |
270 ShowBuildAirToolbar(); |
330 ShowBuildAirToolbar(); |
271 } |
331 } |
272 |
332 |
|
333 #ifdef ENABLE_NETWORK |
|
334 void ShowNetworkChatQueryWindow(byte desttype, byte dest) |
|
335 { |
|
336 _rename_id = desttype + (dest << 8); |
|
337 _rename_what = 2; |
|
338 ShowQueryString(STR_EMPTY, STR_NETWORK_CHAT_QUERY_CAPTION, 60, 250, 1, 0); |
|
339 } |
|
340 |
|
341 void ShowNetworkGiveMoneyWindow(byte player) |
|
342 { |
|
343 _rename_id = player; |
|
344 _rename_what = 3; |
|
345 ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, 180, 1, 0); |
|
346 } |
|
347 |
|
348 void ShowNetworkNeedGamePassword() |
|
349 { |
|
350 _rename_id = NETWORK_GAME_PASSWORD; |
|
351 _rename_what = 4; |
|
352 ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_GAME_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0); |
|
353 } |
|
354 |
|
355 void ShowNetworkNeedCompanyPassword() |
|
356 { |
|
357 _rename_id = NETWORK_COMPANY_PASSWORD; |
|
358 _rename_what = 4; |
|
359 ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0); |
|
360 } |
|
361 |
|
362 #endif /* ENABLE_NETWORK */ |
|
363 |
273 void ShowRenameSignWindow(SignStruct *ss) |
364 void ShowRenameSignWindow(SignStruct *ss) |
274 { |
365 { |
275 _rename_id = ss - _sign_list; |
366 _rename_id = ss - _sign_list; |
276 _rename_what = 0; |
367 _rename_what = 0; |
277 ShowQueryString(ss->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, 1, 0); |
368 ShowQueryString(ss->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, 1, 0); |
284 _rename_what = 1; |
375 _rename_what = 1; |
285 SetDParam(0, id); |
376 SetDParam(0, id); |
286 ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, 1, 0); |
377 ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, 1, 0); |
287 } |
378 } |
288 |
379 |
289 static void CcPlaceSign(bool success, uint tile, uint32 p1, uint32 p2) |
380 void CcPlaceSign(bool success, uint tile, uint32 p1, uint32 p2) |
290 { |
381 { |
291 if (success) { |
382 if (success) { |
292 ShowRenameSignWindow(_new_sign_struct); |
383 ShowRenameSignWindow(_new_sign_struct); |
293 ResetObjectToPlace(); |
384 ResetObjectToPlace(); |
294 } |
385 } |
481 FOR_ALL_PLAYERS(p) { |
572 FOR_ALL_PLAYERS(p) { |
482 if (p->is_active) |
573 if (p->is_active) |
483 num++; |
574 num++; |
484 } |
575 } |
485 |
576 |
|
577 // Increase one to fit in PlayerList in the menu when |
|
578 // in network |
|
579 if (_networking && WP(w,menu_d).main_button == 9) { |
|
580 num++; |
|
581 } |
|
582 |
486 if (WP(w,menu_d).item_count != num) { |
583 if (WP(w,menu_d).item_count != num) { |
487 WP(w,menu_d).item_count = num; |
584 WP(w,menu_d).item_count = num; |
488 SetWindowDirty(w); |
585 SetWindowDirty(w); |
489 num = num * 10 + 2; |
586 num = num * 10 + 2; |
490 w->height = num; |
587 w->height = num; |
491 _player_menu_widgets[0].bottom = _player_menu_widgets[0].top + num - 1; |
588 _player_menu_widgets[0].bottom = _player_menu_widgets[0].top + num - 1; |
492 SetWindowDirty(w); |
589 SetWindowDirty(w); |
493 } |
590 } |
494 } |
591 } |
495 |
592 |
|
593 extern void DrawPlayerIcon(int p, int x, int y); |
|
594 |
496 static void PlayerMenuWndProc(Window *w, WindowEvent *e) |
595 static void PlayerMenuWndProc(Window *w, WindowEvent *e) |
497 { |
596 { |
498 switch(e->event) { |
597 switch(e->event) { |
499 case WE_PAINT: { |
598 case WE_PAINT: { |
500 int x,y; |
599 int x,y; |
508 x = 1; |
607 x = 1; |
509 y = 1; |
608 y = 1; |
510 sel = WP(w,menu_d).sel_index; |
609 sel = WP(w,menu_d).sel_index; |
511 chk = WP(w,menu_d).checked_items; // let this mean gray items. |
610 chk = WP(w,menu_d).checked_items; // let this mean gray items. |
512 |
611 |
|
612 // 9 = playerlist |
|
613 if (_networking && WP(w,menu_d).main_button == 9) { |
|
614 if (sel == 0) { |
|
615 GfxFillRect(x, y, x + 238, y + 9, 0); |
|
616 } |
|
617 DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, 0x0); |
|
618 y += 10; |
|
619 sel--; |
|
620 } |
|
621 |
513 FOR_ALL_PLAYERS(p) { |
622 FOR_ALL_PLAYERS(p) { |
514 if (p->is_active) { |
623 if (p->is_active) { |
515 if (p->index == sel) { |
624 if (p->index == sel) { |
516 GfxFillRect(x, y, x + 0xEE, y + 9, 0); |
625 GfxFillRect(x, y, x + 238, y + 9, 0); |
517 } |
626 } |
518 DrawSprite( ((p->player_color + 0x307)<<16)+0x82EB, x+2, y+1); |
627 |
|
628 DrawPlayerIcon(p->index, x + 2, y + 1); |
519 |
629 |
520 SetDParam(0, p->name_1); |
630 SetDParam(0, p->name_1); |
521 SetDParam(1, p->name_2); |
631 SetDParam(1, p->name_2); |
522 SetDParam(2, GetPlayerNameString(p->index, 3)); |
632 SetDParam(2, GetPlayerNameString(p->index, 3)); |
523 |
633 |
524 color = (byte)((p->index==sel) ? 0xC : 0x10); |
634 color = (byte)((p->index==sel) ? 0xC : 0x10); |
525 if (chk&1) color = 14; |
635 if (chk&1) color = 14; |
526 DrawString(x+0x13, y, STR_7021, color); |
636 DrawString(x + 19, y, STR_7021, color); |
527 |
637 |
528 y += 10; |
638 y += 10; |
529 } |
639 } |
530 chk >>= 1; |
640 chk >>= 1; |
531 } |
641 } |
|
642 |
532 break; |
643 break; |
533 } |
644 } |
534 |
645 |
535 case WE_DESTROY: { |
646 case WE_DESTROY: { |
536 Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); |
647 Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); |
538 SetWindowDirty(v); |
649 SetWindowDirty(v); |
539 return; |
650 return; |
540 } |
651 } |
541 |
652 |
542 case WE_POPUPMENU_SELECT: { |
653 case WE_POPUPMENU_SELECT: { |
543 int index = GetPlayerIndexFromMenu(GetMenuItemIndex(w, e->popupmenu.pt.x, e->popupmenu.pt.y)); |
654 int index = GetMenuItemIndex(w, e->popupmenu.pt.x, e->popupmenu.pt.y); |
544 int action_id = WP(w,menu_d).action_id; |
655 int action_id = WP(w,menu_d).action_id; |
|
656 |
|
657 // We have a new entry at the top of the list of menu 9 when networking |
|
658 // so keep that in count |
|
659 if (!_networking || (WP(w,menu_d).main_button == 9 && index > 0)) { |
|
660 index = GetPlayerIndexFromMenu(index-1)+1; |
|
661 } |
545 |
662 |
546 if (index < 0) { |
663 if (index < 0) { |
547 Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); |
664 Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); |
548 if (GetWidgetFromPos(w2, e->popupmenu.pt.x - w2->left, e->popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button) |
665 if (GetWidgetFromPos(w2, e->popupmenu.pt.x - w2->left, e->popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button) |
549 index = WP(w,menu_d).sel_index; |
666 index = WP(w,menu_d).sel_index; |
558 break; |
675 break; |
559 } |
676 } |
560 case WE_POPUPMENU_OVER: { |
677 case WE_POPUPMENU_OVER: { |
561 int index; |
678 int index; |
562 UpdatePlayerMenuHeight(w); |
679 UpdatePlayerMenuHeight(w); |
563 index = GetPlayerIndexFromMenu(GetMenuItemIndex(w, e->popupmenu.pt.x, e->popupmenu.pt.y)); |
680 index = GetMenuItemIndex(w, e->popupmenu.pt.x, e->popupmenu.pt.y); |
|
681 |
|
682 // We have a new entry at the top of the list of menu 9 when networking |
|
683 // so keep that in count |
|
684 if (index != -1) { |
|
685 if (!_networking || (WP(w,menu_d).main_button == 9 && index != 0)) { |
|
686 index = GetPlayerIndexFromMenu(index-1)+1; |
|
687 } |
|
688 } |
564 |
689 |
565 if (index == -1 || index == WP(w,menu_d).sel_index) |
690 if (index == -1 || index == WP(w,menu_d).sel_index) |
566 return; |
691 return; |
567 |
692 |
568 WP(w,menu_d).sel_index = index; |
693 WP(w,menu_d).sel_index = index; |
610 |
735 |
611 DeleteWindowById(WC_TOOLBAR_MENU, 0); |
736 DeleteWindowById(WC_TOOLBAR_MENU, 0); |
612 w = AllocateWindow(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets); |
737 w = AllocateWindow(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets); |
613 w->flags4 &= ~WF_WHITE_BORDER_MASK; |
738 w->flags4 &= ~WF_WHITE_BORDER_MASK; |
614 WP(w,menu_d).item_count = 0; |
739 WP(w,menu_d).item_count = 0; |
615 WP(w,menu_d).sel_index = _local_player != OWNER_SPECTATOR ? _local_player : 0; |
740 WP(w,menu_d).sel_index = (_local_player != OWNER_SPECTATOR) ? _local_player : 0; |
|
741 if (_networking && main_button == 9 && _local_player != OWNER_SPECTATOR) { |
|
742 WP(w,menu_d).sel_index++; |
|
743 } |
616 WP(w,menu_d).action_id = main_button; |
744 WP(w,menu_d).action_id = main_button; |
617 WP(w,menu_d).main_button = main_button; |
745 WP(w,menu_d).main_button = main_button; |
618 WP(w,menu_d).checked_items = gray; |
746 WP(w,menu_d).checked_items = gray; |
619 _popup_menu_active = true; |
747 _popup_menu_active = true; |
620 SndPlayFx(SND_15_BEEP); |
748 SndPlayFx(SND_15_BEEP); |
986 static void AskResetLandscape(uint mode) |
1114 static void AskResetLandscape(uint mode) |
987 { |
1115 { |
988 AllocateWindowDescFront(&_ask_reset_landscape_desc, mode); |
1116 AllocateWindowDescFront(&_ask_reset_landscape_desc, mode); |
989 } |
1117 } |
990 |
1118 |
991 static void CcTerraform(bool success, uint tile, uint32 p1, uint32 p2) |
1119 void CcTerraform(bool success, uint tile, uint32 p1, uint32 p2) |
992 { |
1120 { |
993 if (success) { |
1121 if (success) { |
994 SndPlayTileFx(SND_1F_SPLAT, tile); |
1122 SndPlayTileFx(SND_1F_SPLAT, tile); |
995 } else { |
1123 } else { |
996 SetRedErrorSquare(_terraform_err_tile); |
1124 SetRedErrorSquare(_terraform_err_tile); |
1047 static void PlaceProc_LowerBigLand(uint tile) |
1175 static void PlaceProc_LowerBigLand(uint tile) |
1048 { |
1176 { |
1049 CommonRaiseLowerBigLand(tile, 0); |
1177 CommonRaiseLowerBigLand(tile, 0); |
1050 } |
1178 } |
1051 |
1179 |
1052 //static void CcDemolish(bool success, uint tile, uint32 p1, uint32 p2) |
1180 //void CcDemolish(bool success, uint tile, uint32 p1, uint32 p2) |
1053 //{ |
1181 //{ |
1054 // if (success) { |
1182 // if (success) { |
1055 //SndPlayTileFx(0x10, tile); |
1183 //SndPlayTileFx(0x10, tile); |
1056 //CreateEffectVehicleAbove(GET_TILE_X(tile)*16 + 8,GET_TILE_Y(tile)*16 + 8, 2, EV_DEMOLISH); |
1184 //CreateEffectVehicleAbove(GET_TILE_X(tile)*16 + 8,GET_TILE_Y(tile)*16 + 8, 2, EV_DEMOLISH); |
1057 // } |
1185 // } |
1255 SndPlayFx(SND_15_BEEP); |
1383 SndPlayFx(SND_15_BEEP); |
1256 |
1384 |
1257 AllocateWindowDescFront(&_scen_edit_land_gen_desc, 0); |
1385 AllocateWindowDescFront(&_scen_edit_land_gen_desc, 0); |
1258 } |
1386 } |
1259 |
1387 |
1260 static void CcBuildTown(bool success, uint tile, uint32 p1, uint32 p2) |
1388 void CcBuildTown(bool success, uint tile, uint32 p1, uint32 p2) |
1261 { |
1389 { |
1262 if (success) { |
1390 if (success) { |
1263 SndPlayTileFx(SND_1F_SPLAT, tile); |
1391 SndPlayTileFx(SND_1F_SPLAT, tile); |
1264 ResetObjectToPlace(); |
1392 ResetObjectToPlace(); |
1265 } |
1393 } |
1711 case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break; |
1839 case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break; |
1712 case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break; |
1840 case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break; |
1713 case WKC_CTRL | 'S': _make_screenshot = 1; break; |
1841 case WKC_CTRL | 'S': _make_screenshot = 1; break; |
1714 case WKC_CTRL | 'G': _make_screenshot = 2; break; |
1842 case WKC_CTRL | 'G': _make_screenshot = 2; break; |
1715 case WKC_BACKQUOTE: IConsoleSwitch(); e->keypress.cont=false; break; |
1843 case WKC_BACKQUOTE: IConsoleSwitch(); e->keypress.cont=false; break; |
1716 case WKC_CTRL | WKC_ALT | 'C': if(!_networking) ShowCheatWindow(); break; |
1844 case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break; |
1717 } |
1845 } |
1718 } break; |
1846 } break; |
1719 |
1847 |
1720 case WE_PLACE_OBJ: { |
1848 case WE_PLACE_OBJ: { |
1721 _place_proc(e->place.tile); |
1849 _place_proc(e->place.tile); |
2245 w = AllocateWindowDesc(&_toolb_normal_desc); |
2379 w = AllocateWindowDesc(&_toolb_normal_desc); |
2246 w->disabled_state = 1 << 17; // disable zoon-in button (by default game is zoomed in) |
2380 w->disabled_state = 1 << 17; // disable zoon-in button (by default game is zoomed in) |
2247 |
2381 |
2248 if (_networking) { // if networking, disable fast-forward button |
2382 if (_networking) { // if networking, disable fast-forward button |
2249 w->disabled_state |= (1 << 1); |
2383 w->disabled_state |= (1 << 1); |
2250 if (!_networking_server) // if not server, disable pause button |
2384 if (!_network_server) // if not server, disable pause button |
2251 w->disabled_state |= (1 << 0); |
2385 w->disabled_state |= (1 << 0); |
2252 } |
2386 } |
2253 |
2387 |
2254 w->flags4 &= ~WF_WHITE_BORDER_MASK; |
2388 w->flags4 &= ~WF_WHITE_BORDER_MASK; |
2255 |
2389 |