diff --git a/src/interface/window.h b/src/interface/window.h index 3d20200d32..347df9c53f 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -579,7 +579,7 @@ void window_options_open(); void window_shortcut_keys_open(); void window_shortcut_change_open(int selected_key); void window_guest_open(rct_peep* peep); -void window_staff_open(rct_peep* peep); +rct_window *window_staff_open(rct_peep* peep); void window_staff_fire_prompt_open(rct_peep* peep); void window_park_awards_open(); void window_park_entrance_open(); diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index e367ce7d39..d3a1bdd0cd 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -809,6 +809,8 @@ enum { STR_DOWN_TIME_LABEL_1889 = 1889, STR_SELECT_HOW_OFTEN_A_MECHANIC_SHOULD_CHECK_THIS_RIDE = 1890, + STR_NO_THING_IN_PARK_YET = 1891, + STR_ITEMS_SOLD = 1894, STR_BUILD_RIDE_TIP = 1895, STR_FINANCES_SUMMARY_EXPENDITURE_INCOME = 1896, diff --git a/src/peep/staff.c b/src/peep/staff.c index f35a93239b..11cf6b1966 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -29,6 +29,9 @@ #include "peep.h" #include "staff.h" +uint32 *gStaffPatrolAreas = (uint32*)0x013B0E72; +uint8 *gStaffModes = (uint8*)0x013CA672; + /** * * rct2: 0x00669E55 @@ -451,3 +454,14 @@ void staff_reset_stats() peep->staff_bins_emptied = 0; } } + +bool staff_is_patrol_area_set(int staffIndex, int x, int y) +{ + x = (x & 0x1F80) >> 7; + y = (y & 0x1F80) >> 1; + + int peepOffset = staffIndex * 128; + int offset = (x | y) >> 5; + int bitIndex = (x | y) & 0x1F; + return gStaffPatrolAreas[peepOffset + offset] & (1 << bitIndex); +} diff --git a/src/peep/staff.h b/src/peep/staff.h index 51467efecc..42303f33f7 100644 --- a/src/peep/staff.h +++ b/src/peep/staff.h @@ -49,6 +49,9 @@ enum STAFF_ORDERS{ STAFF_ORDERS_FIX_RIDES = (1 << 1) }; +extern uint32 *gStaffPatrolAreas; +extern uint8 *gStaffModes; + void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_hire_new_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); @@ -60,5 +63,6 @@ uint16 hire_new_staff_member(uint8 staffType); void staff_update_greyed_patrol_areas(); int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y); void staff_reset_stats(); +bool staff_is_patrol_area_set(int staffIndex, int x, int y); #endif \ No newline at end of file diff --git a/src/windows/staff.c b/src/windows/staff.c index de7e41d4ef..eddac342b5 100644 --- a/src/windows/staff.c +++ b/src/windows/staff.c @@ -297,7 +297,7 @@ uint32 window_staff_page_enabled_widgets[] = { * * rct2: 0x006BEE98 */ -void window_staff_open(rct_peep* peep) +rct_window *window_staff_open(rct_peep* peep) { rct_window* w = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index); if (w == NULL) { @@ -318,7 +318,6 @@ void window_staff_open(rct_peep* peep) w->min_height = WH; w->max_width = 500; w->max_height = 450; - } w->page = 0; window_invalidate(w); @@ -333,6 +332,8 @@ void window_staff_open(rct_peep* peep) window_staff_viewport_init(w); if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED) window_event_mouse_up_call(w, WIDX_CHECKBOX_3); + + return w; } /** diff --git a/src/windows/staff_list.c b/src/windows/staff_list.c index 1da2146008..68c3b8134a 100644 --- a/src/windows/staff_list.c +++ b/src/windows/staff_list.c @@ -23,16 +23,18 @@ #include "../game.h" #include "../drawing/drawing.h" #include "../input.h" +#include "../interface/themes.h" #include "../interface/viewport.h" #include "../interface/widget.h" #include "../interface/window.h" #include "../localisation/localisation.h" #include "../peep/peep.h" #include "../peep/staff.h" +#include "../sprites.h" +#include "../world/footpath.h" #include "../world/sprite.h" #include "dropdown.h" -#include "../interface/themes.h" -#include "../sprites.h" +#include "error.h" enum { WINDOW_STAFF_LIST_TAB_HANDYMEN, @@ -216,14 +218,11 @@ static void window_staff_list_mouseup(rct_window *w, int widgetIndex) break; case WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON: - RCT2_CALLPROC_X(0x006BD9FF, 0, 0, 0, widgetIndex, (int)w, 0, 0); - - // TODO: The code below works, but due to some funny things, when clicking again on the show patrol area button to disable the tool, - // the mouseup event is getting called when it should not be - //tool_set(w, WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON, 0x0C); - //show_gridlines(); - //RCT2_GLOBAL(0x009DEA50, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) | 0x8000; - //gfx_invalidate_screen(); + if (!tool_set(w, WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON, 12)) { + show_gridlines(); + RCT2_GLOBAL(0x009DEA50, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) | 0x8000; + gfx_invalidate_screen(); + } break; case WIDX_STAFF_LIST_MAP: window_map_open(); @@ -327,7 +326,55 @@ void window_staff_list_update(rct_window *w) */ static void window_staff_list_tooldown(rct_window *w, int widgetIndex, int x, int y) { - RCT2_CALLPROC_X(0x006BD990, x, y, 0, widgetIndex, (int)w, 0, 0); + int direction, distance, closestPeepDistance, selectedPeepType; + rct_map_element *mapElement; + rct_peep *peep, *closestPeep; + uint16 spriteIndex; + + if (widgetIndex == WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON) { + selectedPeepType = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); + + footpath_get_coordinates_from_pos(x, y, &x, &y, &direction, &mapElement); + if (x == 0x8000) + return; + + bool isPatrolAreaSet = staff_is_patrol_area_set(200 + selectedPeepType, x, y); + + closestPeep = NULL; + closestPeepDistance = INT_MAX; + FOR_ALL_STAFF(spriteIndex, peep) { + if (peep->staff_type != selectedPeepType) + continue; + + if (isPatrolAreaSet) { + if (!(gStaffModes[peep->staff_id] & 2)) { + continue; + } + if (!mechanic_is_location_in_patrol(peep, x, y)) { + continue; + } + } + + if (peep->x == (sint16)0x8000) { + continue; + } + + distance = abs(x - peep->x) + abs(y - peep->y); + if (distance < closestPeepDistance) { + closestPeepDistance = distance; + closestPeep = peep; + } + } + + if (closestPeep != NULL) { + tool_cancel(); + rct_window *staffWindow = window_staff_open(closestPeep); + window_event_dropdown_call(staffWindow, 11, 0); + } else { + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, rct_string_id) = STR_HANDYMAN_PLURAL + selectedPeepType; + window_error_open(STR_NO_THING_IN_PARK_YET, STR_NONE); + } + } } /**