diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 6df6da5262..b2cca5aa12 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -494,6 +494,17 @@ static constexpr const rct_size16 window_guest_page_sizes[][2] = { }; // clang-format on +static Guest* GetGuest(rct_window* w) +{ + auto guest = GetEntity(w->number); + if (guest == nullptr) + { + window_close(w); + return nullptr; + } + return guest; +} + /** * * rct2: 0x006989E9 @@ -583,7 +594,11 @@ static void window_guest_common_invalidate(rct_window* w) w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - auto peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatNameTo(ft); @@ -605,7 +620,11 @@ static void window_guest_common_invalidate(rct_window* w) */ void window_guest_disable_widgets(rct_window* w) { - Peep* peep = GetEntity(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } uint64_t disabled_widgets = 0; if (peep_can_be_picked_up(peep)) @@ -678,7 +697,11 @@ void window_guest_overview_resize(rct_window* w) */ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex) { - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } switch (widgetIndex) { @@ -796,55 +819,57 @@ void window_guest_viewport_init(rct_window* w) if (w->page != WINDOW_GUEST_OVERVIEW) return; - auto peep = GET_PEEP(w->number); - if (peep != nullptr) + const auto peep = GetGuest(w); + if (peep == nullptr) { - auto focus = viewport_update_smart_guest_follow(w, peep); - bool reCreateViewport = false; - uint16_t origViewportFlags{}; - if (w->viewport != nullptr) + return; + } + + auto focus = viewport_update_smart_guest_follow(w, peep); + bool reCreateViewport = false; + uint16_t origViewportFlags{}; + if (w->viewport != nullptr) + { + // Check all combos, for now skipping y and rot + if (focus.coordinate.x == w->viewport_focus_coordinates.x + && (focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK) == w->viewport_focus_coordinates.y + && focus.coordinate.z == w->viewport_focus_coordinates.z + && focus.coordinate.rotation == w->viewport_focus_coordinates.rotation) + return; + + origViewportFlags = w->viewport->flags; + + reCreateViewport = true; + w->viewport->width = 0; + w->viewport = nullptr; + } + + window_event_invalidate_call(w); + + w->viewport_focus_coordinates.x = focus.coordinate.x; + w->viewport_focus_coordinates.y = focus.coordinate.y; + w->viewport_focus_coordinates.z = focus.coordinate.z; + w->viewport_focus_coordinates.rotation = focus.coordinate.rotation; + + if (peep->State != PEEP_STATE_PICKED && w->viewport == nullptr) + { + auto view_widget = &w->widgets[WIDX_VIEWPORT]; + auto screenPos = ScreenCoordsXY{ view_widget->left + 1 + w->windowPos.x, view_widget->top + 1 + w->windowPos.y }; + int32_t width = view_widget->width() - 1; + int32_t height = view_widget->height() - 1; + + viewport_create( + w, screenPos, width, height, 0, + { focus.coordinate.x, focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK, focus.coordinate.z }, + focus.sprite.type & VIEWPORT_FOCUS_TYPE_MASK, focus.sprite.sprite_id); + if (w->viewport != nullptr && reCreateViewport) { - // Check all combos, for now skipping y and rot - if (focus.coordinate.x == w->viewport_focus_coordinates.x - && (focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK) == w->viewport_focus_coordinates.y - && focus.coordinate.z == w->viewport_focus_coordinates.z - && focus.coordinate.rotation == w->viewport_focus_coordinates.rotation) - return; - - origViewportFlags = w->viewport->flags; - - reCreateViewport = true; - w->viewport->width = 0; - w->viewport = nullptr; - } - - window_event_invalidate_call(w); - - w->viewport_focus_coordinates.x = focus.coordinate.x; - w->viewport_focus_coordinates.y = focus.coordinate.y; - w->viewport_focus_coordinates.z = focus.coordinate.z; - w->viewport_focus_coordinates.rotation = focus.coordinate.rotation; - - if (peep->State != PEEP_STATE_PICKED && w->viewport == nullptr) - { - auto view_widget = &w->widgets[WIDX_VIEWPORT]; - auto screenPos = ScreenCoordsXY{ view_widget->left + 1 + w->windowPos.x, view_widget->top + 1 + w->windowPos.y }; - int32_t width = view_widget->width() - 1; - int32_t height = view_widget->height() - 1; - - viewport_create( - w, screenPos, width, height, 0, - { focus.coordinate.x, focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK, focus.coordinate.z }, - focus.sprite.type & VIEWPORT_FOCUS_TYPE_MASK, focus.sprite.sprite_id); - if (w->viewport != nullptr && reCreateViewport) - { - w->viewport->flags = origViewportFlags; - } - w->flags |= WF_NO_SCROLLING; - w->Invalidate(); + w->viewport->flags = origViewportFlags; } + w->flags |= WF_NO_SCROLLING; w->Invalidate(); } + w->Invalidate(); } /** @@ -872,7 +897,12 @@ static void window_guest_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dp screenCoords = ScreenCoordsXY{ 14, 20 }; - Peep* peep = GET_PEEP(w->number); + const Peep* peep = GetEntity(w->number); + if (peep == nullptr) + { + window_close(w); + return; + } if (peep->AssignedPeepType == PeepType::Staff && peep->StaffType == STAFF_TYPE_ENTERTAINER) screenCoords.y++; @@ -928,7 +958,11 @@ static void window_guest_stats_tab_paint(rct_window* w, rct_drawpixelinfo* dpi) rct_widget* widget = &w->widgets[WIDX_TAB_2]; auto screenCoords = w->windowPos + ScreenCoordsXY{ widget->left, widget->top }; - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } int32_t image_id = get_peep_face_sprite_large(peep); if (w->page == WINDOW_GUEST_STATS) { @@ -1077,7 +1111,11 @@ void window_guest_overview_paint(rct_window* w, rct_drawpixelinfo* dpi) } // Draw the centred label - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatActionTo(ft); @@ -1130,7 +1168,11 @@ void window_guest_overview_invalidate(rct_window* w) { window_guest_common_invalidate(w); - auto peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } w->pressed_widgets &= ~(1 << WIDX_TRACK); if (peep->PeepFlags & PEEP_FLAGS_TRACKING) { @@ -1171,8 +1213,12 @@ void window_guest_overview_update(rct_window* w) widget_invalidate(w, WIDX_TAB_1); widget_invalidate(w, WIDX_TAB_2); - Peep* peep = GET_PEEP(w->number); - if (peep != nullptr && peep->WindowInvalidateFlags & PEEP_INVALIDATE_PEEP_ACTION) + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } + if (peep->WindowInvalidateFlags & PEEP_INVALIDATE_PEEP_ACTION) { peep->WindowInvalidateFlags &= ~PEEP_INVALIDATE_PEEP_ACTION; widget_invalidate(w, WIDX_ACTION_LBL); @@ -1254,8 +1300,11 @@ void window_guest_overview_tool_update(rct_window* w, rct_widgetindex widgetInde w->picked_peep_frame = 0; } - Peep* peep; - peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } uint32_t imageId = g_peep_animation_entries[peep->SpriteType].sprite_animation[PEEP_ACTION_SPRITE_TYPE_UI].base_image; imageId += w->picked_peep_frame >> 2; @@ -1336,7 +1385,11 @@ void window_guest_mouse_up(rct_window* w, rct_widgetindex widgetIndex) void window_guest_stats_update(rct_window* w) { w->frame_no++; - Peep* peep = GET_PEEP(w->number); + auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } peep->WindowInvalidateFlags &= ~PEEP_INVALIDATE_PEEP_STATS; w->Invalidate(); @@ -1389,7 +1442,11 @@ void window_guest_stats_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_debug_tab_paint(w, dpi); // ebx - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } // Not sure why this is not stats widgets // cx dx @@ -1572,32 +1629,33 @@ void window_guest_rides_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_3); - auto peep = GET_PEEP(w->number); - auto guest = peep->AsGuest(); - if (guest != nullptr) + const auto guest = GetGuest(w); + if (guest == nullptr) { - // Every 2048 ticks do a full window_invalidate - int32_t number_of_ticks = gScenarioTicks - peep->TimeInPark; - if (!(number_of_ticks & 0x7FF)) - w->Invalidate(); + return; + } - uint8_t curr_list_position = 0; - for (const auto& ride : GetRideManager()) - { - if (ride.IsRide() && guest->HasRidden(&ride)) - { - w->list_item_positions[curr_list_position] = ride.id; - curr_list_position++; - } - } + // Every 2048 ticks do a full window_invalidate + int32_t number_of_ticks = gScenarioTicks - guest->TimeInPark; + if (!(number_of_ticks & 0x7FF)) + w->Invalidate(); - // If there are new items - if (w->no_list_items != curr_list_position) + uint8_t curr_list_position = 0; + for (const auto& ride : GetRideManager()) + { + if (ride.IsRide() && guest->HasRidden(&ride)) { - w->no_list_items = curr_list_position; - w->Invalidate(); + w->list_item_positions[curr_list_position] = ride.id; + curr_list_position++; } } + + // If there are new items + if (w->no_list_items != curr_list_position) + { + w->no_list_items = curr_list_position; + w->Invalidate(); + } } /** @@ -1690,7 +1748,11 @@ void window_guest_rides_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } // cx dx auto screenCoords = w->windowPos @@ -1770,7 +1832,11 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } // cx dx auto screenCoords = w->windowPos @@ -1866,7 +1932,11 @@ void window_guest_thoughts_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_5); - auto peep = GET_PEEP(w->number); + auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } if (peep->WindowInvalidateFlags & PEEP_INVALIDATE_PEEP_THOUGHTS) { peep->WindowInvalidateFlags &= ~PEEP_INVALIDATE_PEEP_THOUGHTS; @@ -1889,7 +1959,11 @@ void window_guest_thoughts_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } // cx dx auto screenCoords = w->windowPos @@ -1930,7 +2004,11 @@ void window_guest_inventory_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_6); - auto peep = GET_PEEP(w->number); + auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } if (peep->WindowInvalidateFlags & PEEP_INVALIDATE_PEEP_INVENTORY) { peep->WindowInvalidateFlags &= ~PEEP_INVALIDATE_PEEP_INVENTORY; @@ -2062,36 +2140,38 @@ void window_guest_inventory_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - const auto guest = (GET_PEEP(w->number))->AsGuest(); - if (guest != nullptr) + const auto guest = GetGuest(w); + if (guest == nullptr) { - rct_widget* pageBackgroundWidget = &window_guest_inventory_widgets[WIDX_PAGE_BACKGROUND]; - auto screenCoords = w->windowPos + ScreenCoordsXY{ pageBackgroundWidget->left + 4, pageBackgroundWidget->top + 2 }; - int32_t itemNameWidth = pageBackgroundWidget->width() - 8; + return; + } - int32_t maxY = w->windowPos.y + w->height - 22; - int32_t numItems = 0; + rct_widget* pageBackgroundWidget = &window_guest_inventory_widgets[WIDX_PAGE_BACKGROUND]; + auto screenCoords = w->windowPos + ScreenCoordsXY{ pageBackgroundWidget->left + 4, pageBackgroundWidget->top + 2 }; + int32_t itemNameWidth = pageBackgroundWidget->width() - 8; - gfx_draw_string_left(dpi, STR_CARRYING, nullptr, COLOUR_BLACK, screenCoords); - screenCoords.y += 10; + int32_t maxY = w->windowPos.y + w->height - 22; + int32_t numItems = 0; - for (int32_t item = 0; item < SHOP_ITEM_COUNT; item++) - { - if (screenCoords.y >= maxY) - break; - if (!guest->HasItem(item)) - continue; + gfx_draw_string_left(dpi, STR_CARRYING, nullptr, COLOUR_BLACK, screenCoords); + screenCoords.y += 10; - rct_string_id stringId = window_guest_inventory_format_item(guest, item); - screenCoords.y += gfx_draw_string_left_wrapped( - dpi, gCommonFormatArgs, screenCoords, itemNameWidth, stringId, COLOUR_BLACK); - numItems++; - } + for (int32_t item = 0; item < SHOP_ITEM_COUNT; item++) + { + if (screenCoords.y >= maxY) + break; + if (!guest->HasItem(item)) + continue; - if (numItems == 0) - { - gfx_draw_string_left(dpi, STR_NOTHING, nullptr, COLOUR_BLACK, screenCoords); - } + rct_string_id stringId = window_guest_inventory_format_item(guest, item); + screenCoords.y += gfx_draw_string_left_wrapped( + dpi, gCommonFormatArgs, screenCoords, itemNameWidth, stringId, COLOUR_BLACK); + numItems++; + } + + if (numItems == 0) + { + gfx_draw_string_left(dpi, STR_NOTHING, nullptr, COLOUR_BLACK, screenCoords); } } @@ -2119,7 +2199,11 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - auto peep = GET_PEEP(w->number); + const auto peep = GetGuest(w); + if (peep == nullptr) + { + return; + } auto screenCoords = w->windowPos + ScreenCoordsXY{ window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4, window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4 }; diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 44bb7f6298..8e1e274dd1 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -301,6 +301,17 @@ enum class PatrolAreaValue static PatrolAreaValue _staffPatrolAreaPaintValue = PatrolAreaValue::NONE; +static Staff* GetStaff(rct_window* w) +{ + auto staff = GetEntity(w->number); + if (staff == nullptr) + { + window_close(w); + return nullptr; + } + return staff; +} + /** * * rct2: 0x006BEE98 @@ -349,7 +360,11 @@ rct_window* window_staff_open(Peep* peep) */ void window_staff_disable_widgets(rct_window* w) { - Peep* peep = GetEntity(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } uint64_t disabled_widgets = (1 << WIDX_TAB_4); if (peep != nullptr && peep->StaffType == STAFF_TYPE_SECURITY) @@ -442,7 +457,11 @@ void window_staff_set_page(rct_window* w, int32_t page) */ void window_staff_overview_mouseup(rct_window* w, rct_widgetindex widgetIndex) { - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } switch (widgetIndex) { @@ -569,7 +588,11 @@ void window_staff_overview_mousedown(rct_window* w, rct_widgetindex widgetIndex, window_dropdown_show_text(dropdownPos, extray, w->colours[1], 0, 2); gDropdownDefaultIndex = 0; - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } // Disable clear patrol area if no area is set. if (!(gStaffModes[peep->StaffId] & 2)) @@ -592,7 +615,11 @@ void window_staff_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex, // Clear patrol if (dropdownIndex == 1) { - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } for (int32_t i = 0; i < STAFF_PATROL_AREA_SIZE; i++) { gStaffPatrolAreas[peep->StaffId * STAFF_PATROL_AREA_SIZE + i] = 0; @@ -635,7 +662,11 @@ void window_staff_overview_update(rct_window* w) */ static void window_staff_set_order(rct_window* w, int32_t order_id) { - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } uint8_t newOrders = peep->StaffOrders ^ (1 << order_id); auto staffSetOrdersAction = StaffSetOrdersAction(w->number, newOrders); @@ -741,7 +772,11 @@ void window_staff_stats_update(rct_window* w) w->frame_no++; widget_invalidate(w, WIDX_TAB_3); - Peep* peep = GET_PEEP(w->number); + auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } if (peep->WindowInvalidateFlags & PEEP_INVALIDATE_STAFF_STATS) { peep->WindowInvalidateFlags &= ~PEEP_INVALIDATE_STAFF_STATS; @@ -774,7 +809,11 @@ void window_staff_stats_invalidate(rct_window* w) w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatNameTo(ft); @@ -809,7 +848,11 @@ void window_staff_options_invalidate(rct_window* w) w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatNameTo(ft); @@ -885,7 +928,11 @@ void window_staff_overview_invalidate(rct_window* w) w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatNameTo(ft); @@ -948,7 +995,11 @@ void window_staff_overview_paint(rct_window* w, rct_drawpixelinfo* dpi) } // Draw the centred label - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } auto ft = Formatter::Common(); peep->FormatActionTo(ft); rct_widget* widget = &w->widgets[WIDX_BTM_LABEL]; @@ -1024,7 +1075,11 @@ void window_staff_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dpi) screenCoords = ScreenCoordsXY{ 14, 20 }; - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } if (peep->AssignedPeepType == PeepType::Staff && peep->StaffType == STAFF_TYPE_ENTERTAINER) screenCoords.y++; @@ -1091,7 +1146,11 @@ void window_staff_stats_paint(rct_window* w, rct_drawpixelinfo* dpi) window_staff_options_tab_paint(w, dpi); window_staff_stats_tab_paint(w, dpi); - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } auto screenCoords = w->windowPos + ScreenCoordsXY{ window_staff_stats_widgets[WIDX_RESIZE].left + 4, window_staff_stats_widgets[WIDX_RESIZE].top + 4 }; @@ -1173,8 +1232,11 @@ void window_staff_overview_tool_update(rct_window* w, rct_widgetindex widgetInde w->picked_peep_frame = 0; } - Peep* peep; - peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } uint32_t imageId = g_peep_animation_entries[peep->SpriteType].sprite_animation[PEEP_ACTION_SPRITE_TYPE_UI].base_image; imageId += w->picked_peep_frame >> 2; @@ -1327,7 +1389,11 @@ void window_staff_viewport_init(rct_window* w) focus.sprite_id = w->number; - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } if (peep->State == PEEP_STATE_PICKED) { @@ -1398,7 +1464,11 @@ void window_staff_options_mousedown(rct_window* w, rct_widgetindex widgetIndex, return; } - Peep* peep = GET_PEEP(w->number); + const auto peep = GetStaff(w); + if (peep == nullptr) + { + return; + } int32_t checkedIndex = -1; // This will be moved below where Items Checked is when all // of dropdown related functions are finished. This prevents diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index c14c0a5e03..a75782560a 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -479,10 +479,13 @@ void window_staff_list_scrollmousedown(rct_window* w, int32_t scrollIndex, const } else { - auto peep = GET_PEEP(spriteIndex); - auto intent = Intent(WC_PEEP); - intent.putExtra(INTENT_EXTRA_PEEP, peep); - context_open_intent(&intent); + auto peep = GetEntity(spriteIndex); + if (peep != nullptr) + { + auto intent = Intent(WC_PEEP); + intent.putExtra(INTENT_EXTRA_PEEP, peep); + context_open_intent(&intent); + } } break; } @@ -695,7 +698,11 @@ void window_staff_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_ if (y + 11 >= dpi->y) { - auto peep = GET_PEEP(spriteIndex); + auto peep = GetEntity(spriteIndex); + if (peep == nullptr) + { + continue; + } int32_t format = (_quick_fire_mode ? STR_RED_STRINGID : STR_BLACK_STRING); if (i == _windowStaffListHighlightedIndex) diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index 6064c4748c..3d2cc1fc96 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -622,7 +622,7 @@ static void window_title_command_editor_tool_down( if (info.sprite->generic.Is()) { validSprite = true; - auto peep = GET_PEEP(spriteIndex); + auto peep = GetEntity(spriteIndex); if (peep != nullptr) { uint8_t formatArgs[32]{}; diff --git a/src/openrct2/actions/GuestSetFlagsAction.hpp b/src/openrct2/actions/GuestSetFlagsAction.hpp index 27766c0ad3..3b2d508d19 100644 --- a/src/openrct2/actions/GuestSetFlagsAction.hpp +++ b/src/openrct2/actions/GuestSetFlagsAction.hpp @@ -45,7 +45,7 @@ public: GameActionResult::Ptr Query() const override { - Peep* peep = GET_PEEP(_peepId); + Peep* peep = TryGetEntity(_peepId); if (peep == nullptr) { log_error("Used invalid sprite index for peep: %u", static_cast(_peepId)); @@ -56,7 +56,7 @@ public: GameActionResult::Ptr Execute() const override { - Peep* peep = GET_PEEP(_peepId); + Peep* peep = TryGetEntity(_peepId); if (peep == nullptr) { log_error("Used invalid sprite index for peep: %u", static_cast(_peepId)); diff --git a/src/openrct2/actions/GuestSetNameAction.hpp b/src/openrct2/actions/GuestSetNameAction.hpp index fcfe53b717..20aa15cf72 100644 --- a/src/openrct2/actions/GuestSetNameAction.hpp +++ b/src/openrct2/actions/GuestSetNameAction.hpp @@ -72,8 +72,8 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_NAME_GUEST, STR_NONE); } - auto peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Guest) + auto guest = TryGetEntity(_spriteIndex); + if (guest == nullptr) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_NAME_GUEST, STR_NONE); @@ -84,31 +84,26 @@ public: GameActionResult::Ptr Execute() const override { - auto peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Guest) + auto guest = TryGetEntity(_spriteIndex); + if (guest == nullptr) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_NAME_GUEST, STR_NONE); } - auto curName = peep->GetName(); + auto curName = guest->GetName(); if (curName == _name) { return std::make_unique(GA_ERROR::OK, STR_NONE); } - if (!peep->SetName(_name)) + if (!guest->SetName(_name)) { return std::make_unique(GA_ERROR::UNKNOWN, STR_CANT_NAME_GUEST, STR_NONE); } // Easter egg functions are for guests only - Guest* guest = peep->AsGuest(); - - if (guest != nullptr) - { - guest->HandleEasterEggName(); - } + guest->HandleEasterEggName(); gfx_invalidate_screen(); @@ -116,9 +111,9 @@ public: context_broadcast_intent(&intent); auto res = std::make_unique(); - res->Position.x = peep->x; - res->Position.y = peep->y; - res->Position.z = peep->z; + res->Position.x = guest->x; + res->Position.y = guest->y; + res->Position.z = guest->z; return res; } }; diff --git a/src/openrct2/actions/PeepPickupAction.hpp b/src/openrct2/actions/PeepPickupAction.hpp index af4aa68c94..fe8f439411 100644 --- a/src/openrct2/actions/PeepPickupAction.hpp +++ b/src/openrct2/actions/PeepPickupAction.hpp @@ -65,7 +65,7 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); } - Peep* const peep = GET_PEEP(_spriteId); + auto* const peep = TryGetEntity(_spriteId); if (!peep || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP) { log_error("Failed to pick up peep for sprite %d", _spriteId); @@ -124,7 +124,7 @@ public: GameActionResult::Ptr Execute() const override { - Peep* const peep = GET_PEEP(_spriteId); + Peep* const peep = TryGetEntity(_spriteId); if (!peep || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP) { log_error("Failed to pick up peep for sprite %d", _spriteId); diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp index bb9c758703..4ac2457010 100644 --- a/src/openrct2/actions/SetCheatAction.hpp +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -664,7 +664,7 @@ private: { offset++; } - auto peep = GET_PEEP(vehicle->peep[i + offset]); + auto peep = TryGetEntity(vehicle->peep[i + offset]); if (peep != nullptr) { vehicle->mass -= peep->Mass; diff --git a/src/openrct2/actions/StaffFireAction.hpp b/src/openrct2/actions/StaffFireAction.hpp index 99ca31481f..d040777b4e 100644 --- a/src/openrct2/actions/StaffFireAction.hpp +++ b/src/openrct2/actions/StaffFireAction.hpp @@ -47,8 +47,8 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - auto peep = GET_PEEP(_spriteId); - if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteId); + if (staff == nullptr) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -59,14 +59,14 @@ public: GameActionResult::Ptr Execute() const override { - auto peep = GET_PEEP(_spriteId); - if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteId); + if (staff == nullptr) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } window_close_by_class(WC_FIRE_PROMPT); - peep_sprite_remove(peep); + peep_sprite_remove(staff); return MakeResult(); } }; diff --git a/src/openrct2/actions/StaffSetCostumeAction.hpp b/src/openrct2/actions/StaffSetCostumeAction.hpp index cc33042a77..68b1d381f6 100644 --- a/src/openrct2/actions/StaffSetCostumeAction.hpp +++ b/src/openrct2/actions/StaffSetCostumeAction.hpp @@ -73,8 +73,8 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - Peep* peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Staff || peep->StaffType != STAFF_TYPE_ENTERTAINER) + auto* staff = TryGetEntity(_spriteIndex); + if (staff == nullptr) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -91,27 +91,32 @@ public: GameActionResult::Ptr Execute() const override { - Peep* peep = GET_PEEP(_spriteIndex); + auto* staff = TryGetEntity(_spriteIndex); + if (staff == nullptr) + { + log_warning("Invalid game command for sprite %u", _spriteIndex); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } auto spriteType = static_cast(_costume + 4); - peep->SpriteType = spriteType; - peep->PeepFlags &= ~PEEP_FLAGS_SLOW_WALK; + staff->SpriteType = spriteType; + staff->PeepFlags &= ~PEEP_FLAGS_SLOW_WALK; if (peep_slow_walking_types[spriteType]) { - peep->PeepFlags |= PEEP_FLAGS_SLOW_WALK; + staff->PeepFlags |= PEEP_FLAGS_SLOW_WALK; } - peep->ActionFrame = 0; - peep->UpdateCurrentActionSpriteType(); - peep->Invalidate(); + staff->ActionFrame = 0; + staff->UpdateCurrentActionSpriteType(); + staff->Invalidate(); window_invalidate_by_number(WC_PEEP, _spriteIndex); auto intent = Intent(INTENT_ACTION_REFRESH_STAFF_LIST); context_broadcast_intent(&intent); auto res = std::make_unique(); - res->Position.x = peep->x; - res->Position.y = peep->y; - res->Position.z = peep->z; + res->Position.x = staff->x; + res->Position.y = staff->y; + res->Position.z = staff->z; return res; } }; diff --git a/src/openrct2/actions/StaffSetNameAction.hpp b/src/openrct2/actions/StaffSetNameAction.hpp index 7d95532592..7519138155 100644 --- a/src/openrct2/actions/StaffSetNameAction.hpp +++ b/src/openrct2/actions/StaffSetNameAction.hpp @@ -58,8 +58,8 @@ public: GA_ERROR::INVALID_PARAMETERS, STR_STAFF_ERROR_CANT_NAME_STAFF_MEMBER, STR_NONE); } - auto peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteIndex); + if (staff == nullptr) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique( @@ -71,21 +71,21 @@ public: GameActionResult::Ptr Execute() const override { - auto peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteIndex); + if (staff == nullptr) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique( GA_ERROR::INVALID_PARAMETERS, STR_STAFF_ERROR_CANT_NAME_STAFF_MEMBER, STR_NONE); } - auto curName = peep->GetName(); + auto curName = staff->GetName(); if (curName == _name) { return std::make_unique(GA_ERROR::OK, STR_NONE); } - if (!peep->SetName(_name)) + if (!staff->SetName(_name)) { return std::make_unique(GA_ERROR::UNKNOWN, STR_CANT_NAME_GUEST, STR_NONE); } @@ -96,9 +96,9 @@ public: context_broadcast_intent(&intent); auto res = std::make_unique(); - res->Position.x = peep->x; - res->Position.y = peep->y; - res->Position.z = peep->z; + res->Position.x = staff->x; + res->Position.y = staff->y; + res->Position.z = staff->z; return res; } }; diff --git a/src/openrct2/actions/StaffSetOrdersAction.hpp b/src/openrct2/actions/StaffSetOrdersAction.hpp index 1c9405e979..63167a1fcb 100644 --- a/src/openrct2/actions/StaffSetOrdersAction.hpp +++ b/src/openrct2/actions/StaffSetOrdersAction.hpp @@ -53,9 +53,8 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - Peep* peep = GET_PEEP(_spriteIndex); - if (peep->AssignedPeepType != PeepType::Staff - || (peep->StaffType != STAFF_TYPE_HANDYMAN && peep->StaffType != STAFF_TYPE_MECHANIC)) + auto* staff = TryGetEntity(_spriteIndex); + if (staff == nullptr || (staff->StaffType != STAFF_TYPE_HANDYMAN && staff->StaffType != STAFF_TYPE_MECHANIC)) { log_warning("Invalid game command for sprite %u", _spriteIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -66,18 +65,22 @@ public: GameActionResult::Ptr Execute() const override { - Peep* peep = GET_PEEP(_spriteIndex); - - peep->StaffOrders = _ordersId; + auto* staff = TryGetEntity(_spriteIndex); + if (staff == nullptr) + { + log_warning("Invalid game command for sprite %u", _spriteIndex); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + staff->StaffOrders = _ordersId; window_invalidate_by_number(WC_PEEP, _spriteIndex); auto intent = Intent(INTENT_ACTION_REFRESH_STAFF_LIST); context_broadcast_intent(&intent); auto res = std::make_unique(); - res->Position.x = peep->x; - res->Position.y = peep->y; - res->Position.z = peep->z; + res->Position.x = staff->x; + res->Position.y = staff->y; + res->Position.z = staff->z; return res; } }; diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp index 547ae106e7..47eef2e01a 100644 --- a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp @@ -55,8 +55,8 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - auto peep = GET_PEEP(_spriteId); - if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteId); + if (staff == nullptr) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -67,16 +67,16 @@ public: GameActionResult::Ptr Execute() const override { - auto peep = GET_PEEP(_spriteId); - if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->AssignedPeepType != PeepType::Staff) + auto staff = TryGetEntity(_spriteId); + if (staff == nullptr) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - int32_t patrolOffset = peep->StaffId * STAFF_PATROL_AREA_SIZE; + int32_t patrolOffset = staff->StaffId * STAFF_PATROL_AREA_SIZE; - staff_toggle_patrol_area(peep->StaffId, _loc); + staff_toggle_patrol_area(staff->StaffId, _loc); bool isPatrolling = false; for (int32_t i = 0; i < 128; i++) @@ -88,10 +88,10 @@ public: } } - gStaffModes[peep->StaffId] &= ~(1 << 1); + gStaffModes[staff->StaffId] &= ~(1 << 1); if (isPatrolling) { - gStaffModes[peep->StaffId] |= (1 << 1); + gStaffModes[staff->StaffId] |= (1 << 1); } for (int32_t y = 0; y < 4 * COORDS_XY_STEP; y += COORDS_XY_STEP) diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 73c7006042..1561316876 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -469,12 +469,14 @@ static int32_t cc_staff(InteractiveConsole& console, const arguments_t& argv) int_val[0] = console_parse_int(argv[2], &int_valid[0]); int_val[1] = console_parse_int(argv[3], &int_valid[1]); - if (int_valid[0] && int_valid[1] && ((GET_PEEP(int_val[0])) != nullptr)) + if (int_valid[0] && int_valid[1]) { - Peep* peep = GET_PEEP(int_val[0]); - - peep->Energy = int_val[1]; - peep->EnergyTarget = int_val[1]; + Peep* peep = GetEntity(int_val[0]); + if (peep != nullptr) + { + peep->Energy = int_val[1]; + peep->EnergyTarget = int_val[1]; + } } } else if (argv[1] == "costume") @@ -483,16 +485,18 @@ static int32_t cc_staff(InteractiveConsole& console, const arguments_t& argv) bool int_valid[2] = { false }; int_val[0] = console_parse_int(argv[2], &int_valid[0]); int_val[1] = console_parse_int(argv[3], &int_valid[1]); - Peep* peep = nullptr; if (!int_valid[0]) { console.WriteLineError("Invalid staff ID"); return 1; } - peep = GET_PEEP(int_val[0]); - bool is_entertainer = peep != nullptr && peep->AssignedPeepType == PeepType::Staff - && peep->StaffType == STAFF_TYPE_ENTERTAINER; - if (!is_entertainer) + auto staff = GetEntity(int_val[0]); + if (staff == nullptr) + { + console.WriteLineError("Invalid staff ID"); + return 1; + } + if (staff->StaffType != STAFF_TYPE_ENTERTAINER) { console.WriteLineError("Specified staff is not entertainer"); return 1; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 8db9c7c8e7..f10aa62679 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -655,7 +655,14 @@ void viewport_update_smart_sprite_follow(rct_window* window) } else if (entity->sprite_identifier == SPRITE_IDENTIFIER_PEEP) { - Peep* peep = GET_PEEP(window->viewport_smart_follow_sprite); + Peep* peep = TryGetEntity(window->viewport_smart_follow_sprite); + if (peep == nullptr) + { + // will never happen + window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL; + window->viewport_target_sprite = SPRITE_INDEX_NULL; + return; + } if (peep->AssignedPeepType == PeepType::Guest) viewport_update_smart_guest_follow(window, peep); diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index c0bc5e9970..547f163f8f 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -901,12 +901,19 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile if (!is_staff_list) { - Staff* staff = (GET_PEEP(staffIndex))->AsStaff(); - if (!staff->IsPatrolAreaSet(session->MapPosition)) + Staff* staff = GetEntity(staffIndex); + if (staff == nullptr) { - patrolColour = COLOUR_GREY; + log_error("Invalid staff index for draw patrol areas!"); + } + else + { + if (!staff->IsPatrolAreaSet(session->MapPosition)) + { + patrolColour = COLOUR_GREY; + } + staffType = staff->StaffType; } - staffType = staff->StaffType; } if (staff_is_patrol_area_set_for_type(static_cast(staffType), session->MapPosition)) diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index fc9d477fb7..d50fb5cfc7 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1084,12 +1084,19 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c if (!is_staff_list) { - Staff* staff = (GET_PEEP(staffIndex))->AsStaff(); - if (!staff->IsPatrolAreaSet({ x, y })) + Staff* staff = GetEntity(staffIndex); + if (staff == nullptr) { - patrolColour = COLOUR_GREY; + log_error("Invalid staff index for draw patrol areas!"); + } + else + { + if (!staff->IsPatrolAreaSet({ x, y })) + { + patrolColour = COLOUR_GREY; + } + staffType = staff->StaffType; } - staffType = staff->StaffType; } if (staff_is_patrol_area_set_for_type(static_cast(staffType), session->MapPosition)) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index fe39b40cc1..b07b7ce8f6 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -2025,8 +2025,8 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t // Check if there's room in the queue for the peep to enter. if (ride->stations[entranceNum].LastPeepInQueue != SPRITE_INDEX_NULL) { - Peep* lastPeepInQueue = GET_PEEP(ride->stations[entranceNum].LastPeepInQueue); - if (abs(lastPeepInQueue->z - z) <= 6) + Peep* lastPeepInQueue = GetEntity(ride->stations[entranceNum].LastPeepInQueue); + if (lastPeepInQueue != nullptr && (abs(lastPeepInQueue->z - z) <= 6)) { int32_t dx = abs(lastPeepInQueue->x - x); int32_t dy = abs(lastPeepInQueue->y - y); @@ -4081,22 +4081,21 @@ void Guest::UpdateRideEnterVehicle() if (vehicle->IsUsedInPairs()) { - auto* seatedPeep = GET_PEEP(vehicle->peep[CurrentSeat ^ 1]); - if (seatedPeep != nullptr) + auto* seatedGuest = GetEntity(vehicle->peep[CurrentSeat ^ 1]); + if (seatedGuest != nullptr) { - auto* seatedPeepAsGuest = seatedPeep->AsGuest(); - if (seatedPeepAsGuest == nullptr || seatedPeepAsGuest->SubState != PEEP_RIDE_ENTER_VEHICLE) + if (seatedGuest->SubState != PEEP_RIDE_ENTER_VEHICLE) return; vehicle->num_peeps++; ride->cur_num_customers++; - vehicle->mass += seatedPeepAsGuest->Mass; - seatedPeepAsGuest->MoveTo({ LOCATION_NULL, 0, 0 }); - seatedPeepAsGuest->SetState(PEEP_STATE_ON_RIDE); - seatedPeepAsGuest->GuestTimeOnRide = 0; - seatedPeepAsGuest->SubState = PEEP_RIDE_ON_RIDE; - seatedPeepAsGuest->OnEnterRide(CurrentRide); + vehicle->mass += seatedGuest->Mass; + seatedGuest->MoveTo({ LOCATION_NULL, 0, 0 }); + seatedGuest->SetState(PEEP_STATE_ON_RIDE); + seatedGuest->GuestTimeOnRide = 0; + seatedGuest->SubState = PEEP_RIDE_ON_RIDE; + seatedGuest->OnEnterRide(CurrentRide); } } @@ -5569,10 +5568,13 @@ void Guest::UpdateQueuing() // first check if the next in queue is actually nearby // if they are not then it's safe to assume that this is // the front of the queue. - Peep* next_peep = GET_PEEP(GuestNextInQueue); - if (abs(next_peep->x - x) < 32 && abs(next_peep->y - y) < 32) + Peep* nextGuest = GetEntity(GuestNextInQueue); + if (nextGuest != nullptr) { - is_front = false; + if (abs(nextGuest->x - x) < 32 && abs(nextGuest->y - y) < 32) + { + is_front = false; + } } } diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 257fb2ce22..8e6c8d4ffa 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -2219,11 +2219,15 @@ static bool peep_update_queue_position(Peep* peep, uint8_t previous_action) if (peep->GuestNextInQueue == SPRITE_INDEX_NULL) return false; - Peep* peep_next = GET_PEEP(peep->GuestNextInQueue); + auto* guestNext = GetEntity(peep->GuestNextInQueue); + if (guestNext == nullptr) + { + return false; + } - int16_t x_diff = abs(peep_next->x - peep->x); - int16_t y_diff = abs(peep_next->y - peep->y); - int16_t z_diff = abs(peep_next->z - peep->z); + int16_t x_diff = abs(guestNext->x - peep->x); + int16_t y_diff = abs(guestNext->y - peep->y); + int16_t z_diff = abs(guestNext->z - peep->z); if (z_diff > 10) return false; @@ -2240,29 +2244,29 @@ static bool peep_update_queue_position(Peep* peep, uint8_t previous_action) { if (x_diff > 13) { - if ((peep->x & 0xFFE0) != (peep_next->x & 0xFFE0) || (peep->y & 0xFFE0) != (peep_next->y & 0xFFE0)) + if ((peep->x & 0xFFE0) != (guestNext->x & 0xFFE0) || (peep->y & 0xFFE0) != (guestNext->y & 0xFFE0)) return false; } - if (peep->sprite_direction != peep_next->sprite_direction) + if (peep->sprite_direction != guestNext->sprite_direction) return false; - switch (peep_next->sprite_direction / 8) + switch (guestNext->sprite_direction / 8) { case 0: - if (peep->x >= peep_next->x) + if (peep->x >= guestNext->x) return false; break; case 1: - if (peep->y <= peep_next->y) + if (peep->y <= guestNext->y) return false; break; case 2: - if (peep->x <= peep_next->x) + if (peep->x <= guestNext->x) return false; break; case 3: - if (peep->y >= peep_next->y) + if (peep->y >= guestNext->y) return false; break; } @@ -3202,8 +3206,12 @@ rct_string_id get_real_name_string_id_from_id(uint32_t id) int32_t peep_compare(const uint16_t sprite_index_a, const uint16_t sprite_index_b) { - Peep const* peep_a = GET_PEEP(sprite_index_a); - Peep const* peep_b = GET_PEEP(sprite_index_b); + Peep const* peep_a = GetEntity(sprite_index_a); + Peep const* peep_b = GetEntity(sprite_index_b); + if (peep_a == nullptr || peep_b == nullptr) + { + return 0; + } // Compare types if (peep_a->AssignedPeepType != peep_b->AssignedPeepType) @@ -3383,13 +3391,18 @@ void Peep::RemoveFromQueue() auto spriteId = station.LastPeepInQueue; while (spriteId != SPRITE_INDEX_NULL) { - Peep* other_peep = GET_PEEP(spriteId); - if (sprite_index == other_peep->GuestNextInQueue) + auto* otherGuest = GetEntity(spriteId); + if (otherGuest == nullptr) { - other_peep->GuestNextInQueue = GuestNextInQueue; + log_error("Invalid Guest Queue list!"); return; } - spriteId = other_peep->GuestNextInQueue; + if (sprite_index == otherGuest->GuestNextInQueue) + { + otherGuest->GuestNextInQueue = GuestNextInQueue; + return; + } + spriteId = otherGuest->GuestNextInQueue; } } diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 06deb41371..e0a7b9a6fe 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -996,9 +996,6 @@ enum PATHING_RIDE_ENTRANCE = 1 << 3, }; -/** Helper macro until rides are stored in this module. */ -#define GET_PEEP(sprite_index) &(get_sprite(sprite_index)->peep) - // rct2: 0x00982708 extern rct_peep_animation_entry g_peep_animation_entries[PEEP_SPRITE_TYPE_COUNT]; extern const bool gSpriteTypeToSlowWalkMap[48]; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index eecb6c24a3..6a9cd6dfcb 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -2179,8 +2179,11 @@ void Ride::UpdateSpiralSlide() { slide_in_use--; - Peep* peep = GET_PEEP(slide_peep); - peep->DestinationX++; + auto* peep = GetEntity(slide_peep); + if (peep != nullptr) + { + peep->DestinationX++; + } } const uint8_t current_rotation = get_current_rotation(); diff --git a/src/openrct2/ride/Station.cpp b/src/openrct2/ride/Station.cpp index be595ab43b..fb45609475 100644 --- a/src/openrct2/ride/Station.cpp +++ b/src/openrct2/ride/Station.cpp @@ -207,9 +207,12 @@ static void ride_update_station_race(Ride* ride, StationIndex stationIndex) // Found a winner if (vehicle->num_peeps != 0) { - Peep* peep = GET_PEEP(vehicle->peep[0]); - ride->race_winner = peep->sprite_index; - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + auto* peep = GetEntity(vehicle->peep[0]); + if (peep != nullptr) + { + ride->race_winner = peep->sprite_index; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + } } // Race is over diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index ccbdda0818..3552393015 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2992,8 +2992,8 @@ void Vehicle::PeepEasterEggHereWeAre() const vehicle = GET_VEHICLE(spriteId); for (int32_t i = 0; i < vehicle->num_peeps; ++i) { - Peep* curPeep = GET_PEEP(vehicle->peep[i]); - if (curPeep->PeepFlags & PEEP_FLAGS_HERE_WE_ARE) + auto* curPeep = GetEntity(vehicle->peep[i]); + if (curPeep != nullptr && curPeep->PeepFlags & PEEP_FLAGS_HERE_WE_ARE) { curPeep->InsertNewThought(PEEP_THOUGHT_TYPE_HERE_WE_ARE, curPeep->CurrentRide); } @@ -4054,17 +4054,23 @@ void Vehicle::UpdateUnloadingPassengers() { next_free_seat -= 2; - Peep* curPeep = GET_PEEP(peep[seat * 2]); + auto firstGuest = GetEntity(peep[seat * 2]); peep[seat * 2] = SPRITE_INDEX_NULL; - curPeep->SetState(PEEP_STATE_LEAVING_RIDE); - curPeep->SubState = PEEP_RIDE_LEAVE_VEHICLE; + if (firstGuest != nullptr) + { + firstGuest->SetState(PEEP_STATE_LEAVING_RIDE); + firstGuest->SubState = PEEP_RIDE_LEAVE_VEHICLE; + } - curPeep = GET_PEEP(peep[seat * 2 + 1]); + auto secondGuest = GetEntity(peep[seat * 2 + 1]); peep[seat * 2 + 1] = SPRITE_INDEX_NULL; - curPeep->SetState(PEEP_STATE_LEAVING_RIDE); - curPeep->SubState = PEEP_RIDE_LEAVE_VEHICLE; + if (secondGuest != nullptr) + { + secondGuest->SetState(PEEP_STATE_LEAVING_RIDE); + secondGuest->SubState = PEEP_RIDE_LEAVE_VEHICLE; + } } } else @@ -4096,9 +4102,12 @@ void Vehicle::UpdateUnloadingPassengers() train->next_free_seat = 0; for (uint8_t peepIndex = 0; peepIndex < train->num_peeps; peepIndex++) { - Peep* curPeep = GET_PEEP(train->peep[peepIndex]); - curPeep->SetState(PEEP_STATE_LEAVING_RIDE); - curPeep->SubState = PEEP_RIDE_LEAVE_VEHICLE; + Peep* curPeep = GetEntity(train->peep[peepIndex]); + if (curPeep != nullptr) + { + curPeep->SetState(PEEP_STATE_LEAVING_RIDE); + curPeep->SubState = PEEP_RIDE_LEAVE_VEHICLE; + } } } } @@ -5211,7 +5220,10 @@ void Vehicle::KillPassengers(Ride* curRide) for (auto i = 0; i < num_peeps; i++) { - Peep* curPeep = GET_PEEP(peep[i]); + auto* curPeep = GetEntity(peep[i]); + if (curPeep == nullptr) + continue; + if (!curPeep->OutsideOfPark) { decrement_guests_in_park(); @@ -8807,16 +8819,16 @@ loc_6DC743: { if (trackPos.z == 2) { - Peep* curPeep = GET_PEEP(peep[0]); - if (curPeep->Id & 7) + auto* curPeep = GetEntity(peep[0]); + if (curPeep != nullptr && curPeep->Id & 7) { trackPos.z = 7; } } if (trackPos.z == 6) { - Peep* curPeep = GET_PEEP(peep[0]); - if (curPeep->Id & 7) + auto* curPeep = GetEntity(peep[0]); + if (curPeep != nullptr && curPeep->Id & 7) { trackPos.z = 8; } diff --git a/src/openrct2/ride/gentle/FerrisWheel.cpp b/src/openrct2/ride/gentle/FerrisWheel.cpp index 2e8fd2994c..52974c0e3b 100644 --- a/src/openrct2/ride/gentle/FerrisWheel.cpp +++ b/src/openrct2/ride/gentle/FerrisWheel.cpp @@ -112,8 +112,8 @@ static void paint_ferris_wheel_structure( continue; } - Peep* peep = GET_PEEP(vehicle->peep[i]); - if (peep->State != PEEP_STATE_ON_RIDE) + auto* peep = GetEntity(vehicle->peep[i]); + if (peep == nullptr || peep->State != PEEP_STATE_ON_RIDE) { continue; } diff --git a/src/openrct2/ride/gentle/SpaceRings.cpp b/src/openrct2/ride/gentle/SpaceRings.cpp index 6792c1fd13..7dda8064f8 100644 --- a/src/openrct2/ride/gentle/SpaceRings.cpp +++ b/src/openrct2/ride/gentle/SpaceRings.cpp @@ -71,10 +71,13 @@ static void paint_space_rings_structure(paint_session* session, Ride* ride, uint if (vehicle != nullptr && vehicle->num_peeps > 0) { - Peep* rider = GET_PEEP(vehicle->peep[0]); - imageColourFlags = SPRITE_ID_PALETTE_COLOUR_2(rider->TshirtColour, rider->TrousersColour); - imageId = ((baseImageId & 0x7FFFF) + 352 + frameNum) | imageColourFlags; - sub_98199C(session, imageId, 0, 0, 20, 20, 23, height, -10, -10, height); + auto* rider = GetEntity(vehicle->peep[0]); + if (rider != nullptr) + { + imageColourFlags = SPRITE_ID_PALETTE_COLOUR_2(rider->TshirtColour, rider->TrousersColour); + imageId = ((baseImageId & 0x7FFFF) + 352 + frameNum) | imageColourFlags; + sub_98199C(session, imageId, 0, 0, 20, 20, 23, height, -10, -10, height); + } } } diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index 8a006487f3..c290b2665e 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -156,6 +156,12 @@ template<> bool SpriteBase::Is() const return sprite_identifier == SPRITE_IDENTIFIER_PEEP; } +template<> bool SpriteBase::Is() const +{ + auto peep = As(); + return peep && peep->AssignedPeepType == PeepType::Guest; +} + rct_sprite* get_sprite(size_t sprite_idx) { assert(sprite_idx < MAX_SPRITES);