diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 3e32fb79e3..76a1fdfc39 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -59,6 +59,7 @@ + @@ -132,6 +133,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 222e1bfbba..7f24637b5d 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -156,6 +156,9 @@ Header Files + + Header Files + @@ -371,6 +374,9 @@ Windows + + Source Files + diff --git a/src/game.c b/src/game.c index 8ea5dbcc3e..5176330499 100644 --- a/src/game.c +++ b/src/game.c @@ -40,6 +40,7 @@ #include "viewport.h" #include "widget.h" #include "window.h" +#include "staff.h" #include "window_error.h" #include "window_tooltip.h" @@ -2188,6 +2189,7 @@ static int game_check_affordability(int cost) } static uint32 game_do_command_table[58]; +static GAME_COMMAND_POINTER* new_game_command_table[58]; /** * @@ -2227,9 +2229,13 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int * RCT2_GLOBAL(0x009A8C28, uint8)++; *ebx &= ~1; - + // Primary command - RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp); + if (game_do_command_table[command] == 0) { + new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp); + } else { + RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp); + } cost = *ebx; if (cost != 0x80000000) { @@ -2252,7 +2258,11 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int * } // Secondary command - RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp); + if (game_do_command_table[command] == 0) { + new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp); + } else { + RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp); + } *edx = *ebx; if (*edx != 0x80000000 && *edx < cost) @@ -2375,54 +2385,6 @@ static void game_load_or_quit() } -/** -* -* rct2: 0x00669E55 -*/ -static void game_update_staff_colour() -{ - byte tabIndex, colour, _bl; - int spriteIndex; - rct_peep *peep; - - #ifdef _MSC_VER - __asm mov _bl, bl - #else - __asm__("mov %[_bl], bl " : [_bl] "+m" (_bl)); - #endif - - #ifdef _MSC_VER - __asm mov tabIndex, bh - #else - __asm__("mov %[tabIndex], bh " : [tabIndex] "+m" (tabIndex)); - #endif - - #ifdef _MSC_VER - __asm mov colour, dh - #else - __asm__("mov %[colour], bh " : [colour] "+m" (colour)); - #endif - - if (_bl & 1) { - RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[tabIndex] = colour; - - FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == tabIndex) { - peep->tshirt_colour = colour; - peep->trousers_colour = colour; - } - } - } - - gfx_invalidate_screen(); - - #ifdef _MSC_VER - __asm mov ebx, 0 - #else - __asm__("mov ebx, 0 "); - #endif -} - /** * * rct2: 0x00674F40 @@ -2733,7 +2695,7 @@ static uint32 game_do_command_table[58] = { 0x006E66A0, 0x006E6878, 0x006C5AE9, - 0x006BEFA1, + 0, // use new_game_command_table, original: 0x006BEFA1, 29 0x006C09D1, // 30 0x006C0B83, 0x006C0BB5, @@ -2744,7 +2706,7 @@ static uint32 game_do_command_table[58] = { 0x00666A63, 0x006CD8CE, 0x00669E30, - (uint32)game_update_staff_colour, // 40 + (uint32)game_command_update_staff_colour, // 40 0x006E519A, 0x006E5597, 0x006B893C, @@ -2764,4 +2726,67 @@ static uint32 game_do_command_table[58] = { 0x0068DF91 }; +void game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {} + +static GAME_COMMAND_POINTER* new_game_command_table[58] = { + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, // 10 + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, // 20 + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_hire_new_staff_member, //game_command_emptysub, + game_command_emptysub, // 30 + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, // 40 + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, // 50 + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub, + game_command_emptysub +}; + #pragma endregion diff --git a/src/game.h b/src/game.h index 92f11036ad..5c0771ca58 100644 --- a/src/game.h +++ b/src/game.h @@ -82,6 +82,8 @@ enum GAME_COMMAND { GAME_COMMAND_57 }; +typedef void (GAME_COMMAND_POINTER)(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); + void game_create_windows(); void game_update(); void game_logic_update(); diff --git a/src/peep.h b/src/peep.h index a2b253feb8..18e5cd17f6 100644 --- a/src/peep.h +++ b/src/peep.h @@ -34,20 +34,11 @@ #define PEEP_NOEXIT_WARNING_THRESHOLD 8 #define PEEP_LOST_WARNING_THRESHOLD 8 - - enum PEEP_TYPE { PEEP_TYPE_GUEST, PEEP_TYPE_STAFF }; -enum STAFF_TYPE { - STAFF_TYPE_HANDYMAN, - STAFF_TYPE_MECHANIC, - STAFF_TYPE_SECURITY, - STAFF_TYPE_ENTERTAINER -}; - enum PEEP_THOUGHT_TYPE { PEEP_THOUGHT_TYPE_SPENT_MONEY = 1, // "I've spent all my money" PEEP_THOUGHT_TYPE_SICK = 2, // "I feel sick" @@ -314,17 +305,18 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01; - uint16 pad_02; + uint16 var_02; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 var_08; - uint8 pad_09; + uint8 var_09; // 0x09 uint16 sprite_index; // 0x0A uint16 var_0C; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - sint16 pad_14; + uint8 var_14; // 0x14 + uint8 var_15; // 0x15 sint16 var_16; sint16 var_18; sint16 var_1A; @@ -372,7 +364,9 @@ typedef struct { uint8 current_train; // 0x6A uint8 current_car; // 0x6B uint8 current_seat; // 0x6C - uint8 pad_6D[3]; + uint8 var_6D; // 0x6D + uint8 var_6E; // 0x6E + uint8 pad_6F; uint8 var_70; uint8 var_71; uint8 var_72; @@ -386,18 +380,22 @@ typedef struct { uint32 id; // 0x9C money32 cash_in_pocket; // 0xA0 money32 cash_spent; // 0xA4 - uint8 pad_A8; + uint8 var_A8; // 0xA8 sint32 time_in_park; // 0xA9 - uint8 var_AD; + uint8 var_AD; // creation/hire time? uint16 var_AE; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 - uint8 pad_C4; + uint8 var_C4; // 0xC4 uint8 var_C5; uint8 var_C6; uint8 photo1_ride_ref; // 0xC7 uint32 flags; // 0xC8 - uint8 var_CC; - uint8 pad_CD[0x17]; + uint32 var_CC; + uint8 pad_D0[0x10]; + uint8 var_E0; // 0xE0 + uint8 pad_E1; + uint8 var_E2; // 0xE2 + uint8 pad_E3; money16 paid_to_enter; // 0xE4 money16 paid_on_rides; // 0xE6 money16 paid_on_food; // 0xE8 diff --git a/src/staff.c b/src/staff.c new file mode 100644 index 0000000000..1e0bc041cb --- /dev/null +++ b/src/staff.c @@ -0,0 +1,272 @@ +/***************************************************************************** +* Copyright (c) 2014 Dániel Tar +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "staff.h" +#include "addresses.h" +#include "rct2.h" +#include "game.h" +#include "finance.h" +#include "peep.h" +#include "sprite.h" +#include "string_ids.h" +#include "viewport.h" + +/** +* +* rct2: 0x00669E55 +*/ +void game_command_update_staff_colour() +{ + uint8 staff_type, colour, _bl; + int spriteIndex; + rct_peep *peep; + + #ifdef _MSC_VER + __asm mov _bl, bl + #else + __asm__("mov %[_bl], bl " : [_bl] "+m" (_bl)); + #endif + + #ifdef _MSC_VER + __asm mov staff_type, bh + #else + __asm__("mov %[staff_type], bh " : [staff_type] "+m" (staff_type)); + #endif + + #ifdef _MSC_VER + __asm mov colour, dh + #else + __asm__("mov %[colour], bh " : [colour] "+m" (colour)); + #endif + + if (_bl & 1) { + RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[staff_type] = colour; + + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == staff_type) { + peep->tshirt_colour = colour; + peep->trousers_colour = colour; + } + } + } + + gfx_invalidate_screen(); + + #ifdef _MSC_VER + __asm mov ebx, 0 + #else + __asm__("mov ebx, 0 "); + #endif +} + +/** +* +* rct2: 0x006BEFA1 +*/ +void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, + int* esi, int* edi, int* ebp) +{ + uint8 _bl = *ebx & 0xFF, staff_type = (*ebx & 0xFF00) >> 8; + uint16 _ax = *eax & 0xFFFF, _cx = *ecx & 0xFFFF, _dx = *edx & 0xFFFF; + + RCT2_GLOBAL(0x0141F56C, uint8) = 0x28; + RCT2_GLOBAL(0x009DEA5E, uint16) = _ax; + RCT2_GLOBAL(0x009DEA60, uint16) = _cx; + RCT2_GLOBAL(0x009DEA62, uint16) = _dx; + + if (RCT2_GLOBAL(0x13573C8, uint16) < 0x190) { + *ebx = 0x80000000; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME; + return; + } + + int i; + for (i = 0; i < STAFF_MAX_COUNT; i++) { + if (!(RCT2_ADDRESS(0x013CA672, uint8)[i] & 1)) + break; + } + + if (i == STAFF_MAX_COUNT) { + *ebx = 0x80000000; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_STAFF_IN_GAME; + return; + } + + int newStaffId = i; + + int _eax, _ebx, _ecx = _cx, _edx, _esi, _edi, _ebp; + _esi = 0; + _ebx = _bl; + RCT2_CALLFUNC_X(0x0069EC6B, &_eax, &_ebx, &_ecx, &_edx, &_esi, &_edi, &_ebp); + rct_peep* newPeep = (rct_peep*)_esi; + + //if ((newPeep = create_peep_sprite(_bl)) == NULL) + if (_esi == 0) + { + *ebx = 0x80000000; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME; + return; + } + + if (_bl == 0) { + RCT2_CALLPROC_X(0x0069EDB6, 0, 0, _ecx, 0, (int)newPeep, 0, 0); + } + else { + RCT2_CALLPROC_X(0x0069ED0B, 0, 0, 4, 0, (int)newPeep, 0, 0); + + newPeep->sprite_identifier = 1; + newPeep->var_09 = 0x0F; + newPeep->var_15 = 5; + newPeep->var_14 = 8; + newPeep->sprite_direction = 0; + + RCT2_CALLPROC_X(0x0069E9D3, _ax, 0, *ecx, _dx, (int)newPeep, 0, 0); + + newPeep->state = PEEP_STATE_PICKED; + if (newPeep->x != -32768) { + newPeep->state = 0; + } + + newPeep->var_45 = 0; + newPeep->var_71 = 0xFF; + newPeep->var_6D = 0; + newPeep->var_70 = 0; + newPeep->var_E0 = 0; + newPeep->var_6E = 0; + newPeep->var_C4 = 0; + newPeep->type = PEEP_TYPE_STAFF; + newPeep->var_2A = 0; + newPeep->flags = 0; + newPeep->paid_to_enter = 0; + newPeep->paid_on_rides = 0; + newPeep->paid_on_food = 0; + newPeep->paid_on_souvenirs = 0; + + newPeep->var_C6 = 0; + if (staff_type == 0) { + newPeep->var_C6 = 7; + } + else if (staff_type == 1) { + newPeep->var_C6 = 3; + } + + newPeep->staff_type = 0xFF; + + uint16 idSearchSpriteIndex; + rct_peep* idSearchPeep; + + // We search for the first available id for a given staff type + int newStaffIndex = 0; + for (;;) { + int found = 0; + newStaffIndex++; + + FOR_ALL_STAFF(idSearchSpriteIndex, idSearchPeep) { + if (idSearchPeep->staff_type != staff_type) { + continue; + } + + if (idSearchPeep->id == newStaffIndex) { + found = 1; + break; + } + } + + if (found == 0) + break; + } + + newPeep->id = newStaffIndex; + newPeep->staff_type = staff_type; + + _eax = RCT2_ADDRESS(0x009929FC, uint8)[staff_type]; + newPeep->name_string_idx = staff_type + 0x300; + newPeep->sprite_type = _eax; + + _edx = RCT2_ADDRESS(0x0098270C, uint32)[_eax * 2]; + newPeep->var_14 = *((uint8*)_edx); + newPeep->var_09 = *((uint8*)(_edx + 1)); + newPeep->var_15 = *((uint8*)(_edx + 2)); + + RCT2_CALLPROC_X(0x0069E9D3, newPeep->x, 0, newPeep->y, newPeep->z, (int)newPeep, 0, 0); + RCT2_CALLPROC_X(0x006EC473, *eax, 0, 0, 0, (int)newPeep, 0, 0); + + newPeep->var_AD = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint8); + newPeep->var_CC = 0xFFFFFFFF; + + uint8 colour = RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[staff_type > 2 ? 2 : staff_type]; + newPeep->tshirt_colour = colour; + newPeep->trousers_colour = colour; + + newPeep->energy = 0x60; + newPeep->energy_growth_rate = 0x60; + newPeep->var_E2 = 0; + + RCT2_CALLPROC_X(0x00699115, (uint32)ebp & 0xFFFFFF3F, 0, 0, 0, (int)newPeep, 0, + (*ebp << 25) | (*ebp >> 6)); + + newPeep->var_C5 = newStaffId; + + RCT2_ADDRESS(0x013CA672, uint8)[newStaffId] = 1; + + for (int edi = 0; edi < 0x80; edi++) { + int addr = 0x013B0E72 + (newStaffId << 9) + edi * 4; + RCT2_GLOBAL(addr, uint32) = 0; + } + } + + *ebx = 0; + *edi = newPeep->sprite_index; +} + +/* + * Updates the colour of the given staff type. +*/ +void update_staff_colour(uint8 staff_type, uint16 colour) +{ + game_do_command( + 0, + (staff_type << 8) + 1, + 0, + (colour << 8) + 4, + GAME_COMMAND_SET_STAFF_COLOUR, + 0, + 0); +} + +/* + * Hires a new staff member of the given type. If the hire cannot be completed (eg. the maximum + * number of staff is reached or there are too many people in the game) it returns 0xFFFF. +*/ +uint16 hire_new_staff_member(uint8 staff_type) +{ + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_HIRE_NEW_STAFF; + + int eax, ebx, ecx, edx, esi, edi, ebp; + eax = 0x8000; + ebx = staff_type << 8 | 1; + + int result = game_do_command_p(GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + if (result == 0x80000000) + return 0xFFFF; + + return edi; +} \ No newline at end of file diff --git a/src/staff.h b/src/staff.h new file mode 100644 index 0000000000..533c0b4a8f --- /dev/null +++ b/src/staff.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2014 Dániel Tar + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*****************************************************************************/ + +#ifndef _STAFF_H_ +#define _STAFF_H_ + +#include "rct2.h" + +#define STAFF_MAX_COUNT 0xC8 + +enum STAFF_TYPE { + STAFF_TYPE_HANDYMAN, + STAFF_TYPE_MECHANIC, + STAFF_TYPE_SECURITY, + STAFF_TYPE_ENTERTAINER +}; + +void game_command_update_staff_colour(); +void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); + +void update_staff_colour(uint8 staff_type, uint16 color); +uint16 hire_new_staff_member(uint8 staff_type); + +#endif \ No newline at end of file diff --git a/src/string_ids.h b/src/string_ids.h index 15d483ca12..aabbb8442c 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -337,12 +337,15 @@ enum { STR_GUESTS_TIP = 1693, STR_STAFF_TIP = 1694, + STR_TOO_MANY_PEOPLE_IN_GAME = 1699, STR_HIRE_HANDYMAN = 1700, - STR_HIRE_MECHANIC = 1700, - STR_HIRE_SECURITY_GUARD = 1700, - STR_HIRE_ENTERTAINER = 1700, + STR_HIRE_MECHANIC = 1701, + STR_HIRE_SECURITY_GUARD = 1702, + STR_HIRE_ENTERTAINER = 1703, STR_CANT_HIRE_NEW_STAFF = 1704, + STR_TOO_MANY_STAFF_IN_GAME = 1707, + STR_CANT_RENAME_PARK = 1717, STR_PARK_NAME = 1718, STR_ENTER_PARK_NAME = 1719, diff --git a/src/window_staff.c b/src/window_staff.c index d4db8262b9..650dd10dc7 100644 --- a/src/window_staff.c +++ b/src/window_staff.c @@ -23,6 +23,7 @@ #include "game.h" #include "gfx.h" #include "peep.h" +#include "staff.h" #include "sprite.h" #include "string_ids.h" #include "viewport.h" @@ -193,24 +194,6 @@ void window_staff_close() { window_staff_cancel_tools(w); } -void window_staff_hire_new() { - uint8 bl = 1; - RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_HIRE_NEW_STAFF; - int eax, ebx, ecx, edx, esi, edi, ebp; - - eax = 0x8000; - ebx = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) << 8 | bl; - - int result = game_do_command_p(GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - if (result == 0x80000000) { - rct_window* window = window_find_by_id(WC_STAFF_LIST, 0); - window_invalidate(window); - } else { - window_staff_peep_open(&g_sprite_list[edi].peep); - } -} - /** * * rct2: 0x006BD94C @@ -219,6 +202,7 @@ static void window_staff_mouseup() { short widgetIndex; rct_window *w; + uint16 newStaffId; window_widget_get_registers(w, widgetIndex); @@ -227,7 +211,15 @@ static void window_staff_mouseup() window_close(w); break; case WIDX_STAFF_HIRE_BUTTON: - window_staff_hire_new(); + newStaffId = hire_new_staff_member(RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)); + + if (newStaffId == 0xFFFF) { + rct_window* window = window_find_by_id(WC_STAFF_LIST, 0); + window_invalidate(window); + } else { + window_staff_peep_open(&g_sprite_list[newStaffId].peep); + } + break; case WIDX_STAFF_SHOW_PATROL_AREA_BUTTON: RCT2_CALLPROC_X(0x006BD9FF, 0, 0, 0, widgetIndex, (int)w, 0, 0); @@ -310,14 +302,7 @@ static void window_staff_dropdown() window_dropdown_get_registers(w, widgetIndex, dropdownIndex); if (widgetIndex == WIDX_STAFF_UNIFORM_COLOR_PICKER && dropdownIndex != -1) { - game_do_command( - 0, - (RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) << 8) + 1, - 0, - (dropdownIndex << 8) + 4, - GAME_COMMAND_SET_STAFF_COLOUR, - 0, - 0); + update_staff_colour(RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8), dropdownIndex); } }