From a3fe00f0a374d8fb960c7d1aa74e57f7b2842389 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 3 Aug 2019 17:27:50 +0100 Subject: [PATCH 1/7] Refactor ride list to a manager with iterator --- .../windows/EditorInventionsList.cpp | 8 +- src/openrct2-ui/windows/Guest.cpp | 41 ++- src/openrct2-ui/windows/NewCampaign.cpp | 78 ++--- src/openrct2-ui/windows/Ride.cpp | 36 ++- src/openrct2/actions/RideCreateAction.hpp | 6 +- src/openrct2/actions/RideSetPriceAction.hpp | 49 +-- src/openrct2/interface/InteractiveConsole.cpp | 11 +- src/openrct2/peep/Guest.cpp | 17 +- src/openrct2/peep/Peep.h | 4 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct2/S6Exporter.cpp | 7 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 287 ++++++++---------- src/openrct2/ride/Ride.h | 99 +++++- src/openrct2/ride/RideRatings.cpp | 11 +- src/openrct2/ride/RideRatings.h | 2 +- src/openrct2/ride/RideTypes.h | 1 + src/openrct2/scenario/Scenario.cpp | 20 +- src/openrct2/world/Park.cpp | 8 +- test/tests/RideRatings.cpp | 39 +-- 20 files changed, 387 insertions(+), 341 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 43fd558152..d521bc2673 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -186,13 +186,9 @@ static void research_rides_setup() } // Set research required for rides in use - for (uint16_t rideIndex = 0; rideIndex < MAX_RIDES; rideIndex++) + for (const auto &ride : GetRideManager()) { - auto ride = get_ride(rideIndex); - if (ride->type != RIDE_TYPE_NULL) - { - Editor::SetSelectedObject(OBJECT_TYPE_RIDE, ride->subtype, OBJECT_SELECTION_FLAG_SELECTED); - } + Editor::SetSelectedObject(OBJECT_TYPE_RIDE, ride.subtype, OBJECT_SELECTION_FLAG_SELECTED); } } diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 5c05f09de0..b35588e437 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1571,34 +1571,31 @@ void window_guest_rides_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_3); - Peep* peep = GET_PEEP(w->number); - - // Every 2048 ticks do a full window_invalidate - int32_t number_of_ticks = gScenarioTicks - peep->time_in_park; - if (!(number_of_ticks & 0x7FF)) - window_invalidate(w); - - uint8_t curr_list_position = 0; - for (ride_id_t ride_id = 0; ride_id < MAX_RIDES; ride_id++) + auto peep = GET_PEEP(w->number); + auto guest = peep->AsGuest(); + if (guest != nullptr) { - // Offset to the ride_id bit in peep_rides_been_on - uint8_t ride_id_bit = ride_id % 8; - uint8_t ride_id_offset = ride_id / 8; - if (peep->rides_been_on[ride_id_offset] & (1 << ride_id_bit)) + // Every 2048 ticks do a full window_invalidate + int32_t number_of_ticks = gScenarioTicks - peep->time_in_park; + if (!(number_of_ticks & 0x7FF)) + window_invalidate(w); + + uint8_t curr_list_position = 0; + for (const auto& ride : GetRideManager()) { - Ride* ride = get_ride(ride_id); - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (guest->HasRidden(&ride) && gRideClassifications[ride.type] == RIDE_CLASS_RIDE) { - w->list_item_positions[curr_list_position] = ride_id; + 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; - window_invalidate(w); + + // If there are new items + if (w->no_list_items != curr_list_position) + { + w->no_list_items = curr_list_position; + window_invalidate(w); + } } } diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index 78748c3ec5..72a4448b7f 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -89,7 +89,7 @@ static rct_window_event_list window_new_campaign_events = { }; // clang-format on -static uint8_t window_new_campaign_rides[MAX_RIDES]; +static std::vector window_new_campaign_rides; static uint8_t window_new_campaign_shop_items[64]; static int32_t ride_value_compare(const void* a, const void* b) @@ -116,11 +116,7 @@ static int32_t ride_name_compare(const void* a, const void* b) */ rct_window* window_new_campaign_open(int16_t campaignType) { - rct_window* w; - Ride* ride; - int32_t i, numApplicableRides; - - w = window_bring_to_front_by_class(WC_NEW_CAMPAIGN); + auto w = window_bring_to_front_by_class(WC_NEW_CAMPAIGN); if (w != nullptr) { if (w->campaign.campaign_type == campaignType) @@ -148,36 +144,30 @@ rct_window* window_new_campaign_open(int16_t campaignType) w->campaign.ride_id = SELECTED_RIDE_UNDEFINED; // Get all applicable rides - numApplicableRides = 0; - window_new_campaign_rides[0] = RIDE_ID_NULL; - FOR_ALL_RIDES (i, ride) + window_new_campaign_rides.clear(); + for (const auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_OPEN) + if (ride.status == RIDE_STATUS_OPEN) { - continue; + if (!ride_type_has_flag( + ride.type, + RIDE_TYPE_FLAG_IS_SHOP | RIDE_TYPE_FLAG_SELLS_FOOD | RIDE_TYPE_FLAG_SELLS_DRINKS + | RIDE_TYPE_FLAG_IS_BATHROOM)) + { + window_new_campaign_rides.push_back(ride.id); + } } - if (ride_type_has_flag( - ride->type, - RIDE_TYPE_FLAG_IS_SHOP | RIDE_TYPE_FLAG_SELLS_FOOD | RIDE_TYPE_FLAG_SELLS_DRINKS | RIDE_TYPE_FLAG_IS_BATHROOM)) - { - continue; - } - - window_new_campaign_rides[numApplicableRides++] = i; } // Take top 128 most valuable rides - if (numApplicableRides > DROPDOWN_ITEMS_MAX_SIZE) + if (window_new_campaign_rides.size() > DROPDOWN_ITEMS_MAX_SIZE) { - qsort(window_new_campaign_rides, numApplicableRides, sizeof(uint8_t), ride_value_compare); - numApplicableRides = DROPDOWN_ITEMS_MAX_SIZE; + qsort(window_new_campaign_rides.data(), window_new_campaign_rides.size(), sizeof(ride_id_t), ride_value_compare); + window_new_campaign_rides.resize(DROPDOWN_ITEMS_MAX_SIZE); } // Sort rides by name - qsort(window_new_campaign_rides, numApplicableRides, sizeof(uint8_t), ride_name_compare); - - window_new_campaign_rides[numApplicableRides] = RIDE_ID_NULL; - + qsort(window_new_campaign_rides.data(), window_new_campaign_rides.size(), sizeof(ride_id_t), ride_name_compare); return w; } @@ -279,27 +269,25 @@ static void window_new_campaign_mousedown(rct_window* w, rct_widgetindex widgetI else { int32_t numItems = 0; - for (int32_t i = 0; i < DROPDOWN_ITEMS_MAX_SIZE; i++) + for (auto rideId : window_new_campaign_rides) { - if (window_new_campaign_rides[i] == RIDE_ID_NULL) - break; - - auto ride = get_ride(window_new_campaign_rides[i]); - if (ride == nullptr) - break; - - // HACK until dropdown items have longer argument buffers - gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; - if (ride->custom_name.empty()) + auto ride = get_ride(rideId); + if (ride != nullptr) { - ride->FormatNameTo(&gDropdownItemsArgs[i]); + // HACK until dropdown items have longer argument buffers + gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; + if (ride->custom_name.empty()) + { + ride->FormatNameTo(&gDropdownItemsArgs[numItems]); + } + else + { + gDropdownItemsFormat[numItems] = STR_OPTIONS_DROPDOWN_ITEM; + set_format_arg_on( + (uint8_t*)&gDropdownItemsArgs[numItems], 0, const char*, ride->custom_name.c_str()); + } + numItems++; } - else - { - gDropdownItemsFormat[i] = STR_OPTIONS_DROPDOWN_ITEM; - set_format_arg_on((uint8_t*)&gDropdownItemsArgs[i], 0, const char*, ride->custom_name.c_str()); - } - numItems++; } window_dropdown_show_text_custom_width( @@ -328,7 +316,7 @@ static void window_new_campaign_dropdown(rct_window* w, rct_widgetindex widgetIn if (widgetIndex != WIDX_RIDE_DROPDOWN_BUTTON) return; - if (dropdownIndex == -1) + if (dropdownIndex < 0 || dropdownIndex >= window_new_campaign_rides.size()) return; if (w->campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 4fbd95d0c7..971f80b797 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -958,7 +958,7 @@ struct ride_overall_view { uint8_t zoom; }; -static ride_overall_view ride_overall_views[MAX_RIDES] = {}; +static std::vector ride_overall_views = {}; static constexpr const int32_t window_ride_tab_animation_divisor[] = { 0, 0, 2, 2, 4, 2, 8, 8, 2, 0 }; static constexpr const int32_t window_ride_tab_animation_frames[] = { 0, 0, 4, 16, 8, 16, 8, 8, 8, 0 }; @@ -1498,10 +1498,15 @@ static void window_ride_update_overall_view(Ride* ride) maxz = std::max(maxz, z2); } - auto view = &ride_overall_views[ride->id]; - view->x = (minx + maxx) / 2 + 16; - view->y = (miny + maxy) / 2 + 16; - view->z = (minz + maxz) / 2 - 8; + if (ride->id >= ride_overall_views.size()) + { + ride_overall_views.resize(ride->id + 1); + } + + auto& view = ride_overall_views[ride->id]; + view.x = (minx + maxx) / 2 + 16; + view.y = (miny + maxy) / 2 + 16; + view.z = (minz + maxz) / 2 - 8; // Calculate size to determine from how far away to view the ride int32_t dx = maxx - minx; @@ -1514,12 +1519,12 @@ static void window_ride_update_overall_view(Ride* ride) { // Each farther zoom level shows twice as many tiles (log) // Appropriate zoom is lowered by one to fill the entire view with the ride - view->zoom = std::clamp(std::ceil(std::log(size / 80)) - 1, 0, 3); + view.zoom = std::clamp(std::ceil(std::log(size / 80)) - 1, 0, 3); } else { // Small rides or stalls are zoomed in all the way. - view->zoom = 0; + view.zoom = 0; } } @@ -1906,14 +1911,15 @@ static void window_ride_init_viewport(rct_window* w) w->viewport_focus_coordinates.var_480 = 0; } - ride_overall_view* view = &ride_overall_views[w->number]; - - focus.coordinate.x = view->x; - focus.coordinate.y = view->y; - focus.coordinate.z = view->z; - focus.coordinate.zoom = view->zoom; - - focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE; + if (w->number < ride_overall_views.size()) + { + const auto& view = ride_overall_views[w->number]; + focus.coordinate.x = view.x; + focus.coordinate.y = view.y; + focus.coordinate.z = view.z; + focus.coordinate.zoom = view.zoom; + focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE; + } } focus.coordinate.var_480 = w->viewport_focus_coordinates.var_480; diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 759683d904..e631af55d4 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -74,7 +74,7 @@ public: GameActionResult::Ptr Query() const override { - ride_id_t rideIndex = ride_get_empty_slot(); + auto rideIndex = GetNextFreeRideId(); if (rideIndex == RIDE_ID_NULL) { // No more free slots available. @@ -119,11 +119,11 @@ public: auto res = MakeResult(); int32_t rideEntryIndex = ride_get_entry_index(_rideType, _subType); - ride_id_t rideIndex = ride_get_empty_slot(); + auto rideIndex = GetNextFreeRideId(); res->rideIndex = rideIndex; - auto ride = get_ride(rideIndex); + auto ride = GetOrAllocateRide(rideIndex); rideEntry = get_ride_entry(rideEntryIndex); if (rideEntry == nullptr) { diff --git a/src/openrct2/actions/RideSetPriceAction.hpp b/src/openrct2/actions/RideSetPriceAction.hpp index bee8a205e8..cc056176a0 100644 --- a/src/openrct2/actions/RideSetPriceAction.hpp +++ b/src/openrct2/actions/RideSetPriceAction.hpp @@ -159,35 +159,42 @@ public: private: void RideSetCommonPrice(int32_t shopItem) const { - Ride* ride = get_ride(0); - for (uint8_t rideId = 0; rideId < MAX_RIDES; rideId++, ride++) + for (auto& ride : GetRideManager()) { - // Unplaced rides have a type of NULL - if (ride->type == RIDE_TYPE_NULL) - continue; - - rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); - - if (ride->type != RIDE_TYPE_TOILETS || shopItem != SHOP_ITEM_ADMISSION) + auto invalidate = false; + auto rideEntry = get_ride_entry(ride.subtype); + if (ride.type == RIDE_TYPE_TOILETS && shopItem == SHOP_ITEM_ADMISSION) { - if (rideEntry->shop_item == shopItem) + if (ride.price != _price) { - ride->price = _price; - window_invalidate_by_number(WC_RIDE, rideId); + ride.price = _price; + invalidate = true; } } - else + else if (rideEntry != nullptr && rideEntry->shop_item == shopItem) { - ride->price = _price; - window_invalidate_by_number(WC_RIDE, rideId); + if (ride.price != _price) + { + ride.price = _price; + invalidate = true; + } } - - // If the shop item is the same or an on-ride photo - if (rideEntry->shop_item_secondary == shopItem - || (rideEntry->shop_item_secondary == SHOP_ITEM_NONE && shop_item_is_photo(shopItem))) + if (rideEntry != nullptr) { - ride->price_secondary = _price; - window_invalidate_by_number(WC_RIDE, rideId); + // If the shop item is the same or an on-ride photo + if (rideEntry->shop_item_secondary == shopItem + || (rideEntry->shop_item_secondary == SHOP_ITEM_NONE && shop_item_is_photo(shopItem))) + { + if (ride.price_secondary != _price) + { + ride.price_secondary = _price; + invalidate = true; + } + } + } + if (invalidate) + { + window_invalidate_by_number(WC_RIDE, ride.id); } } } diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 7b22bd82e9..47865996c9 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1225,16 +1225,7 @@ static int32_t cc_show_limits(InteractiveConsole& console, [[maybe_unused]] cons map_reorganise_elements(); int32_t tileElementCount = gNextFreeTileElement - gTileElements - 1; - int32_t rideCount = 0; - for (int32_t i = 0; i < MAX_RIDES; ++i) - { - Ride* ride = get_ride(i); - if (ride->type != RIDE_TYPE_NULL) - { - rideCount++; - } - } - + int32_t rideCount = ride_get_count(); int32_t spriteCount = 0; for (int32_t i = 1; i < SPRITE_LIST_COUNT; ++i) { diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 269cf1bd1f..50f1833e83 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1883,18 +1883,17 @@ Ride* Guest::FindBestRideToGoOn() // Pick the most exciting ride auto rideConsideration = FindRidesToGoOn(); Ride* mostExcitingRide = nullptr; - for (int32_t i = 0; i < MAX_RIDES; i++) + for (auto& ride : GetRideManager()) { - if (rideConsideration[i]) + if (rideConsideration.size() > ride.id && rideConsideration[ride.id]) { - auto ride = get_ride(i); - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) + if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) { - if (ShouldGoOnRide(ride, 0, false, true) && ride_has_ratings(ride)) + if (ShouldGoOnRide(&ride, 0, false, true) && ride_has_ratings(&ride)) { - if (mostExcitingRide == nullptr || ride->excitement > mostExcitingRide->excitement) + if (mostExcitingRide == nullptr || ride.excitement > mostExcitingRide->excitement) { - mostExcitingRide = ride; + mostExcitingRide = &ride; } } } @@ -2372,13 +2371,13 @@ void Guest::SpendMoney(money16& peep_expend_type, money32 amount) audio_play_sound_at_location(SoundId::Purchase, x, y, z); } -void Guest::SetHasRidden(Ride* ride) +void Guest::SetHasRidden(const Ride* ride) { rides_been_on[ride->id / 8] |= 1 << (ride->id % 8); SetHasRiddenRideType(ride->type); } -bool Guest::HasRidden(Ride* ride) const +bool Guest::HasRidden(const Ride* ride) const { return rides_been_on[ride->id / 8] & (1 << (ride->id % 8)); } diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index d8bd7bfcef..24f698c623 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -763,8 +763,8 @@ public: bool UpdateWalkingFindBin(); void SpendMoney(money16& peep_expend_type, money32 amount); void SpendMoney(money32 amount); - void SetHasRidden(Ride* ride); - bool HasRidden(Ride* ride) const; + void SetHasRidden(const Ride* ride); + bool HasRidden(const Ride* ride) const; void SetHasRiddenRideType(int32_t rideType); bool HasRiddenRideType(int32_t rideType) const; int32_t HasFoodStandardFlag() const; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index c3940367ae..7776be6070 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -741,7 +741,7 @@ private: { if (_s4.rides[i].type != RIDE_TYPE_NULL) { - ImportRide(get_ride(i), &_s4.rides[i], i); + ImportRide(GetOrAllocateRide(i), &_s4.rides[i], i); } } } diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 5d7554e24c..b2acae8725 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -462,9 +462,14 @@ void S6Exporter::ExportParkName() void S6Exporter::ExportRides() { + const Ride nullRide{}; for (int32_t index = 0; index < RCT12_MAX_RIDES_IN_PARK; index++) { - auto src = get_ride(index); + const auto* src = get_ride(index); + if (src == nullptr) + { + src = &nullRide; + } auto dst = &_s6.rides[index]; *dst = {}; if (src->type == RIDE_TYPE_NULL) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index c413877193..bb80667f2a 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -482,7 +482,7 @@ public: auto src = &_s6.rides[index]; if (src->type != RIDE_TYPE_NULL) { - auto dst = get_ride(index); + auto dst = GetOrAllocateRide(index); ImportRide(dst, src, index); } } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index d6b78fb3ea..3c65cecf4f 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -150,7 +150,7 @@ static constexpr const int32_t RideInspectionInterval[] = { 10, 20, 30, 45, 60, 120, 0, 0, }; -Ride gRideList[MAX_RIDES]; +static std::vector _rides; uint16_t gRideCount; bool gGotoStartPlacementMode = false; @@ -212,18 +212,65 @@ static void ride_music_update(Ride* ride); static void ride_shop_connected(Ride* ride); void loc_6DDF9C(Ride* ride, TileElement* tileElement); -Ride* get_ride(int32_t index) +RideManager GetRideManager() { - if (index < 0 || index >= MAX_RIDES) + return {}; +} + +RideManager::Iterator RideManager::begin() +{ + return RideManager::Iterator(*this, 0, _rides.size()); +} + +RideManager::Iterator RideManager::end() +{ + return RideManager::Iterator(*this, _rides.size(), _rides.size()); +} + +ride_id_t GetNextFreeRideId() +{ + size_t result = _rides.size(); + for (size_t i = 0; i < _rides.size(); i++) { - log_error("invalid index %d for ride", index); - return nullptr; + if (_rides[i].type == RIDE_TYPE_NULL) + { + result = i; + break; + } } - auto ride = &gRideList[index]; -#ifdef DEBUG - assert(ride->id == index); -#endif - return ride; + if (result >= RIDE_ID_NULL) + { + return RIDE_ID_NULL; + } + return (ride_id_t)result; +} + +Ride* GetOrAllocateRide(ride_id_t index) +{ + Ride* result{}; + if (index < _rides.size()) + { + result = &_rides[index]; + } + else + { + result = &_rides.emplace_back(); + } + result->id = index; + return result; +} + +Ride* get_ride(ride_id_t index) +{ + if (index < _rides.size()) + { + auto& ride = _rides[index]; + if (ride.type != RIDE_TYPE_NULL) + { + return &ride; + } + } + return nullptr; } rct_ride_entry* get_ride_entry(int32_t index) @@ -321,12 +368,11 @@ uint8_t* get_ride_entry_indices_for_ride_type(uint8_t rideType) int32_t ride_get_count() { - Ride* ride; - int32_t i, count = 0; - - FOR_ALL_RIDES (i, ride) + int32_t count = 0; + for ([[maybe_unused]] auto& ride : GetRideManager()) + { count++; - + } return count; } @@ -398,13 +444,11 @@ void Ride::QueueInsertGuestAtFront(int32_t stationIndex, Peep* peep) */ void ride_update_favourited_stat() { - int32_t i; - Ride* ride; uint16_t spriteIndex; Peep* peep; - FOR_ALL_RIDES (i, ride) - ride->guests_favourite = 0; + for (auto& ride : GetRideManager()) + ride.guests_favourite = 0; FOR_ALL_PEEPS (spriteIndex, peep) { @@ -412,9 +456,12 @@ void ride_update_favourited_stat() return; if (peep->favourite_ride != RIDE_ID_NULL) { - ride = get_ride(peep->favourite_ride); - ride->guests_favourite++; - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_CUSTOMER; + auto ride = get_ride(peep->favourite_ride); + if (ride != nullptr) + { + ride->guests_favourite++; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_CUSTOMER; + } } } @@ -952,13 +999,8 @@ bool Ride::SupportsStatus(int32_t s) const */ void ride_init_all() { - for (int32_t i = 0; i < MAX_RIDES; i++) - { - auto ride = &gRideList[i]; - *ride = {}; - ride->id = i; - ride->type = RIDE_TYPE_NULL; - } + _rides.clear(); + _rides.shrink_to_fit(); } /** @@ -967,11 +1009,8 @@ void ride_init_all() */ void reset_all_ride_build_dates() { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - ride->build_date -= gDateMonthsElapsed; + for (auto& ride : GetRideManager()) + ride.build_date -= gDateMonthsElapsed; } #pragma endregion @@ -2058,23 +2097,20 @@ int32_t ride_initialise_construction_window(Ride* ride) */ void Ride::UpdateAll() { - Ride* ride; - int32_t i; - // Remove all rides if scenario editor if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) { if (gS6Info.editor_step <= EDITOR_STEP_INVENTIONS_LIST_SET_UP) - FOR_ALL_RIDES (i, ride) - ride->Delete(); + for (auto& ride : GetRideManager()) + ride.Delete(); return; } window_update_viewport_ride_music(); // Update rides - FOR_ALL_RIDES (i, ride) - ride->Update(); + for (auto& ride : GetRideManager()) + ride.Update(); ride_music_update_final(); } @@ -3040,13 +3076,10 @@ void ride_measurements_update() return; // For each ride measurement - ride_id_t i{}; - Ride* ride{}; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - auto measurement = ride->measurement.get(); - if (measurement != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) - && ride->status != RIDE_STATUS_SIMULATING) + auto measurement = ride.measurement.get(); + if (measurement != nullptr && (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) && ride.status != RIDE_STATUS_SIMULATING) { if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) { @@ -3055,9 +3088,9 @@ void ride_measurements_update() else { // For each vehicle - for (int32_t j = 0; j < ride->num_vehicles; j++) + for (int32_t j = 0; j < ride.num_vehicles; j++) { - uint16_t vehicleSpriteIdx = ride->vehicles[j]; + uint16_t vehicleSpriteIdx = ride.vehicles[j]; if (vehicleSpriteIdx != SPRITE_INDEX_NULL) { auto vehicle = GET_VEHICLE(vehicleSpriteIdx); @@ -3086,17 +3119,15 @@ static void ride_free_old_measurements() size_t numRideMeasurements; do { - ride_id_t i{}; - Ride* ride{}; Ride* lruRide{}; numRideMeasurements = 0; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->measurement != nullptr) + if (ride.measurement != nullptr) { - if (lruRide == nullptr || ride->measurement->last_use_tick > lruRide->measurement->last_use_tick) + if (lruRide == nullptr || ride.measurement->last_use_tick > lruRide->measurement->last_use_tick) { - lruRide = ride; + lruRide = &ride; } numRideMeasurements++; } @@ -3175,13 +3206,11 @@ vehicle_colour ride_get_vehicle_colour(Ride* ride, int32_t vehicleIndex) static bool ride_does_vehicle_colour_exist(uint8_t ride_sub_type, vehicle_colour* vehicleColour) { - int32_t i; - Ride* ride2; - FOR_ALL_RIDES (i, ride2) + for (auto& ride : GetRideManager()) { - if (ride2->subtype != ride_sub_type) + if (ride.subtype != ride_sub_type) continue; - if (ride2->vehicle_colours[0].Body != vehicleColour->main) + if (ride.vehicle_colours[0].Body != vehicleColour->main) continue; return false; } @@ -3262,20 +3291,17 @@ void ride_set_vehicle_colours_to_random_preset(Ride* ride, uint8_t preset_index) */ void ride_check_all_reachable() { - Ride* ride; - int32_t i; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->connected_message_throttle != 0) - ride->connected_message_throttle--; - if (ride->status != RIDE_STATUS_OPEN || ride->connected_message_throttle != 0) + if (ride.connected_message_throttle != 0) + ride.connected_message_throttle--; + if (ride.status != RIDE_STATUS_OPEN || ride.connected_message_throttle != 0) continue; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) - ride_shop_connected(ride); + if (ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_IS_SHOP)) + ride_shop_connected(&ride); else - ride_entrance_exit_connected(ride); + ride_entrance_exit_connected(&ride); } } @@ -5660,19 +5686,6 @@ void Ride::StopGuestsQueuing() } } -ride_id_t ride_get_empty_slot() -{ - for (ride_id_t i = 0; i < MAX_RIDES; i++) - { - Ride* ride = get_ride(i); - if (ride->type == RIDE_TYPE_NULL) - { - return i; - } - } - return RIDE_ID_NULL; -} - uint8_t Ride::GetDefaultMode() const { const rct_ride_entry* rideEntry = get_ride_entry(subtype); @@ -5695,18 +5708,15 @@ uint8_t Ride::GetDefaultMode() const static bool ride_with_colour_config_exists(uint8_t ride_type, const TrackColour* colours) { - Ride* ride; - int32_t i; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->type != ride_type) + if (ride.type != ride_type) continue; - if (ride->track_colour[0].main != colours->main) + if (ride.track_colour[0].main != colours->main) continue; - if (ride->track_colour[0].additional != colours->additional) + if (ride.track_colour[0].additional != colours->additional) continue; - if (ride->track_colour[0].supports != colours->supports) + if (ride.track_colour[0].supports != colours->supports) continue; return true; @@ -5719,15 +5729,13 @@ bool Ride::NameExists(const std::string_view& name, ride_id_t excludeRideId) char buffer[256]{}; uint32_t formatArgs[32]{}; - Ride* ride; - int32_t i; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (i != excludeRideId) + if (ride.id != excludeRideId) { - ride->FormatNameTo(formatArgs); + ride.FormatNameTo(formatArgs); format_string(buffer, 256, STR_STRINGID, formatArgs); - if (std::string_view(buffer) == name && ride_has_any_track_elements(ride)) + if (std::string_view(buffer) == name && ride_has_any_track_elements(&ride)) { return true; } @@ -5796,14 +5804,11 @@ void Ride::SetColourPreset(uint8_t index) money32 ride_get_common_price(Ride* forRide) { - Ride* ride; - int32_t i; - - FOR_ALL_RIDES (i, ride) + for (const auto& ride : GetRideManager()) { - if (ride->type == forRide->type && ride != forRide) + if (ride.type == forRide->type && &ride != forRide) { - return ride->price; + return ride.price; } } @@ -6112,24 +6117,6 @@ bool ride_has_any_track_elements(const Ride* ride) return false; } -void ride_all_has_any_track_elements(bool* rideIndexArray) -{ - tile_element_iterator it; - - std::fill_n(rideIndexArray, MAX_RIDES, false); - - tile_element_iterator_begin(&it); - while (tile_element_iterator_next(&it)) - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - if (it.element->IsGhost()) - continue; - - rideIndexArray[it.element->AsTrack()->GetRideIndex()] = true; - } -} - /** * * rct2: 0x006847BA @@ -7240,11 +7227,9 @@ void Ride::Crash(uint8_t vehicleIndex) void ride_reset_all_names() { - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - ride->SetNameToDefault(); + ride.SetNameToDefault(); } } @@ -7615,13 +7600,11 @@ int32_t get_booster_speed(uint8_t rideType, int32_t rawSpeed) void fix_invalid_vehicle_sprite_sizes() { - Ride* ride; - uint16_t i; - FOR_ALL_RIDES (i, ride) + for (const auto& ride : GetRideManager()) { for (uint16_t j = 0; j < MAX_VEHICLES_PER_RIDE; j++) { - uint16_t rideSpriteIndex = ride->vehicles[j]; + uint16_t rideSpriteIndex = ride.vehicles[j]; while (rideSpriteIndex != SPRITE_INDEX_NULL) { rct_vehicle* vehicle = try_get_vehicle(rideSpriteIndex); @@ -7727,14 +7710,12 @@ void determine_ride_entrance_and_exit_locations() { log_verbose("Inspecting ride entrance / exit locations"); - ride_id_t rideIndex; - Ride* ride; - FOR_ALL_RIDES (rideIndex, ride) + for (auto& ride : GetRideManager()) { for (int32_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) { - TileCoordsXYZD entranceLoc = ride->stations[stationIndex].Entrance; - TileCoordsXYZD exitLoc = ride->stations[stationIndex].Exit; + TileCoordsXYZD entranceLoc = ride.stations[stationIndex].Entrance; + TileCoordsXYZD exitLoc = ride.stations[stationIndex].Exit; bool fixEntrance = false; bool fixExit = false; @@ -7744,14 +7725,14 @@ void determine_ride_entrance_and_exit_locations() const EntranceElement* entranceElement = map_get_ride_entrance_element_at( entranceLoc.x * 32, entranceLoc.y * 32, entranceLoc.z, false); - if (entranceElement == nullptr || entranceElement->GetRideIndex() != rideIndex + if (entranceElement == nullptr || entranceElement->GetRideIndex() != ride.id || entranceElement->GetStationIndex() != stationIndex) { fixEntrance = true; } else { - ride->stations[stationIndex].Entrance.direction = (uint8_t)entranceElement->GetDirection(); + ride.stations[stationIndex].Entrance.direction = (uint8_t)entranceElement->GetDirection(); } } @@ -7760,14 +7741,14 @@ void determine_ride_entrance_and_exit_locations() const EntranceElement* entranceElement = map_get_ride_exit_element_at( exitLoc.x * 32, exitLoc.y * 32, entranceLoc.z, false); - if (entranceElement == nullptr || entranceElement->GetRideIndex() != rideIndex + if (entranceElement == nullptr || entranceElement->GetRideIndex() != ride.id || entranceElement->GetStationIndex() != stationIndex) { fixExit = true; } else { - ride->stations[stationIndex].Exit.direction = (uint8_t)entranceElement->GetDirection(); + ride.stations[stationIndex].Exit.direction = (uint8_t)entranceElement->GetDirection(); } } @@ -7795,7 +7776,7 @@ void determine_ride_entrance_and_exit_locations() continue; } const EntranceElement* entranceElement = tileElement->AsEntrance(); - if (entranceElement->GetRideIndex() != rideIndex) + if (entranceElement->GetRideIndex() != ride.id) { continue; } @@ -7805,15 +7786,15 @@ void determine_ride_entrance_and_exit_locations() } // The expected height is where entrances and exit reside in non-hacked parks. - const uint8_t expectedHeight = ride->stations[stationIndex].Height; + const uint8_t expectedHeight = ride.stations[stationIndex].Height; if (fixEntrance && entranceElement->GetEntranceType() == ENTRANCE_TYPE_RIDE_ENTRANCE) { if (alreadyFoundEntrance) { - if (ride->stations[stationIndex].Entrance.z == expectedHeight) + if (ride.stations[stationIndex].Entrance.z == expectedHeight) continue; - if (ride->stations[stationIndex].Entrance.z > entranceElement->base_height) + if (ride.stations[stationIndex].Entrance.z > entranceElement->base_height) continue; } @@ -7824,31 +7805,31 @@ void determine_ride_entrance_and_exit_locations() entranceElement->base_height, (uint8_t)entranceElement->GetDirection(), }; - ride_set_entrance_location(ride, stationIndex, newEntranceLoc); + ride_set_entrance_location(&ride, stationIndex, newEntranceLoc); alreadyFoundEntrance = true; log_verbose( - "Fixed disconnected entrance of ride %d, station %d to x = %d, y = %d and z = %d.", - rideIndex, stationIndex, x, y, entranceElement->base_height); + "Fixed disconnected entrance of ride %d, station %d to x = %d, y = %d and z = %d.", ride.id, + stationIndex, x, y, entranceElement->base_height); } else if (fixExit && entranceElement->GetEntranceType() == ENTRANCE_TYPE_RIDE_EXIT) { if (alreadyFoundExit) { - if (ride->stations[stationIndex].Exit.z == expectedHeight) + if (ride.stations[stationIndex].Exit.z == expectedHeight) continue; - if (ride->stations[stationIndex].Exit.z > entranceElement->base_height) + if (ride.stations[stationIndex].Exit.z > entranceElement->base_height) continue; } // Found our exit ride_set_exit_location( - ride, stationIndex, + &ride, stationIndex, { x, y, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() }); alreadyFoundExit = true; log_verbose( - "Fixed disconnected exit of ride %d, station %d to x = %d, y = %d and z = %d.", rideIndex, + "Fixed disconnected exit of ride %d, station %d to x = %d, y = %d and z = %d.", ride.id, stationIndex, x, y, entranceElement->base_height); } } while (!(tileElement++)->IsLastForTile()); @@ -7858,13 +7839,13 @@ void determine_ride_entrance_and_exit_locations() if (fixEntrance && !alreadyFoundEntrance) { - ride_clear_entrance_location(ride, stationIndex); - log_verbose("Cleared disconnected entrance of ride %d, station %d.", rideIndex, stationIndex); + ride_clear_entrance_location(&ride, stationIndex); + log_verbose("Cleared disconnected entrance of ride %d, station %d.", ride.id, stationIndex); } if (fixExit && !alreadyFoundExit) { - ride_clear_exit_location(ride, stationIndex); - log_verbose("Cleared disconnected exit of ride %d, station %d.", rideIndex, stationIndex); + ride_clear_exit_location(&ride, stationIndex); + log_verbose("Cleared disconnected exit of ride %d, station %d.", ride.id, stationIndex); } } } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 4754f051c6..7afd19126f 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -40,6 +40,7 @@ struct Staff; #define MAX_STATIONS 4 #define MAX_RIDES 255 #define RIDE_ID_NULL 255 +#define RIDE_TYPE_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 constexpr uint16_t const MAX_INVERSIONS = RCT12_MAX_INVERSIONS; @@ -201,8 +202,8 @@ struct RideMeasurement */ struct Ride { - ride_id_t id; - uint8_t type; + ride_id_t id = RIDE_ID_NULL; + uint8_t type = RIDE_TYPE_NULL; // pointer to static info. for example, wild mouse type is 0x36, subtype is // 0x4c. uint8_t subtype; @@ -544,7 +545,6 @@ enum enum { - RIDE_TYPE_NULL = 255, RIDE_TYPE_SPIRAL_ROLLER_COASTER = 0, RIDE_TYPE_STAND_UP_ROLLER_COASTER, RIDE_TYPE_SUSPENDED_SWINGING_COASTER, @@ -990,24 +990,92 @@ struct rct_ride_properties extern const rct_ride_properties RideProperties[RIDE_TYPE_COUNT]; -/** Helper macros until rides are stored in this module. */ -Ride* get_ride(int32_t index); +Ride* get_ride(ride_id_t index); + +struct RideManager +{ + const Ride* operator[](ride_id_t id) const + { + return get_ride(id); + } + + Ride* operator[](ride_id_t id) + { + return get_ride(id); + } + + class Iterator + { + friend RideManager; + + private: + RideManager& _rideManager; + size_t _index{}; + size_t _endIndex{}; + + public: + using difference_type = ride_id_t; + using value_type = Ride; + using pointer = const Ride*; + using reference = const Ride&; + using iterator_category = std::forward_iterator_tag; + + private: + Iterator(RideManager& rideManager, size_t beginIndex, size_t endIndex) + : _rideManager(rideManager) + , _index(beginIndex) + , _endIndex(endIndex) + { + if (_index < _endIndex && _rideManager[(ride_id_t)_index] == nullptr) + { + ++(*this); + } + } + + public: + Iterator& operator++() + { + do + { + _index++; + } while (_index < _endIndex && _rideManager[(ride_id_t)_index] == nullptr); + return *this; + } + Iterator operator++(int) + { + auto result = *this; + ++(*this); + return result; + } + bool operator==(Iterator other) const + { + return _index == other._index; + } + bool operator!=(Iterator other) const + { + return !(*this == other); + } + Ride& operator*() + { + return *_rideManager[(ride_id_t)_index]; + } + }; + + Iterator begin(); + Iterator end(); +}; + +RideManager GetRideManager(); +ride_id_t GetNextFreeRideId(); +Ride* GetOrAllocateRide(ride_id_t index); rct_ride_entry* get_ride_entry(int32_t index); std::string_view get_ride_entry_name(size_t index); RideMeasurement* get_ride_measurement(int32_t index); -/** - * Helper macro loop for enumerating through all the non null rides. - */ -#define FOR_ALL_RIDES(i, ride) \ - for (i = 0; i < MAX_RIDES; i++) \ - if ((ride = get_ride(i))->type != RIDE_TYPE_NULL) - extern money16 gTotalRideValueForMoney; extern const uint8_t gRideClassifications[MAX_RIDES]; -extern Ride gRideList[MAX_RIDES]; extern const rct_string_id ColourSchemeNames[4]; extern uint16_t gRideCount; @@ -1130,7 +1198,6 @@ uint8_t ride_get_helix_sections(Ride* ride); bool ride_type_has_flag(int32_t rideType, uint32_t flag); bool ride_has_any_track_elements(const Ride* ride); -void ride_all_has_any_track_elements(bool* rideIndexArray); void ride_construction_set_default_next_piece(); @@ -1209,4 +1276,8 @@ LocationXY16 ride_get_rotated_coords(int16_t x, int16_t y, int16_t z); void determine_ride_entrance_and_exit_locations(); void ride_clear_leftover_entrances(Ride* ride); +#define FOR_ALL_RIDES(i, ride) \ + for (auto& __ride : GetRideManager()) \ + if ((ride = &__ride) != nullptr && (i = __ride.id) != RIDE_ID_NULL) + #endif diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 7286d9e18d..926978f2c3 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -97,12 +97,11 @@ static void ride_ratings_add(rating_tuple* rating, int32_t excitement, int32_t i * processed will be overwritten. * Only purpose of this function currently is for testing. */ -void ride_ratings_update_ride(ride_id_t rideIndex) +void ride_ratings_update_ride(const Ride& ride) { - Ride* ride = get_ride(rideIndex); - if (ride->type != RIDE_TYPE_NULL && ride->status != RIDE_STATUS_CLOSED) + if (ride.status != RIDE_STATUS_CLOSED) { - gRideRatingsCalcData.current_ride = rideIndex; + gRideRatingsCalcData.current_ride = ride.id; gRideRatingsCalcData.state = RIDE_RATINGS_STATE_INITIALISE; while (gRideRatingsCalcData.state != RIDE_RATINGS_STATE_FIND_NEXT_RIDE) { @@ -162,8 +161,8 @@ static void ride_ratings_update_state_0() currentRide = 0; } - Ride* ride = get_ride(currentRide); - if (ride->type != RIDE_TYPE_NULL && ride->status != RIDE_STATUS_CLOSED) + auto ride = get_ride(currentRide); + if (ride != nullptr && ride->status != RIDE_STATUS_CLOSED) { gRideRatingsCalcData.state = RIDE_RATINGS_STATE_INITIALISE; } diff --git a/src/openrct2/ride/RideRatings.h b/src/openrct2/ride/RideRatings.h index 3ec272f7e3..8cd3f2b5fd 100644 --- a/src/openrct2/ride/RideRatings.h +++ b/src/openrct2/ride/RideRatings.h @@ -58,5 +58,5 @@ struct rct_ride_rating_calc_data extern rct_ride_rating_calc_data gRideRatingsCalcData; -void ride_ratings_update_ride(ride_id_t rideIndex); +void ride_ratings_update_ride(const Ride& ride); void ride_ratings_update_all(); diff --git a/src/openrct2/ride/RideTypes.h b/src/openrct2/ride/RideTypes.h index 9a5b081ec4..473a6a8008 100644 --- a/src/openrct2/ride/RideTypes.h +++ b/src/openrct2/ride/RideTypes.h @@ -12,3 +12,4 @@ #include typedef uint8_t ride_id_t; +struct Ride; diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index b5b6b8152e..cfb89f6fcc 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -646,9 +646,27 @@ void scenario_fix_ghosts(rct_s6_data* s6) } } +static void ride_all_has_any_track_elements(bool* rideIndexArray) +{ + tile_element_iterator it; + + std::fill_n(rideIndexArray, MAX_RIDES, false); + + tile_element_iterator_begin(&it); + while (tile_element_iterator_next(&it)) + { + if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK) + continue; + if (it.element->IsGhost()) + continue; + + rideIndexArray[it.element->AsTrack()->GetRideIndex()] = true; + } +} + void scenario_remove_trackless_rides(rct_s6_data* s6) { - bool rideHasTrack[MAX_RIDES]; + bool rideHasTrack[RCT12_MAX_RIDES_IN_PARK]; ride_all_has_any_track_elements(rideHasTrack); for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++) { diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index a8bf2651d8..74c55e9dd9 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -493,13 +493,11 @@ int32_t Park::CalculateParkRating() const money32 Park::CalculateParkValue() const { - money32 result = 0; - // Sum ride values - for (int32_t i = 0; i < MAX_RIDES; i++) + money32 result = 0; + for (const auto& ride : GetRideManager()) { - auto ride = get_ride(i); - result += CalculateRideValue(ride); + result += CalculateRideValue(&ride); } // +7.00 per guest diff --git a/test/tests/RideRatings.cpp b/test/tests/RideRatings.cpp index a556c06090..edb42e7783 100644 --- a/test/tests/RideRatings.cpp +++ b/test/tests/RideRatings.cpp @@ -28,34 +28,26 @@ class RideRatings : public testing::Test protected: void CalculateRatingsForAllRides() { - for (int rideId = 0; rideId < MAX_RIDES; rideId++) + for (const auto& ride : GetRideManager()) { - Ride* ride = get_ride(rideId); - if (ride->type != RIDE_TYPE_NULL) - { - ride_ratings_update_ride(rideId); - } + ride_ratings_update_ride(ride); } } void DumpRatings() { - for (int rideId = 0; rideId < MAX_RIDES; rideId++) + for (const auto& ride : GetRideManager()) { - Ride* ride = get_ride(rideId); - if (ride->type != RIDE_TYPE_NULL) - { - std::string line = FormatRatings(ride); - printf("%s\n", line.c_str()); - } + std::string line = FormatRatings(ride); + printf("%s\n", line.c_str()); } } - std::string FormatRatings(Ride* ride) + std::string FormatRatings(const Ride& ride) { - rating_tuple ratings = ride->ratings; + rating_tuple ratings = ride.ratings; std::string line = String::StdFormat( - "%s: (%d, %d, %d)", ride_type_get_enum_name(ride->type), (int)ratings.excitement, (int)ratings.intensity, + "%s: (%d, %d, %d)", ride_type_get_enum_name(ride.type), (int)ratings.excitement, (int)ratings.intensity, (int)ratings.nausea); return line; } @@ -77,6 +69,7 @@ TEST_F(RideRatings, all) // Check ride count to check load was successful ASSERT_EQ(gRideCount, 134); + ASSERT_EQ(ride_get_count(), 134); CalculateRatingsForAllRides(); @@ -86,16 +79,12 @@ TEST_F(RideRatings, all) // Check ride ratings int expI = 0; - for (int rideId = 0; rideId < MAX_RIDES; rideId++) + for (const auto& ride : GetRideManager()) { - Ride* ride = get_ride(rideId); - if (ride->type != RIDE_TYPE_NULL) - { - std::string actual = FormatRatings(ride); - std::string expected = expectedRatings[expI]; - ASSERT_STREQ(actual.c_str(), expected.c_str()); + auto actual = FormatRatings(ride); + auto expected = expectedRatings[expI]; + ASSERT_STREQ(actual.c_str(), expected.c_str()); - expI++; - } + expI++; } } From 414b53b56da021cfe566b5e5e829037110052960 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 3 Aug 2019 18:11:30 +0100 Subject: [PATCH 2/7] Remove ride classifications --- .../windows/EditorObjectiveOptions.cpp | 18 +-- src/openrct2-ui/windows/Guest.cpp | 2 +- src/openrct2-ui/windows/Ride.cpp | 55 ++++----- src/openrct2-ui/windows/RideList.cpp | 105 ++++++++---------- src/openrct2/management/Marketing.cpp | 2 +- src/openrct2/peep/Guest.cpp | 4 +- src/openrct2/peep/Peep.cpp | 2 - src/openrct2/rct2/S6Exporter.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 1 - src/openrct2/ride/Ride.cpp | 97 +++------------- src/openrct2/ride/Ride.h | 28 +++-- test/tests/MultiLaunch.cpp | 4 +- test/tests/RideRatings.cpp | 1 - 13 files changed, 118 insertions(+), 203 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index d6bd3856d0..cc802ac83b 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -12,6 +12,7 @@ #include "../interface/Window.h" #include "Window.h" +#include #include #include #include @@ -1040,7 +1041,7 @@ static void window_editor_objective_options_rides_update(rct_window* w) numItems = 0; FOR_ALL_RIDES (i, ride) { - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { w->list_item_positions[numItems] = i; numItems++; @@ -1187,20 +1188,9 @@ static void window_editor_objective_options_rides_scrollpaint(rct_window* w, rct */ static void window_editor_objective_options_update_disabled_widgets(rct_window* w) { - Ride* ride; - int32_t i, numRides; - // Check if there are any rides (not shops or facilities) - numRides = 0; - FOR_ALL_RIDES (i, ride) - { - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) - { - numRides++; - } - } - - if (numRides != 0) + const auto& rideManager = GetRideManager(); + if (std::any_of(rideManager.begin(), rideManager.end(), [](const Ride& ride) { return ride.IsRide(); })) { w->disabled_widgets &= ~(1 << WIDX_TAB_2); } diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index b35588e437..a80cb0cf56 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1583,7 +1583,7 @@ void window_guest_rides_update(rct_window* w) uint8_t curr_list_position = 0; for (const auto& ride : GetRideManager()) { - if (guest->HasRidden(&ride) && gRideClassifications[ride.type] == RIDE_CLASS_RIDE) + if (ride.IsRide() && guest->HasRidden(&ride)) { w->list_item_positions[curr_list_position] = ride.id; curr_list_position++; diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 971f80b797..12ac5a4312 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1264,32 +1264,32 @@ static void window_ride_draw_tab_image(rct_drawpixelinfo* dpi, rct_window* w, in static void window_ride_draw_tab_main(rct_drawpixelinfo* dpi, rct_window* w) { rct_widgetindex widgetIndex = WIDX_TAB_1 + WINDOW_RIDE_PAGE_MAIN; - if (!(w->disabled_widgets & (1LL << widgetIndex))) { - int32_t spriteIndex = 0; - int32_t rideType = get_ride(w->number)->type; - - switch (gRideClassifications[rideType]) + auto ride = get_ride(w->number); + if (ride != nullptr) { - case RIDE_CLASS_RIDE: - spriteIndex = SPR_TAB_RIDE_0; - if (w->page == WINDOW_RIDE_PAGE_MAIN) - spriteIndex += (w->frame_no / 4) % 16; - break; - case RIDE_CLASS_SHOP_OR_STALL: - spriteIndex = SPR_TAB_SHOPS_AND_STALLS_0; - if (w->page == WINDOW_RIDE_PAGE_MAIN) - spriteIndex += (w->frame_no / 4) % 16; - break; - case RIDE_CLASS_KIOSK_OR_FACILITY: - spriteIndex = SPR_TAB_KIOSKS_AND_FACILITIES_0; - if (w->page == WINDOW_RIDE_PAGE_MAIN) - spriteIndex += (w->frame_no / 4) % 8; - break; + int32_t spriteIndex = 0; + switch (ride->GetClassification()) + { + case RideClassification::Ride: + spriteIndex = SPR_TAB_RIDE_0; + if (w->page == WINDOW_RIDE_PAGE_MAIN) + spriteIndex += (w->frame_no / 4) % 16; + break; + case RideClassification::ShopOrStall: + spriteIndex = SPR_TAB_SHOPS_AND_STALLS_0; + if (w->page == WINDOW_RIDE_PAGE_MAIN) + spriteIndex += (w->frame_no / 4) % 16; + break; + case RideClassification::KioskOrFacility: + spriteIndex = SPR_TAB_KIOSKS_AND_FACILITIES_0; + if (w->page == WINDOW_RIDE_PAGE_MAIN) + spriteIndex += (w->frame_no / 4) % 8; + break; + } + gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0); } - - gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0); } } @@ -2296,8 +2296,9 @@ static void populate_vehicle_type_dropdown(Ride* ride) bool selectionShouldBeExpanded; int32_t rideTypeIterator, rideTypeIteratorMax; if (gCheatsShowVehiclesFromOtherTrackTypes - && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE - || ride->type == RIDE_TYPE_MINI_GOLF)) + && !( + ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE + || ride->type == RIDE_TYPE_MINI_GOLF)) { selectionShouldBeExpanded = true; rideTypeIterator = 0; @@ -6837,7 +6838,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) y = w->y + window_ride_customer_widgets[WIDX_PAGE_BACKGROUND].top + 4; // Customers currently on ride - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { int16_t customersOnRide = ride->num_riders; gfx_draw_string_left(dpi, STR_CUSTOMERS_ON_RIDE, &customersOnRide, COLOUR_BLACK, x, y); @@ -6878,7 +6879,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) y += LIST_ROW_HEIGHT; // Queue time - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { queueTime = ride->GetMaxQueueTime(); stringId = queueTime == 1 ? STR_QUEUE_TIME_MINUTE : STR_QUEUE_TIME_MINUTES; @@ -6912,7 +6913,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) y += LIST_ROW_HEIGHT; // Guests favourite - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { stringId = ride->guests_favourite == 1 ? STR_FAVOURITE_RIDE_OF_GUEST : STR_FAVOURITE_RIDE_OF_GUESTS; gfx_draw_string_left(dpi, stringId, &ride->guests_favourite, COLOUR_BLACK, x, y); diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index 3005546b66..3ffab68e2b 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -527,30 +527,23 @@ static void window_ride_list_invalidate(rct_window* w) w->widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN; w->widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN; - int8_t allClosed = -1; - int8_t allOpen = -1; - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + const auto& rideManager = GetRideManager(); + auto allClosed = false; + auto allOpen = false; + if (std::size(rideManager) != 0) { - if (w->page != gRideClassifications[ride->type]) - continue; - if (ride->status == RIDE_STATUS_OPEN) - { - if (allOpen == -1) - allOpen = true; - allClosed = false; - } - else - { - if (allClosed == -1) - allClosed = true; - allOpen = false; - } + auto c = (RideClassification)w->page; + allClosed = std::all_of(rideManager.begin(), rideManager.end(), [c](const Ride& ride) { + return ride.GetClassification() == c&& ride.status == RIDE_STATUS_OPEN; + }); + allOpen = std::all_of(rideManager.begin(), rideManager.end(), [c](const Ride& ride) { + return ride.GetClassification() == c&& ride.status != RIDE_STATUS_OPEN; + }); } - w->widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (allClosed == 1) * 2 + + w->widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (allClosed ? 1 : 0) * 2 + widget_is_pressed(w, WIDX_CLOSE_LIGHT); - w->widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (allOpen == 1) * 2 + w->widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (allOpen ? 1 : 0) * 2 + widget_is_pressed(w, WIDX_OPEN_LIGHT); w->widgets[WIDX_QUICK_DEMOLISH].top = w->widgets[WIDX_OPEN_LIGHT].bottom + 3; } @@ -731,7 +724,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, break; case INFORMATION_TYPE_GUESTS_FAVOURITE: formatSecondary = 0; - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { set_format_arg(2, uint16_t, ride->guests_favourite); formatSecondary = ride->guests_favourite == 1 ? STR_GUESTS_FAVOURITE_LABEL @@ -782,13 +775,11 @@ static void window_ride_list_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* */ void window_ride_list_refresh_list(rct_window* w) { - int32_t i; - Ride *ride, *otherRide; int32_t list_index = 0; - - FOR_ALL_RIDES (i, ride) + for (auto& ridec : GetRideManager()) { - if (w->page != gRideClassifications[ride->type] + auto ride = &ridec; + if (ride->GetClassification() != (RideClassification)w->page || (ride->status == RIDE_STATUS_CLOSED && !ride_has_any_track_elements(ride))) continue; @@ -797,7 +788,7 @@ void window_ride_list_refresh_list(rct_window* w) ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_LIST; } - w->list_item_positions[list_index] = i; + w->list_item_positions[list_index] = ride->id; int32_t current_list_position = list_index; switch (w->list_information_type) { @@ -806,7 +797,7 @@ void window_ride_list_refresh_list(rct_window* w) auto strA = ride->GetName(); while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); auto strB = otherRide->GetName(); if (_strcmpi(strA.c_str(), strB.c_str()) >= 0) break; @@ -818,7 +809,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_POPULARITY: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->popularity * 4 <= otherRide->popularity * 4) break; @@ -828,7 +819,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_SATISFACTION: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->satisfaction * 5 <= otherRide->satisfaction * 5) break; @@ -838,7 +829,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_PROFIT: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->profit <= otherRide->profit) break; @@ -848,7 +839,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_TOTAL_CUSTOMERS: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->total_customers <= otherRide->total_customers) break; @@ -858,7 +849,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_TOTAL_PROFIT: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->total_profit <= otherRide->total_profit) break; @@ -868,7 +859,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_CUSTOMERS: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride_customers_per_hour(ride) <= ride_customers_per_hour(otherRide)) break; @@ -878,7 +869,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_AGE: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->build_date <= otherRide->build_date) break; @@ -888,7 +879,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_INCOME: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->income_per_hour <= otherRide->income_per_hour) break; @@ -898,7 +889,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_RUNNING_COST: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->upkeep_cost <= otherRide->upkeep_cost) break; @@ -908,7 +899,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_QUEUE_LENGTH: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->GetTotalQueueLength() <= otherRide->GetTotalQueueLength()) break; @@ -918,7 +909,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_QUEUE_TIME: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->GetMaxQueueTime() <= otherRide->GetMaxQueueTime()) break; @@ -928,7 +919,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_RELIABILITY: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->reliability_percentage <= otherRide->reliability_percentage) break; @@ -938,7 +929,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_DOWN_TIME: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->downtime <= otherRide->downtime) break; @@ -948,7 +939,7 @@ void window_ride_list_refresh_list(rct_window* w) case INFORMATION_TYPE_GUESTS_FAVOURITE: while (--current_list_position >= 0) { - otherRide = get_ride(w->list_item_positions[current_list_position]); + auto otherRide = get_ride(w->list_item_positions[current_list_position]); if (ride->guests_favourite <= otherRide->guests_favourite) break; @@ -967,30 +958,22 @@ void window_ride_list_refresh_list(rct_window* w) static void window_ride_list_close_all(rct_window* w) { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (w->page != gRideClassifications[ride->type]) - continue; - if (ride->status == RIDE_STATUS_CLOSED) - continue; - ride_set_status(ride, RIDE_STATUS_CLOSED); + if (ride.status != RIDE_STATUS_CLOSED && ride.GetClassification() == (RideClassification)w->page) + { + ride_set_status(&ride, RIDE_STATUS_CLOSED); + } } } static void window_ride_list_open_all(rct_window* w) { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (w->page != gRideClassifications[ride->type]) - continue; - if (ride->status == RIDE_STATUS_OPEN) - continue; - ride_set_status(ride, RIDE_STATUS_OPEN); + if (ride.status != RIDE_STATUS_OPEN && ride.GetClassification() == (RideClassification)w->page) + { + ride_set_status(&ride, RIDE_STATUS_OPEN); + } } } diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 2112f56d13..55d7f0a78d 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -182,7 +182,7 @@ bool marketing_is_campaign_type_applicable(int32_t campaignType) // Check if any rides exist FOR_ALL_RIDES (i, ride) { - if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) + if (ride->IsRide()) { return true; } diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 50f1833e83..fb198f9ce0 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1399,7 +1399,7 @@ void Guest::CheckIfLost() { if (!(peep_flags & PEEP_FLAGS_LOST)) { - if (gRideCount < 2) + if (ride_get_count() < 2) return; peep_flags ^= PEEP_FLAGS_21; @@ -6510,7 +6510,7 @@ static bool peep_should_watch_ride(TileElement* tileElement) return false; } - if (gRideClassifications[ride->type] != RIDE_CLASS_RIDE) + if (!ride->IsRide()) { return false; } diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index d0208fc0e3..6fedd244a5 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1208,8 +1208,6 @@ void peep_problem_warnings_update() disgust_counter = 0, bathroom_counter = 0, vandalism_counter = 0; uint8_t* warning_throttle = gPeepWarningThrottle; - gRideCount = ride_get_count(); // refactor this to somewhere else - FOR_ALL_GUESTS (spriteIndex, peep) { if (peep->outside_of_park != 0 || peep->thoughts[0].freshness > 5) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index b2acae8725..4f8b8b9322 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -303,7 +303,7 @@ void S6Exporter::Export() // _s6.game_version_number _s6.completed_company_value_record = gScenarioCompanyValueRecord; _s6.loan_hash = GetLoanHash(gInitialCash, gBankLoan, gMaxBankLoan); - _s6.ride_count = gRideCount; + _s6.ride_count = ride_get_count(); // pad_013587CA _s6.historical_profit = gHistoricalProfit; // pad_013587D4 diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index bb80667f2a..7fd0dc0751 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -321,7 +321,6 @@ public: _gameVersion = _s6.game_version_number; gScenarioCompanyValueRecord = _s6.completed_company_value_record; // _s6.loan_hash; - gRideCount = _s6.ride_count; // pad_013587CA gHistoricalProfit = _s6.historical_profit; // pad_013587D4 diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 3c65cecf4f..3cb04ae1c7 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -70,89 +70,13 @@ using namespace OpenRCT2; -#pragma region Ride classification table - -/** rct2: 0x0097C3AF */ -// clang-format off -const uint8_t gRideClassifications[255] = { - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_SHOP_OR_STALL, - RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_RIDE, RIDE_CLASS_SHOP_OR_STALL, - RIDE_CLASS_KIOSK_OR_FACILITY, RIDE_CLASS_KIOSK_OR_FACILITY, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_KIOSK_OR_FACILITY, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_KIOSK_OR_FACILITY, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_RIDE, RIDE_CLASS_SHOP_OR_STALL, - RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_SHOP_OR_STALL, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, - RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE -}; -// clang-format on - uint8_t gTypeToRideEntryIndexMap[TYPE_TO_RIDE_ENTRY_SLOTS]; - -#pragma endregion - static constexpr const int32_t RideInspectionInterval[] = { 10, 20, 30, 45, 60, 120, 0, 0, }; static std::vector _rides; -uint16_t gRideCount; bool gGotoStartPlacementMode = false; money16 gTotalRideValueForMoney; @@ -217,6 +141,11 @@ RideManager GetRideManager() return {}; } +size_t RideManager::size() const +{ + return ride_get_count(); +} + RideManager::Iterator RideManager::begin() { return RideManager::Iterator(*this, 0, _rides.size()); @@ -7311,7 +7240,7 @@ void Ride::Renew() reliability = RIDE_INITIAL_RELIABILITY; } -bool Ride::IsRide() const +RideClassification Ride::GetClassification() const { switch (type) { @@ -7321,16 +7250,26 @@ bool Ride::IsRide() const case RIDE_TYPE_1F: case RIDE_TYPE_SHOP: case RIDE_TYPE_22: + case RIDE_TYPE_50: + case RIDE_TYPE_52: + case RIDE_TYPE_53: + case RIDE_TYPE_54: + return RideClassification::ShopOrStall; case RIDE_TYPE_INFORMATION_KIOSK: case RIDE_TYPE_TOILETS: case RIDE_TYPE_CASH_MACHINE: case RIDE_TYPE_FIRST_AID: - return false; + return RideClassification::KioskOrFacility; default: - return true; + return RideClassification::Ride; } } +bool Ride::IsRide() const +{ + return GetClassification() == RideClassification::Ride; +} + money16 ride_get_price(const Ride* ride) { if (gParkFlags & PARK_FLAGS_NO_MONEY) diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 7afd19126f..960edec1d3 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -194,6 +194,13 @@ struct RideMeasurement uint8_t altitude[MAX_ITEMS]{}; }; +enum class RideClassification +{ + Ride, + ShopOrStall, + KioskOrFacility +}; + /** * Ride structure. * @@ -388,6 +395,7 @@ private: public: bool CanBreakDown() const; + RideClassification GetClassification() const; bool IsRide() const; void Renew(); void Delete(); @@ -470,13 +478,6 @@ assert_struct_size(ride_name_args, 4); #define TYPE_TO_RIDE_ENTRY_SLOTS 492 extern uint8_t gTypeToRideEntryIndexMap[TYPE_TO_RIDE_ENTRY_SLOTS]; -enum -{ - RIDE_CLASS_RIDE, - RIDE_CLASS_SHOP_OR_STALL, - RIDE_CLASS_KIOSK_OR_FACILITY -}; - // Constants used by the lifecycle_flags property at 0x1D0 enum { @@ -1061,8 +1062,17 @@ struct RideManager } }; + size_t size() const; Iterator begin(); Iterator end(); + Iterator begin() const + { + return ((RideManager*)this)->begin(); + } + Iterator end() const + { + return ((RideManager*)this)->end(); + } }; RideManager GetRideManager(); @@ -1074,12 +1084,8 @@ RideMeasurement* get_ride_measurement(int32_t index); extern money16 gTotalRideValueForMoney; -extern const uint8_t gRideClassifications[MAX_RIDES]; - extern const rct_string_id ColourSchemeNames[4]; -extern uint16_t gRideCount; - extern money32 _currentTrackPrice; extern uint16_t _numCurrentPossibleRideConfigurations; diff --git a/test/tests/MultiLaunch.cpp b/test/tests/MultiLaunch.cpp index f83c4076af..b3a37db893 100644 --- a/test/tests/MultiLaunch.cpp +++ b/test/tests/MultiLaunch.cpp @@ -45,7 +45,7 @@ TEST(MultiLaunchTest, all) game_load_init(); // Check ride count to check load was successful - ASSERT_EQ(gRideCount, 134); + ASSERT_EQ(ride_get_count(), 134); auto gs = context->GetGameState(); ASSERT_NE(gs, nullptr); auto& date = gs->GetDate(); @@ -59,7 +59,7 @@ TEST(MultiLaunchTest, all) ASSERT_EQ(date.GetMonthTicks(), 7862 + updatesToTest); // Check ride count again - ASSERT_EQ(gRideCount, 134); + ASSERT_EQ(ride_get_count(), 134); } SUCCEED(); } diff --git a/test/tests/RideRatings.cpp b/test/tests/RideRatings.cpp index edb42e7783..109f3622ab 100644 --- a/test/tests/RideRatings.cpp +++ b/test/tests/RideRatings.cpp @@ -68,7 +68,6 @@ TEST_F(RideRatings, all) load_from_sv6(path.c_str()); // Check ride count to check load was successful - ASSERT_EQ(gRideCount, 134); ASSERT_EQ(ride_get_count(), 134); CalculateRatingsForAllRides(); From e23638548a2c141ceda25209ab79ef2627b85930 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 14:45:17 +0100 Subject: [PATCH 3/7] Reduce use of MAX_RIDES and RIDE_TYPE_NULL --- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2/EditorObjectSelectionSession.cpp | 4 +-- src/openrct2/actions/RideDemolishAction.hpp | 8 ++--- .../actions/RideEntranceExitPlaceAction.hpp | 10 ++---- .../actions/RideEntranceExitRemoveAction.hpp | 12 ++----- .../actions/RideSetAppearanceAction.hpp | 10 ++---- src/openrct2/actions/RideSetName.hpp | 8 ++--- src/openrct2/actions/RideSetPriceAction.hpp | 12 ++----- src/openrct2/actions/RideSetSetting.hpp | 12 ++----- src/openrct2/actions/RideSetStatus.hpp | 23 ++++++------ .../actions/RideSetVehiclesAction.hpp | 12 ++----- src/openrct2/actions/TrackPlaceAction.hpp | 5 --- src/openrct2/interface/InteractiveConsole.cpp | 36 +++++++++---------- src/openrct2/ride/Ride.h | 3 +- src/openrct2/ride/RideRatings.cpp | 12 +++---- src/openrct2/ride/TrackDesign.cpp | 2 +- src/openrct2/ride/TrackPaint.cpp | 4 +-- src/openrct2/world/Footpath.cpp | 4 +-- src/openrct2/world/Park.cpp | 2 +- 19 files changed, 69 insertions(+), 112 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 0e05989792..1794868de9 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -607,7 +607,7 @@ static void window_ride_construction_close(rct_window* w) // If we demolish a ride all windows will be closed including the construction window, // the ride at this point is already gone. auto ride = get_ride(_currentRideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { return; } diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index b7cdf1cf5a..a8bc528557 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -187,8 +187,8 @@ void setup_in_use_selection_flags() for (uint8_t ride_index = 0; ride_index < 0xFF; ride_index++) { - Ride* ride = get_ride(ride_index); - if (ride->type != RIDE_TYPE_NULL) + auto ride = get_ride(ride_index); + if (ride != nullptr) { uint8_t type = ride->subtype; Editor::SetSelectedObject(OBJECT_TYPE_RIDE, type, OBJECT_SELECTION_FLAG_SELECTED); diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 2b7fdfcf5e..0b2c654782 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -59,8 +59,8 @@ public: GameActionResult::Ptr Query() const override { - Ride* ride = get_ride(_rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DEMOLISH_RIDE, STR_NONE); @@ -105,8 +105,8 @@ public: GameActionResult::Ptr Execute() const override { - Ride* ride = get_ride(_rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DEMOLISH_RIDE, STR_NONE); diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp index 3dd6ebc504..7d37a0a129 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp @@ -60,14 +60,8 @@ public: return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, errorTitle); } - if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) - { - log_warning("Invalid game command for ride %d", (int32_t)_rideIndex); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle); - } - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid game command for ride %d", (int32_t)_rideIndex); return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle); @@ -147,7 +141,7 @@ public: auto errorTitle = _isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION : STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION; Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid game command for ride %d", (int32_t)_rideIndex); return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle); diff --git a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp index 0b67bbddf0..44cf69d825 100644 --- a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp +++ b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp @@ -47,14 +47,8 @@ public: GameActionResult::Ptr Query() const override { - if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) - { - log_warning("Invalid game command for ride %d", int32_t(_rideIndex)); - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); - } - - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid ride id %d for entrance/exit removal", (int32_t)_rideIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -117,7 +111,7 @@ public: GameActionResult::Ptr Execute() const override { Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid ride id %d for entrance/exit removal", (int32_t)_rideIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); diff --git a/src/openrct2/actions/RideSetAppearanceAction.hpp b/src/openrct2/actions/RideSetAppearanceAction.hpp index 0701910143..bda3232938 100644 --- a/src/openrct2/actions/RideSetAppearanceAction.hpp +++ b/src/openrct2/actions/RideSetAppearanceAction.hpp @@ -68,14 +68,8 @@ public: GameActionResult::Ptr Query() const override { - if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) - { - log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); - } - - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); diff --git a/src/openrct2/actions/RideSetName.hpp b/src/openrct2/actions/RideSetName.hpp index 468d08a26d..2c423e8009 100644 --- a/src/openrct2/actions/RideSetName.hpp +++ b/src/openrct2/actions/RideSetName.hpp @@ -52,8 +52,8 @@ public: GameActionResult::Ptr Query() const override { - Ride* ride = get_ride(_rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_RIDE_ATTRACTION, STR_NONE); @@ -70,8 +70,8 @@ public: GameActionResult::Ptr Execute() const override { - Ride* ride = get_ride(_rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_RIDE_ATTRACTION, STR_NONE); diff --git a/src/openrct2/actions/RideSetPriceAction.hpp b/src/openrct2/actions/RideSetPriceAction.hpp index cc056176a0..5f5ed9cd25 100644 --- a/src/openrct2/actions/RideSetPriceAction.hpp +++ b/src/openrct2/actions/RideSetPriceAction.hpp @@ -57,14 +57,8 @@ public: { GameActionResult::Ptr res = std::make_unique(); - if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) - { - log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); - } - - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -86,7 +80,7 @@ public: res->ExpenditureType = RCT_EXPENDITURE_TYPE_PARK_RIDE_TICKETS; Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); diff --git a/src/openrct2/actions/RideSetSetting.hpp b/src/openrct2/actions/RideSetSetting.hpp index ed560e9053..725cf3e82e 100644 --- a/src/openrct2/actions/RideSetSetting.hpp +++ b/src/openrct2/actions/RideSetSetting.hpp @@ -60,14 +60,8 @@ public: GameActionResult::Ptr Query() const override { - if (_rideIndex >= MAX_RIDES || _rideIndex < 0) - { - log_warning("Invalid game command for ride %d", int32_t(_rideIndex)); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); - } - - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid ride: #%d.", (int32_t)_rideIndex); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); @@ -172,7 +166,7 @@ public: GameActionResult::Ptr Execute() const override { Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid ride: #%d.", (int32_t)_rideIndex); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index 3ed8a0888d..5bd1487888 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -59,18 +59,19 @@ public: GameActionResult::Ptr Query() const override { GameActionResult::Ptr res = std::make_unique(); - Ride* ride = get_ride(_rideIndex); - res->ErrorTitle = _StatusErrorTitles[_status]; - ride->FormatNameTo(res->ErrorMessageArgs.data() + 6); - if (_rideIndex >= MAX_RIDES || _rideIndex < 0) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); res->Error = GA_ERROR::INVALID_PARAMETERS; - res->ErrorMessage = STR_INVALID_SELECTION_OF_OBJECTS; + res->ErrorTitle = STR_RIDE_DESCRIPTION_UNKNOWN; + res->ErrorMessage = STR_NONE; return res; } + res->ErrorTitle = _StatusErrorTitles[_status]; + ride->FormatNameTo(res->ErrorMessageArgs.data() + 6); if (_status != ride->status) { if (_status == RIDE_STATUS_SIMULATING && (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) @@ -107,18 +108,18 @@ public: GameActionResult::Ptr res = std::make_unique(); res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - Ride* ride = get_ride(_rideIndex); - res->ErrorTitle = _StatusErrorTitles[_status]; - ride->FormatNameTo(res->ErrorMessageArgs.data() + 6); - - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); res->Error = GA_ERROR::INVALID_PARAMETERS; - res->ErrorMessage = STR_INVALID_SELECTION_OF_OBJECTS; + res->ErrorTitle = STR_RIDE_DESCRIPTION_UNKNOWN; + res->ErrorMessage = STR_NONE; return res; } + res->ErrorTitle = _StatusErrorTitles[_status]; + ride->FormatNameTo(res->ErrorMessageArgs.data() + 6); if (ride->overall_view.xy != RCT_XY8_UNDEFINED) { res->Position.x = ride->overall_view.x * 32 + 16; diff --git a/src/openrct2/actions/RideSetVehiclesAction.hpp b/src/openrct2/actions/RideSetVehiclesAction.hpp index 69b89c02ac..04120166a7 100644 --- a/src/openrct2/actions/RideSetVehiclesAction.hpp +++ b/src/openrct2/actions/RideSetVehiclesAction.hpp @@ -74,14 +74,8 @@ public: } auto errTitle = SetVehicleTypeErrorTitle[_type]; - if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) - { - log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); - } - - Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(_rideIndex); + if (ride == nullptr) { log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); @@ -138,7 +132,7 @@ public: { auto errTitle = SetVehicleTypeErrorTitle[_type]; Ride* ride = get_ride(_rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index ef8e7c9443..bce9e895b8 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -93,11 +93,6 @@ public: log_warning("Invalid ride for track placement, rideIndex = %d", (int32_t)_rideIndex); return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - if (ride->type == RIDE_TYPE_NULL) - { - log_warning("Invalid ride type, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); - } rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 47865996c9..05643e2031 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -136,14 +136,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) { if (argv[0] == "list") { - Ride* ride; - int32_t i; - FOR_ALL_RIDES (i, ride) + for (const auto& ride : GetRideManager()) { - auto name = ride->GetName(); + auto name = ride.GetName(); console.WriteFormatLine( - "ride: %03d type: %02u subtype %03u operating mode: %02u name: %s", i, ride->type, ride->subtype, - ride->mode, name.c_str()); + "ride: %03d type: %02u subtype %03u operating mode: %02u name: %s", ride.id, ride.type, ride.subtype, + ride.mode, name.c_str()); } } else if (argv[0] == "set") @@ -215,7 +213,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) { console.WriteFormatLine("Invalid ride mode."); } - else if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + else if (ride == nullptr) { console.WriteFormatLine("No ride found with index %d", ride_index); } @@ -242,12 +240,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } else { - Ride* ride = get_ride(ride_index); + auto ride = get_ride(ride_index); if (mass <= 0) { console.WriteFormatLine("Friction value must be strictly positive"); } - else if (ride->type == RIDE_TYPE_NULL) + else if (ride == nullptr) { console.WriteFormatLine("No ride found with index %d", ride_index); } @@ -282,12 +280,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } else { - Ride* ride = get_ride(ride_index); + auto ride = get_ride(ride_index); if (excitement <= 0) { console.WriteFormatLine("Excitement value must be strictly positive"); } - else if (ride->type == RIDE_TYPE_NULL) + else if (ride == nullptr) { console.WriteFormatLine("No ride found with index %d", ride_index); } @@ -313,12 +311,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } else { - Ride* ride = get_ride(ride_index); + auto ride = get_ride(ride_index); if (intensity <= 0) { console.WriteFormatLine("Intensity value must be strictly positive"); } - else if (ride->type == RIDE_TYPE_NULL) + else if (ride == nullptr) { console.WriteFormatLine("No ride found with index %d", ride_index); } @@ -344,12 +342,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } else { - Ride* ride = get_ride(ride_index); + auto ride = get_ride(ride_index); if (nausea <= 0) { console.WriteFormatLine("Nausea value must be strictly positive"); } - else if (ride->type == RIDE_TYPE_NULL) + else if (ride == nullptr) { console.WriteFormatLine("No ride found with index %d", ride_index); } @@ -390,13 +388,11 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) if (int_valid[0] && int_valid[1]) { - uint16_t rideId{}; - Ride* ride; - FOR_ALL_RIDES (rideId, ride) + for (const auto& ride : GetRideManager()) { - if (ride->type == rideType) + if (ride.type == rideType) { - auto rideSetPrice = RideSetPriceAction(rideId, price, true); + auto rideSetPrice = RideSetPriceAction(ride.id, price, true); GameActions::Execute(&rideSetPrice); } } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 960edec1d3..343ecbf587 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -18,6 +18,7 @@ #include "RideTypes.h" #include "Vehicle.h" +#include #include interface IObjectManager; @@ -39,10 +40,10 @@ struct Staff; #define MAX_CARS_PER_TRAIN 255 #define MAX_STATIONS 4 #define MAX_RIDES 255 -#define RIDE_ID_NULL 255 #define RIDE_TYPE_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 +constexpr ride_id_t RIDE_ID_NULL = std::numeric_limits::max(); constexpr uint16_t const MAX_INVERSIONS = RCT12_MAX_INVERSIONS; constexpr uint16_t const MAX_GOLF_HOLES = RCT12_MAX_GOLF_HOLES; constexpr uint16_t const MAX_HELICES = RCT12_MAX_HELICES; diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 926978f2c3..4cdb7a8f71 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -194,8 +194,8 @@ static void ride_ratings_update_state_1() static void ride_ratings_update_state_2() { const ride_id_t rideIndex = gRideRatingsCalcData.current_ride; - Ride* ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL || ride->status == RIDE_STATUS_CLOSED) + auto ride = get_ride(rideIndex); + if (ride == nullptr || ride->status == RIDE_STATUS_CLOSED) { gRideRatingsCalcData.state = RIDE_RATINGS_STATE_FIND_NEXT_RIDE; return; @@ -268,8 +268,8 @@ static void ride_ratings_update_state_2() */ static void ride_ratings_update_state_3() { - Ride* ride = get_ride(gRideRatingsCalcData.current_ride); - if (ride->type == RIDE_TYPE_NULL || ride->status == RIDE_STATUS_CLOSED) + auto ride = get_ride(gRideRatingsCalcData.current_ride); + if (ride == nullptr || ride->status == RIDE_STATUS_CLOSED) { gRideRatingsCalcData.state = RIDE_RATINGS_STATE_FIND_NEXT_RIDE; return; @@ -298,8 +298,8 @@ static void ride_ratings_update_state_4() */ static void ride_ratings_update_state_5() { - Ride* ride = get_ride(gRideRatingsCalcData.current_ride); - if (ride->type == RIDE_TYPE_NULL || ride->status == RIDE_STATUS_CLOSED) + auto ride = get_ride(gRideRatingsCalcData.current_ride); + if (ride == nullptr || ride->status == RIDE_STATUS_CLOSED) { gRideRatingsCalcData.state = RIDE_RATINGS_STATE_FIND_NEXT_RIDE; return; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 47f8d22f6b..da8d0021f7 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1870,7 +1870,7 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags } auto ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL) + if (ride == nullptr) { log_warning("Invalid game command for track placement, ride id = %d", ride->id); return MONEY32_UNDEFINED; diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index b95f39c0e3..a6b8690c36 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -2157,8 +2157,8 @@ void track_paint_util_left_corkscrew_up_supports(paint_session* session, uint8_t void track_paint(paint_session* session, uint8_t direction, int32_t height, const TileElement* tileElement) { ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - Ride* ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(rideIndex); + if (ride == nullptr) { log_error("Attempted to paint invalid ride: %d", rideIndex); return; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index e7b61a181d..e0b3058891 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1176,8 +1176,8 @@ void footpath_update_queue_chains() for (uint8_t* queueChainPtr = _footpathQueueChain; queueChainPtr < _footpathQueueChainNext; queueChainPtr++) { ride_id_t rideIndex = *queueChainPtr; - Ride* ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL) + auto ride = get_ride(rideIndex); + if (ride == nullptr) continue; for (int32_t i = 0; i < MAX_STATIONS; i++) diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 74c55e9dd9..b9eebad9f7 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -509,7 +509,7 @@ money32 Park::CalculateParkValue() const money32 Park::CalculateRideValue(const Ride* ride) const { money32 result = 0; - if (ride->type != RIDE_TYPE_NULL && ride->value != RIDE_VALUE_UNDEFINED) + if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED) { result = (ride->value * 10) * (ride_customers_in_last_5_minutes(ride) + rideBonusValue[ride->type] * 4); } From a863c7ae507f6291e409f1f87b671fe2bce884ee Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 16:00:15 +0100 Subject: [PATCH 4/7] Remove rest of FOR_ALL_RIDES instances --- .clang-format | 1 - .../windows/EditorObjectiveOptions.cpp | 11 +- src/openrct2-ui/windows/NewCampaign.cpp | 22 +- src/openrct2/actions/SetCheatAction.hpp | 78 +++---- src/openrct2/interface/InteractiveConsole.cpp | 6 +- src/openrct2/management/Award.cpp | 210 +++++++----------- src/openrct2/management/Finance.cpp | 29 +-- src/openrct2/management/Marketing.cpp | 25 +-- src/openrct2/peep/Guest.cpp | 93 ++++---- src/openrct2/rct1/S4Importer.cpp | 28 +-- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/Ride.h | 8 +- src/openrct2/ride/RideRatings.cpp | 18 +- src/openrct2/ride/ShopItem.cpp | 18 +- src/openrct2/scenario/Scenario.cpp | 127 ++++++----- src/openrct2/world/Banner.cpp | 16 +- src/openrct2/world/Park.cpp | 57 +++-- test/tests/Pathfinding.cpp | 24 +- 18 files changed, 328 insertions(+), 445 deletions(-) diff --git a/.clang-format b/.clang-format index c29e19d6a3..ebb3421b67 100644 --- a/.clang-format +++ b/.clang-format @@ -54,7 +54,6 @@ ForEachMacros: - FOR_ALL_PEEPS - FOR_ALL_GUESTS - FOR_ALL_STAFF - - FOR_ALL_RIDES IncludeBlocks: 'Regroup' IncludeCategories: - Regex: '^"' diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index cc802ac83b..1e474795c7 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -1030,20 +1030,17 @@ static void window_editor_objective_options_rides_resize(rct_window* w) */ static void window_editor_objective_options_rides_update(rct_window* w) { - int32_t i, numItems; - Ride* ride; - w->frame_no++; window_event_invalidate_call(w); window_event_resize_call(w); widget_invalidate(w, WIDX_TAB_2); - numItems = 0; - FOR_ALL_RIDES (i, ride) + auto numItems = 0; + for (auto& ride : GetRideManager()) { - if (ride->IsRide()) + if (ride.IsRide()) { - w->list_item_positions[numItems] = i; + w->list_item_positions[numItems] = ride.id; numItems++; } } diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index 72a4448b7f..e43dac459b 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -177,25 +177,23 @@ rct_window* window_new_campaign_open(int16_t campaignType) */ static void window_new_campaign_get_shop_items() { - int32_t i, numItems; - Ride* ride; - uint64_t items = 0; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); - if (rideEntry == nullptr) + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) { - continue; + auto itemType = rideEntry->shop_item; + if (itemType != SHOP_ITEM_NONE && shop_item_is_food_or_drink(itemType)) + { + items |= 1ULL << itemType; + } } - uint8_t itemType = rideEntry->shop_item; - if (itemType != SHOP_ITEM_NONE && shop_item_is_food_or_drink(itemType)) - items |= 1ULL << itemType; } // - numItems = 0; - for (i = 0; i < 64; i++) + auto numItems = 0; + for (auto i = 0; i < 64; i++) { if (items & (1ULL << i)) { diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp index 9835ec4946..e24030bcf5 100644 --- a/src/openrct2/actions/SetCheatAction.hpp +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -442,77 +442,59 @@ private: void FixBrokenRides() const { - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) + for (auto& ride : GetRideManager()) { - if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) - && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) + if ((ride.mechanic_status != RIDE_MECHANIC_STATUS_FIXING) + && (ride.lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) { - auto mechanic = ride_get_assigned_mechanic(ride); + auto mechanic = ride_get_assigned_mechanic(&ride); if (mechanic != nullptr) { mechanic->RemoveFromRide(); } - ride_fix_breakdown(ride, 0); - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + ride_fix_breakdown(&ride, 0); + ride.window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; } } } void RenewRides() const { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - ride->Renew(); + ride.Renew(); } window_invalidate_by_class(WC_RIDE); } void MakeDestructible() const { - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + ride.lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; + ride.lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; } window_invalidate_by_class(WC_RIDE); } void ResetRideCrashStatus() const { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - // Reset crash status - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; - // Reset crash history - ride->last_crash_type = RIDE_CRASH_TYPE_NONE; + // Reset crash status and history + ride.lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; + ride.last_crash_type = RIDE_CRASH_TYPE_NONE; } window_invalidate_by_class(WC_RIDE); } void Set10MinuteInspection() const { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { // Set inspection interval to 10 minutes - ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; + ride.inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; } window_invalidate_by_class(WC_RIDE); } @@ -654,36 +636,34 @@ private: void RemoveAllGuests() const { - Peep* peep; - rct_vehicle* vehicle; uint16_t spriteIndex, nextSpriteIndex; - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) + for (auto& ride : GetRideManager()) { - ride->num_riders = 0; + ride.num_riders = 0; for (size_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) { - ride->stations[stationIndex].QueueLength = 0; - ride->stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; + ride.stations[stationIndex].QueueLength = 0; + ride.stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; } - for (auto trainIndex : ride->vehicles) + for (auto trainIndex : ride.vehicles) { spriteIndex = trainIndex; while (spriteIndex != SPRITE_INDEX_NULL) { - vehicle = GET_VEHICLE(spriteIndex); + auto vehicle = GET_VEHICLE(spriteIndex); for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++) { while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL) { offset++; } - peep = GET_PEEP(vehicle->peep[i + offset]); - vehicle->mass -= peep->mass; + auto peep = GET_PEEP(vehicle->peep[i + offset]); + if (peep != nullptr) + { + vehicle->mass -= peep->mass; + } } for (auto& peepInTrainIndex : vehicle->peep) @@ -701,7 +681,7 @@ private: for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { - peep = &(get_sprite(spriteIndex)->peep); + auto peep = &(get_sprite(spriteIndex)->peep); nextSpriteIndex = peep->next; if (peep->type == PEEP_TYPE_GUEST) { diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 05643e2031..6fc6dbbe7c 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -368,11 +368,9 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) auto price = arg1; if (int_valid[0]) { - uint16_t rideId{}; - Ride* ride; - FOR_ALL_RIDES (rideId, ride) + for (const auto& ride : GetRideManager()) { - auto rideSetPrice = RideSetPriceAction(rideId, price, true); + auto rideSetPrice = RideSetPriceAction(ride.id, price, true); GameActions::Execute(&rideSetPrice); } } diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index e6a3b07ea2..f9d04a8f04 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -18,6 +18,8 @@ #include "../world/Park.h" #include "NewsItem.h" +#include + #define NEGATIVE 0 #define POSITIVE 1 @@ -144,20 +146,16 @@ static bool award_is_deserved_most_tidy(int32_t activeAwardTypes) /** At least 6 open roller coasters. */ static bool award_is_deserved_best_rollercoasters([[maybe_unused]] int32_t activeAwardTypes) { - int32_t i, rollerCoasters; - Ride* ride; - rct_ride_entry* rideEntry; - - rollerCoasters = 0; - FOR_ALL_RIDES (i, ride) + auto rollerCoasters = 0; + for (const auto& ride : GetRideManager()) { - rideEntry = get_ride_entry(ride->subtype); + auto rideEntry = ride.GetRideEntry(); if (rideEntry == nullptr) { continue; } - if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) + if (ride.status != RIDE_STATUS_OPEN || (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { continue; } @@ -169,7 +167,6 @@ static bool award_is_deserved_best_rollercoasters([[maybe_unused]] int32_t activ rollerCoasters++; } - return (rollerCoasters >= 6); } @@ -250,12 +247,10 @@ static bool award_is_deserved_worst_value(int32_t activeAwardTypes) /** No more than 2 people who think the vandalism is bad and no crashes. */ static bool award_is_deserved_safest([[maybe_unused]] int32_t activeAwardTypes) { - int32_t i, peepsWhoDislikeVandalism; uint16_t spriteIndex; Peep* peep; - Ride* ride; - peepsWhoDislikeVandalism = 0; + auto peepsWhoDislikeVandalism = 0; FOR_ALL_GUESTS (spriteIndex, peep) { if (peep->outside_of_park != 0) @@ -268,10 +263,12 @@ static bool award_is_deserved_safest([[maybe_unused]] int32_t activeAwardTypes) return false; // Check for rides that have crashed maybe? - FOR_ALL_RIDES (i, ride) + const auto& rideManager = GetRideManager(); + if (std::any_of(rideManager.begin(), rideManager.end(), [](const Ride& ride) { + return ride.last_crash_type != RIDE_CRASH_TYPE_NONE; + })) { - if (ride->last_crash_type != RIDE_CRASH_TYPE_NONE) - return false; + return false; } return true; @@ -310,36 +307,28 @@ static bool award_is_deserved_best_staff(int32_t activeAwardTypes) /** At least 7 shops, 4 unique, one shop per 128 guests and no more than 12 hungry guests. */ static bool award_is_deserved_best_food(int32_t activeAwardTypes) { - int32_t i, hungryPeeps, shops, uniqueShops; - uint64_t shopTypes; - Ride* ride; - rct_ride_entry* rideEntry; - uint16_t spriteIndex; - Peep* peep; - if (activeAwardTypes & (1 << PARK_AWARD_WORST_FOOD)) return false; - shops = 0; - uniqueShops = 0; - shopTypes = 0; - FOR_ALL_RIDES (i, ride) + auto shops = 0; + auto uniqueShops = 0; + auto shopTypes = 0; + for (const auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_OPEN) + if (ride.status != RIDE_STATUS_OPEN) continue; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_SELLS_FOOD)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_SELLS_FOOD)) continue; shops++; - rideEntry = get_ride_entry(ride->subtype); - if (rideEntry == nullptr) + auto rideEntry = get_ride_entry(ride.subtype); + if (rideEntry != nullptr) { - continue; - } - if (!(shopTypes & (1ULL << rideEntry->shop_item))) - { - shopTypes |= (1ULL << rideEntry->shop_item); - uniqueShops++; + if (!(shopTypes & (1ULL << rideEntry->shop_item))) + { + shopTypes |= (1ULL << rideEntry->shop_item); + uniqueShops++; + } } } @@ -347,7 +336,9 @@ static bool award_is_deserved_best_food(int32_t activeAwardTypes) return false; // Count hungry peeps - hungryPeeps = 0; + auto hungryPeeps = 0; + uint16_t spriteIndex; + Peep* peep; FOR_ALL_GUESTS (spriteIndex, peep) { if (peep->outside_of_park != 0) @@ -356,43 +347,34 @@ static bool award_is_deserved_best_food(int32_t activeAwardTypes) if (peep->thoughts[0].freshness <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } - return (hungryPeeps <= 12); } /** No more than 2 unique shops, less than one shop per 256 guests and more than 15 hungry guests. */ static bool award_is_deserved_worst_food(int32_t activeAwardTypes) { - int32_t i, hungryPeeps, shops, uniqueShops; - uint64_t shopTypes; - Ride* ride; - rct_ride_entry* rideEntry; - uint16_t spriteIndex; - Peep* peep; - if (activeAwardTypes & (1 << PARK_AWARD_BEST_FOOD)) return false; - shops = 0; - uniqueShops = 0; - shopTypes = 0; - FOR_ALL_RIDES (i, ride) + auto shops = 0; + auto uniqueShops = 0; + auto shopTypes = 0; + for (const auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_OPEN) + if (ride.status != RIDE_STATUS_OPEN) continue; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_SELLS_FOOD)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_SELLS_FOOD)) continue; shops++; - rideEntry = get_ride_entry(ride->subtype); - if (rideEntry == nullptr) + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) { - continue; - } - if (!(shopTypes & (1ULL << rideEntry->shop_item))) - { - shopTypes |= (1ULL << rideEntry->shop_item); - uniqueShops++; + if (!(shopTypes & (1ULL << rideEntry->shop_item))) + { + shopTypes |= (1ULL << rideEntry->shop_item); + uniqueShops++; + } } } @@ -400,7 +382,9 @@ static bool award_is_deserved_worst_food(int32_t activeAwardTypes) return false; // Count hungry peeps - hungryPeeps = 0; + auto hungryPeeps = 0; + uint16_t spriteIndex; + Peep* peep; FOR_ALL_GUESTS (spriteIndex, peep) { if (peep->outside_of_park != 0) @@ -409,25 +393,17 @@ static bool award_is_deserved_worst_food(int32_t activeAwardTypes) if (peep->thoughts[0].freshness <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } - return (hungryPeeps > 15); } /** At least 4 restrooms, 1 restroom per 128 guests and no more than 16 guests who think they need the restroom. */ static bool award_is_deserved_best_restrooms([[maybe_unused]] int32_t activeAwardTypes) { - uint32_t i, numRestrooms, guestsWhoNeedRestroom; - Ride* ride; - uint16_t spriteIndex; - Peep* peep; - // Count open restrooms - numRestrooms = 0; - FOR_ALL_RIDES (i, ride) - { - if (ride->type == RIDE_TYPE_TOILETS && ride->status == RIDE_STATUS_OPEN) - numRestrooms++; - } + const auto& rideManager = GetRideManager(); + auto numRestrooms = std::count_if(rideManager.begin(), rideManager.end(), [](const Ride& ride) { + return ride.type == RIDE_TYPE_TOILETS && ride.status == RIDE_STATUS_OPEN; + }); // At least 4 open restrooms if (numRestrooms < 4) @@ -438,7 +414,9 @@ static bool award_is_deserved_best_restrooms([[maybe_unused]] int32_t activeAwar return false; // Count number of guests who are thinking they need the restroom - guestsWhoNeedRestroom = 0; + auto guestsWhoNeedRestroom = 0; + uint16_t spriteIndex; + Peep* peep; FOR_ALL_GUESTS (spriteIndex, peep) { if (peep->outside_of_park != 0) @@ -447,35 +425,30 @@ static bool award_is_deserved_best_restrooms([[maybe_unused]] int32_t activeAwar if (peep->thoughts[0].freshness <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) guestsWhoNeedRestroom++; } - return (guestsWhoNeedRestroom <= 16); } /** More than half of the rides have satisfaction <= 6 and park rating <= 650. */ static bool award_is_deserved_most_disappointing(int32_t activeAwardTypes) { - uint32_t i, countedRides, disappointingRides; - Ride* ride; - if (activeAwardTypes & (1 << PARK_AWARD_BEST_VALUE)) return false; if (gParkRating > 650) return false; // Count the number of disappointing rides - countedRides = 0; - disappointingRides = 0; - - FOR_ALL_RIDES (i, ride) + auto countedRides = 0; + auto disappointingRides = 0; + for (const auto& ride : GetRideManager()) { - if (ride->excitement == RIDE_RATING_UNDEFINED || ride->popularity == 0xFF) - continue; - - countedRides++; - - // Unpopular - if (ride->popularity <= 6) - disappointingRides++; + if (ride_has_ratings(&ride) && ride.popularity != 0xFF) + { + countedRides++; + if (ride.popularity <= 6) + { + disappointingRides++; + } + } } // Half of the rides are disappointing @@ -485,20 +458,16 @@ static bool award_is_deserved_most_disappointing(int32_t activeAwardTypes) /** At least 6 open water rides. */ static bool award_is_deserved_best_water_rides([[maybe_unused]] int32_t activeAwardTypes) { - int32_t i, waterRides; - Ride* ride; - rct_ride_entry* rideEntry; - - waterRides = 0; - FOR_ALL_RIDES (i, ride) + auto waterRides = 0; + for (const auto& ride : GetRideManager()) { - rideEntry = get_ride_entry(ride->subtype); + auto rideEntry = ride.GetRideEntry(); if (rideEntry == nullptr) { continue; } - if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) + if (ride.status != RIDE_STATUS_OPEN || (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { continue; } @@ -517,22 +486,19 @@ static bool award_is_deserved_best_water_rides([[maybe_unused]] int32_t activeAw /** At least 6 custom designed rides. */ static bool award_is_deserved_best_custom_designed_rides(int32_t activeAwardTypes) { - int32_t i, customDesignedRides; - Ride* ride; - if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) return false; - customDesignedRides = 0; - FOR_ALL_RIDES (i, ride) + auto customDesignedRides = 0; + for (const auto& ride : GetRideManager()) { - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_HAS_TRACK)) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN) continue; - if (ride->excitement < RIDE_RATING(5, 50)) + if (ride.excitement < RIDE_RATING(5, 50)) continue; - if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) + if (ride.status != RIDE_STATUS_OPEN || (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) continue; customDesignedRides++; @@ -541,29 +507,25 @@ static bool award_is_deserved_best_custom_designed_rides(int32_t activeAwardType return (customDesignedRides >= 6); } -/** At least 5 colourful rides and more than half of the rides are colourful. */ -static constexpr const uint8_t dazzling_ride_colours[] = { COLOUR_BRIGHT_PURPLE, COLOUR_BRIGHT_GREEN, COLOUR_LIGHT_ORANGE, - COLOUR_BRIGHT_PINK }; - static bool award_is_deserved_most_dazzling_ride_colours(int32_t activeAwardTypes) { - int32_t i, countedRides, colourfulRides; - Ride* ride; - uint8_t mainTrackColour; + /** At least 5 colourful rides and more than half of the rides are colourful. */ + static constexpr const colour_t dazzling_ride_colours[] = { COLOUR_BRIGHT_PURPLE, COLOUR_BRIGHT_GREEN, COLOUR_LIGHT_ORANGE, + COLOUR_BRIGHT_PINK }; if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) return false; - countedRides = 0; - colourfulRides = 0; - FOR_ALL_RIDES (i, ride) + auto countedRides = 0; + auto colourfulRides = 0; + for (const auto& ride : GetRideManager()) { - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_HAS_TRACK)) continue; countedRides++; - mainTrackColour = ride->track_colour[0].main; + auto mainTrackColour = ride.track_colour[0].main; for (auto dazzling_ride_colour : dazzling_ride_colours) { if (mainTrackColour == dazzling_ride_colour) @@ -603,20 +565,16 @@ static bool award_is_deserved_most_confusing_layout([[maybe_unused]] int32_t act /** At least 10 open gentle rides. */ static bool award_is_deserved_best_gentle_rides([[maybe_unused]] int32_t activeAwardTypes) { - int32_t i, gentleRides; - Ride* ride; - rct_ride_entry* rideEntry; - - gentleRides = 0; - FOR_ALL_RIDES (i, ride) + auto gentleRides = 0; + for (const auto& ride : GetRideManager()) { - rideEntry = get_ride_entry(ride->subtype); + auto rideEntry = ride.GetRideEntry(); if (rideEntry == nullptr) { continue; } - if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) + if (ride.status != RIDE_STATUS_OPEN || (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { continue; } diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index 9eedd38245..80b0e46934 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -179,30 +179,27 @@ void finance_pay_interest() */ void finance_pay_ride_upkeep() { - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED)) + if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED)) { - ride->Renew(); + ride.Renew(); } - if (ride->status != RIDE_STATUS_CLOSED && !(gParkFlags & PARK_FLAGS_NO_MONEY)) + if (ride.status != RIDE_STATUS_CLOSED && !(gParkFlags & PARK_FLAGS_NO_MONEY)) { - int16_t upkeep = ride->upkeep_cost; + int16_t upkeep = ride.upkeep_cost; if (upkeep != -1) { - ride->total_profit -= upkeep; - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; + ride.total_profit -= upkeep; + ride.window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; finance_payment(upkeep, RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS); } } - if (ride->last_crash_type != RIDE_CRASH_TYPE_NONE) + if (ride.last_crash_type != RIDE_CRASH_TYPE_NONE) { - ride->last_crash_type--; + ride.last_crash_type--; } } } @@ -283,13 +280,11 @@ void finance_update_daily_profit() current_profit -= current_loan / 600; // Ride costs - Ride* ride; - int32_t i; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_CLOSED && ride->upkeep_cost != MONEY16_UNDEFINED) + if (ride.status != RIDE_STATUS_CLOSED && ride.upkeep_cost != MONEY16_UNDEFINED) { - current_profit -= 2 * ride->upkeep_cost; + current_profit -= 2 * ride.upkeep_cost; } } } diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 55d7f0a78d..57f66e1ac6 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -161,10 +161,6 @@ void marketing_set_guest_campaign(Peep* peep, int32_t campaignType) bool marketing_is_campaign_type_applicable(int32_t campaignType) { - int32_t i; - Ride* ride; - rct_ride_entry* rideEntry; - switch (campaignType) { case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: @@ -180,9 +176,9 @@ bool marketing_is_campaign_type_applicable(int32_t campaignType) // fall-through case ADVERTISING_CAMPAIGN_RIDE: // Check if any rides exist - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->IsRide()) + if (ride.IsRide()) { return true; } @@ -191,17 +187,16 @@ bool marketing_is_campaign_type_applicable(int32_t campaignType) case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: // Check if any food or drink stalls exist - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - rideEntry = get_ride_entry(ride->subtype); - if (rideEntry == nullptr) + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) { - continue; - } - if (shop_item_is_food_or_drink(rideEntry->shop_item) - || shop_item_is_food_or_drink(rideEntry->shop_item_secondary)) - { - return true; + if (shop_item_is_food_or_drink(rideEntry->shop_item) + || shop_item_is_food_or_drink(rideEntry->shop_item_secondary)) + { + return true; + } } } return false; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index fb198f9ce0..2f9f2979f8 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1912,13 +1912,11 @@ std::bitset Guest::FindRidesToGoOn() if (item_standard_flags & PEEP_ITEM_MAP) { // Consider rides that peep hasn't been on yet - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (!HasRidden(ride)) + if (!HasRidden(&ride)) { - rideConsideration[i] = true; + rideConsideration[ride.id] = true; } } } @@ -1951,13 +1949,11 @@ std::bitset Guest::FindRidesToGoOn() } // Always take the tall rides into consideration (realistic as you can usually see them from anywhere in the park) - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->highest_drop_height > 66 || ride->excitement >= RIDE_RATING(8, 00)) + if (ride.highest_drop_height > 66 || ride.excitement >= RIDE_RATING(8, 00)) { - rideConsideration[i] = true; + rideConsideration[ride.id] = true; } } } @@ -3154,8 +3150,6 @@ static void peep_leave_park(Peep* peep) */ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) { - Ride* ride; - if (peep->state != PEEP_STATE_SITTING && peep->state != PEEP_STATE_WATCHING && peep->state != PEEP_STATE_WALKING) { return; @@ -3166,8 +3160,8 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) return; if (peep->guest_heading_to_ride_id != RIDE_ID_NULL) { - ride = get_ride(peep->guest_heading_to_ride_id); - if (ride->type == rideType) + auto ride = get_ride(peep->guest_heading_to_ride_id); + if (ride != nullptr && ride->type == rideType) { return; } @@ -3179,12 +3173,11 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) if ((peep->item_standard_flags & PEEP_ITEM_MAP) && rideType != RIDE_TYPE_FIRST_AID) { // Consider all rides in the park - int32_t i; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->type == rideType) + if (ride.type == rideType) { - rideConsideration[i >> 5] |= (1u << (i & 0x1F)); + rideConsideration[ride.id >> 5] |= (1u << (ride.id & 0x1F)); } } } @@ -3206,8 +3199,8 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) continue; ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - ride = get_ride(rideIndex); - if (ride->type == rideType) + auto ride = get_ride(rideIndex); + if (ride != nullptr && ride->type == rideType) { rideConsideration[rideIndex >> 5] |= (1u << (rideIndex & 0x1F)); } @@ -3226,8 +3219,8 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) if (!(rideConsideration[i >> 5] & (1u << (i & 0x1F)))) continue; - ride = get_ride(i); - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) + auto ride = get_ride(i); + if (ride != nullptr && !(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) { if (peep->ShouldGoOnRide(ride, 0, false, true)) { @@ -3242,14 +3235,17 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) int32_t closestRideDistance = std::numeric_limits::max(); for (int32_t i = 0; i < numPotentialRides; i++) { - ride = get_ride(potentialRides[i]); - int32_t rideX = ride->stations[0].Start.x * 32; - int32_t rideY = ride->stations[0].Start.y * 32; - int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); - if (distance < closestRideDistance) + auto ride = get_ride(potentialRides[i]); + if (ride != nullptr) { - closestRideIndex = potentialRides[i]; - closestRideDistance = distance; + int32_t rideX = ride->stations[0].Start.x * 32; + int32_t rideY = ride->stations[0].Start.y * 32; + int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); + if (distance < closestRideDistance) + { + closestRideIndex = potentialRides[i]; + closestRideDistance = distance; + } } } if (closestRideIndex == RIDE_ID_NULL) @@ -3270,8 +3266,6 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) */ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeFlags) { - Ride* ride; - if (peep->state != PEEP_STATE_SITTING && peep->state != PEEP_STATE_WATCHING && peep->state != PEEP_STATE_WALKING) { return; @@ -3282,8 +3276,9 @@ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeF return; if (peep->guest_heading_to_ride_id != RIDE_ID_NULL) { - ride = get_ride(peep->guest_heading_to_ride_id); - if (ride_type_has_flag( + auto ride = get_ride(peep->guest_heading_to_ride_id); + if (ride != nullptr + && ride_type_has_flag( ride->type, RIDE_TYPE_FLAG_IS_BATHROOM | RIDE_TYPE_FLAG_SELLS_DRINKS | RIDE_TYPE_FLAG_SELLS_FOOD)) { return; @@ -3301,12 +3296,11 @@ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeF if (peep->item_standard_flags & PEEP_ITEM_MAP) { // Consider all rides in the park - int32_t i; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride_type_has_flag(ride->type, rideTypeFlags)) + if (ride_type_has_flag(ride.type, rideTypeFlags)) { - rideConsideration[i >> 5] |= (1u << (i & 0x1F)); + rideConsideration[ride.id >> 5] |= (1u << (ride.id & 0x1F)); } } } @@ -3328,8 +3322,8 @@ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeF continue; ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - ride = get_ride(rideIndex); - if (ride_type_has_flag(ride->type, rideTypeFlags)) + auto ride = get_ride(rideIndex); + if (ride != nullptr && ride_type_has_flag(ride->type, rideTypeFlags)) { rideConsideration[rideIndex >> 5] |= (1u << (rideIndex & 0x1F)); } @@ -3348,8 +3342,8 @@ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeF if (!(rideConsideration[i >> 5] & (1u << (i & 0x1F)))) continue; - ride = get_ride(i); - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) + auto ride = get_ride(i); + if (ride != nullptr && !(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) { if (peep->ShouldGoOnRide(ride, 0, false, true)) { @@ -3364,14 +3358,17 @@ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeF int32_t closestRideDistance = std::numeric_limits::max(); for (int32_t i = 0; i < numPotentialRides; i++) { - ride = get_ride(potentialRides[i]); - int32_t rideX = ride->stations[0].Start.x * 32; - int32_t rideY = ride->stations[0].Start.y * 32; - int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); - if (distance < closestRideDistance) + auto ride = get_ride(potentialRides[i]); + if (ride != nullptr) { - closestRideIndex = potentialRides[i]; - closestRideDistance = distance; + int32_t rideX = ride->stations[0].Start.x * 32; + int32_t rideY = ride->stations[0].Start.y * 32; + int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); + if (distance < closestRideDistance) + { + closestRideIndex = potentialRides[i]; + closestRideDistance = distance; + } } } if (closestRideIndex == RIDE_ID_NULL) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 7776be6070..bf0b944456 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1081,16 +1081,14 @@ private: void FixRideVehicleLinks(const uint16_t* spriteIndexMap) { - uint8_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - for (uint8_t j = 0; j < std::size(ride->vehicles); j++) + for (uint8_t j = 0; j < std::size(ride.vehicles); j++) { - uint16_t originalIndex = ride->vehicles[j]; + uint16_t originalIndex = ride.vehicles[j]; if (originalIndex != SPRITE_INDEX_NULL) { - ride->vehicles[j] = spriteIndexMap[originalIndex]; + ride.vehicles[j] = spriteIndexMap[originalIndex]; } } } @@ -1368,15 +1366,13 @@ private: } } - int i; - Ride* ride; - Peep* peep; - - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - FixRidePeepLinks(ride, spriteIndexMap); + FixRidePeepLinks(&ride, spriteIndexMap); } + int32_t i; + Peep* peep; FOR_ALL_GUESTS (i, peep) { FixPeepNextInQueue(peep, spriteIndexMap); @@ -3018,13 +3014,11 @@ private: */ void SetDefaultNames() { - ride_id_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->custom_name.empty()) + if (ride.custom_name.empty()) { - ride->SetNameToDefault(); + ride.SetNameToDefault(); } } } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 3cb04ae1c7..9098f1f944 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -868,7 +868,7 @@ void Ride::FormatStatusTo(void* argsV) const } } -int32_t ride_get_total_length(Ride* ride) +int32_t ride_get_total_length(const Ride* ride) { int32_t i, totalLength = 0; for (i = 0; i < ride->num_stations; i++) diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 343ecbf587..e2129f8a21 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1016,7 +1016,7 @@ struct RideManager size_t _endIndex{}; public: - using difference_type = ride_id_t; + using difference_type = intptr_t; using value_type = Ride; using pointer = const Ride*; using reference = const Ride&; @@ -1147,7 +1147,7 @@ void ride_remove_peeps(Ride* ride); void ride_clear_blocked_tiles(Ride* ride); Staff* ride_get_mechanic(Ride* ride); Staff* ride_get_assigned_mechanic(Ride* ride); -int32_t ride_get_total_length(Ride* ride); +int32_t ride_get_total_length(const Ride* ride); int32_t ride_get_total_time(Ride* ride); TrackColour ride_get_track_colour(Ride* ride, int32_t colourScheme); vehicle_colour ride_get_vehicle_colour(Ride* ride, int32_t vehicleIndex); @@ -1283,8 +1283,4 @@ LocationXY16 ride_get_rotated_coords(int16_t x, int16_t y, int16_t z); void determine_ride_entrance_and_exit_locations(); void ride_clear_leftover_entrances(Ride* ride); -#define FOR_ALL_RIDES(i, ride) \ - for (auto& __ride : GetRideManager()) \ - if ((ride = &__ride) != nullptr && (i = __ride.id) != RIDE_ID_NULL) - #endif diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 4cdb7a8f71..eaf1522c5e 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -809,14 +809,10 @@ static void ride_ratings_calculate_value(Ride* ride) } // Other ride of same type penalty - int32_t otherRidesOfSameType = 0; - Ride* ride2; - int32_t i; - FOR_ALL_RIDES (i, ride2) - { - if (ride2->type == ride->type && ride2->status == RIDE_STATUS_OPEN) - otherRidesOfSameType++; - } + const auto& rideManager = GetRideManager(); + auto otherRidesOfSameType = std::count_if(rideManager.begin(), rideManager.end(), [ride](const Ride& r) { + return r.status == RIDE_STATUS_OPEN && r.type == ride->type; + }); if (otherRidesOfSameType > 1) value -= value / 4; @@ -2005,9 +2001,9 @@ static void ride_ratings_calculate_boat_hire(Ride* ride) ride->unreliability_factor = 7; set_unreliability_factor(ride); - // NOTE In the original game, the ratings were zeroed before calling set_unreliability_factor which is unusual as rest of - // the calculation functions do this before hand. This is because set_unreliability_factor alters the value of - // ebx (excitement). This is assumed to be a bug and therefore fixed. + // NOTE In the original game, the ratings were zeroed before calling set_unreliability_factor which is unusual as rest + // of the calculation functions do this before hand. This is because set_unreliability_factor alters the value of ebx + // (excitement). This is assumed to be a bug and therefore fixed. rating_tuple ratings; ride_ratings_set(&ratings, RIDE_RATING(1, 90), RIDE_RATING(0, 80), RIDE_RATING(0, 90)); diff --git a/src/openrct2/ride/ShopItem.cpp b/src/openrct2/ride/ShopItem.cpp index a8bb394d9e..4c898b0e0d 100644 --- a/src/openrct2/ride/ShopItem.cpp +++ b/src/openrct2/ride/ShopItem.cpp @@ -78,30 +78,26 @@ const ShopItemDescriptor ShopItems[SHOP_ITEM_COUNT] = { money32 shop_item_get_common_price(Ride* forRide, int32_t shopItem) { - rct_ride_entry* rideEntry; - Ride* ride; - int32_t i; - - FOR_ALL_RIDES (i, ride) + for (const auto& ride : GetRideManager()) { - if (ride != forRide) + if (&ride != forRide) { - rideEntry = get_ride_entry(ride->subtype); + auto rideEntry = ride.GetRideEntry(); if (rideEntry == nullptr) { continue; } if (rideEntry->shop_item == shopItem) { - return ride->price; + return ride.price; } if (rideEntry->shop_item_secondary == shopItem) { - return ride->price_secondary; + return ride.price_secondary; } - if (shop_item_is_photo(shopItem) && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO)) + if (shop_item_is_photo(shopItem) && (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO)) { - return ride->price_secondary; + return ride.price_secondary; } } } diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index cfb89f6fcc..6e11911143 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -49,6 +49,7 @@ #include "ScenarioSources.h" #include +#include const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT] = { STR_BEGINNER_PARKS, STR_CHALLENGING_PARKS, STR_EXPERT_PARKS, STR_REAL_PARKS, STR_OTHER_PARKS, @@ -516,24 +517,23 @@ uint32_t scenario_rand_max(uint32_t max) static bool scenario_prepare_rides_for_save() { int32_t isFiveCoasterObjective = gScenarioObjectiveType == OBJECTIVE_FINISH_5_ROLLERCOASTERS; - int32_t i; - Ride* ride; uint8_t rcs = 0; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - const rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); - - // If there are more than 5 roller coasters, only mark the first five. - if (isFiveCoasterObjective && rideEntry != nullptr - && (ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) && rcs < 5)) + const auto* rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) { - ride->lifecycle_flags |= RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; - rcs++; - } - else - { - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + // If there are more than 5 roller coasters, only mark the first five. + if (isFiveCoasterObjective && (ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) && rcs < 5)) + { + ride.lifecycle_flags |= RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + rcs++; + } + else + { + ride.lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + } } } @@ -554,7 +554,7 @@ static bool scenario_prepare_rides_for_save() if (isFiveCoasterObjective) { - ride = get_ride(it.element->AsTrack()->GetRideIndex()); + auto ride = get_ride(it.element->AsTrack()->GetRideIndex()); // In the previous step, this flag was set on the first five roller coasters. if (ride != nullptr && ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) @@ -733,30 +733,27 @@ static void scenario_objective_check_park_value_by() **/ static void scenario_objective_check_10_rollercoasters() { - int32_t i, rcs = 0; - uint8_t type_already_counted[256] = {}; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + auto rcs = 0; + std::bitset type_already_counted; + for (const auto& ride : GetRideManager()) { - uint8_t subtype_id = ride->subtype; - rct_ride_entry* rideEntry = get_ride_entry(subtype_id); - if (rideEntry == nullptr) + if (ride.status == RIDE_STATUS_OPEN && ride.excitement >= RIDE_RATING(6, 00) && ride.subtype < RIDE_TYPE_COUNT) { - continue; - } - - if (rideEntry != nullptr && ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) - && ride->status == RIDE_STATUS_OPEN && ride->excitement >= RIDE_RATING(6, 00) - && type_already_counted[subtype_id] == 0) - { - type_already_counted[subtype_id]++; - rcs++; + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) + { + if (ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) && !type_already_counted[ride.subtype]) + { + type_already_counted[ride.subtype] = true; + rcs++; + } + } } } - if (rcs >= 10) + { scenario_success(); + } } /** @@ -830,59 +827,59 @@ static void scenario_objective_check_monthly_ride_income() */ static void scenario_objective_check_10_rollercoasters_length() { - int32_t i, rcs = 0; - uint8_t type_already_counted[256] = {}; - int16_t objective_length = gScenarioObjectiveNumGuests; - Ride* ride; - - FOR_ALL_RIDES (i, ride) + const auto objective_length = gScenarioObjectiveNumGuests; + std::bitset type_already_counted; + auto rcs = 0; + for (const auto& ride : GetRideManager()) { - uint8_t subtype_id = ride->subtype; - rct_ride_entry* rideEntry = get_ride_entry(subtype_id); - if (rideEntry == nullptr) + if (ride.status == RIDE_STATUS_OPEN && ride.excitement >= RIDE_RATING(7, 00) && ride.subtype < RIDE_TYPE_COUNT) { - continue; - } - if (ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) && ride->status == RIDE_STATUS_OPEN - && ride->excitement >= RIDE_RATING(7, 00) && type_already_counted[subtype_id] == 0) - { - if ((ride_get_total_length(ride) >> 16) > objective_length) + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) { - type_already_counted[subtype_id]++; - rcs++; + if (ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER) && !type_already_counted[ride.subtype]) + { + if ((ride_get_total_length(&ride) >> 16) > objective_length) + { + type_already_counted[ride.subtype] = true; + rcs++; + } + } } } } - if (rcs >= 10) + { scenario_success(); + } } static void scenario_objective_check_finish_5_rollercoasters() { - money32 objectiveRideExcitement = gScenarioObjectiveCurrency; + const auto objectiveRideExcitement = gScenarioObjectiveCurrency; // Originally, this did not check for null rides, neither did it check if // the rides are even rollercoasters, never mind the right rollercoasters to be finished. - int32_t i; - Ride* ride; - int32_t rcs = 0; - FOR_ALL_RIDES (i, ride) + auto rcs = 0; + for (const auto& ride : GetRideManager()) { - const rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); - if (rideEntry == nullptr) + if (ride.status != RIDE_STATUS_CLOSED && ride.excitement >= objectiveRideExcitement) { - continue; + auto rideEntry = ride.GetRideEntry(); + if (rideEntry != nullptr) + { + if ((ride.lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) + && ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER)) + { + rcs++; + } + } } - - if (ride->status != RIDE_STATUS_CLOSED && ride->excitement >= objectiveRideExcitement - && (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) && // Set on partially finished coasters - ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER)) - rcs++; } - if (rcs >= 5) + { scenario_success(); + } } static void scenario_objective_check_replay_loan_and_park_value() diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index be414338a8..01fa549f67 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -209,8 +209,6 @@ WallElement* banner_get_scrolling_wall_tile_element(BannerIndex bannerIndex) */ uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z) { - Ride* ride; - static constexpr const LocationXY16 NeighbourCheckOrder[] = { { 32, 0 }, { -32, 0 }, { 0, 32 }, { 0, -32 }, { -32, +32 }, { +32, -32 }, { +32, +32 }, { -32, +32 }, { 0, 0 } }; @@ -224,15 +222,14 @@ uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z) } } - uint8_t index; - ride_id_t rideIndex = RIDE_ID_NULL; - int32_t resultDistance = std::numeric_limits::max(); - FOR_ALL_RIDES (index, ride) + auto rideIndex = RIDE_ID_NULL; + auto resultDistance = std::numeric_limits::max(); + for (auto& ride : GetRideManager()) { - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + if (ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_IS_SHOP)) continue; - LocationXY8 location = ride->overall_view; + LocationXY8 location = ride.overall_view; if (location.xy == RCT_XY8_UNDEFINED) continue; @@ -242,10 +239,9 @@ uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z) if (distance < resultDistance) { resultDistance = distance; - rideIndex = index; + rideIndex = ride.id; } } - return rideIndex; } diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index b9eebad9f7..7723ec4b17 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -421,16 +421,13 @@ int32_t Park::CalculateParkRating() const int32_t totalRideUptime = 0; int32_t totalRideIntensity = 0; int32_t totalRideExcitement = 0; - - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - totalRideUptime += 100 - ride->downtime; - if (ride->excitement != RIDE_RATING_UNDEFINED) + totalRideUptime += 100 - ride.downtime; + if (ride_has_ratings(&ride)) { - totalRideExcitement += ride->excitement / 8; - totalRideIntensity += ride->intensity / 8; + totalRideExcitement += ride.excitement / 8; + totalRideIntensity += ride.intensity / 8; excitingRideCount++; } rideCount++; @@ -524,21 +521,19 @@ money32 Park::CalculateCompanyValue() const money16 Park::CalculateTotalRideValueForMoney() const { money16 totalRideValue = 0; - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_OPEN) + if (ride.status != RIDE_STATUS_OPEN) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) continue; // Add ride value - if (ride->value != RIDE_VALUE_UNDEFINED) + if (ride.value != RIDE_VALUE_UNDEFINED) { - money16 rideValue = (money16)(ride->value - ride->price); + money16 rideValue = (money16)(ride.value - ride.price); if (rideValue > 0) { totalRideValue += rideValue * 2; @@ -553,44 +548,42 @@ uint32_t Park::CalculateSuggestedMaxGuests() const uint32_t suggestedMaxGuests = 0; // TODO combine the two ride loops - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->status != RIDE_STATUS_OPEN) + if (ride.status != RIDE_STATUS_OPEN) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) continue; // Add guest score for ride type - suggestedMaxGuests += rideBonusValue[ride->type]; + suggestedMaxGuests += rideBonusValue[ride.type]; } // If difficult guest generation, extra guests are available for good rides if (gParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) { suggestedMaxGuests = std::min(suggestedMaxGuests, 1000); - FOR_ALL_RIDES (i, ride) + for (auto& ride : GetRideManager()) { - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) continue; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) continue; - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_TESTED)) continue; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_HAS_TRACK)) continue; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_DATA_LOGGING)) + if (!ride_type_has_flag(ride.type, RIDE_TYPE_FLAG_HAS_DATA_LOGGING)) continue; - if (ride->stations[0].SegmentLength < (600 << 16)) + if (ride.stations[0].SegmentLength < (600 << 16)) continue; - if (ride->excitement < RIDE_RATING(6, 00)) + if (ride.excitement < RIDE_RATING(6, 00)) continue; // Bonus guests for good ride - suggestedMaxGuests += rideBonusValue[ride->type] * 2; + suggestedMaxGuests += rideBonusValue[ride.type] * 2; } } diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index 6c965985dd..8582f7b52b 100644 --- a/test/tests/Pathfinding.cpp +++ b/test/tests/Pathfinding.cpp @@ -50,16 +50,16 @@ public: } protected: - static Ride* FindRideByName(const char* name, ride_id_t* outRideIndex) + static Ride* FindRideByName(const char* name) { - Ride* ride; - FOR_ALL_RIDES ((*outRideIndex), ride) + for (auto& ride : GetRideManager()) { - auto thisName = ride->GetName(); + auto thisName = ride.GetName(); if (!_strnicmp(thisName.c_str(), name, sizeof(thisName))) - return ride; + { + return &ride; + } } - return nullptr; } @@ -197,8 +197,7 @@ TEST_P(SimplePathfindingTest, CanFindPathFromStartToGoal) ASSERT_PRED_FORMAT1(AssertIsStartPosition, scenario.start); TileCoordsXYZ pos = scenario.start; - ride_id_t rideIndex; - Ride* ride = FindRideByName(scenario.name, &rideIndex); + auto ride = FindRideByName(scenario.name); ASSERT_NE(ride, nullptr); auto entrancePos = ride_get_entrance_location(ride, 0); @@ -206,8 +205,8 @@ TEST_P(SimplePathfindingTest, CanFindPathFromStartToGoal) entrancePos.x - TileDirectionDelta[entrancePos.direction].x, entrancePos.y - TileDirectionDelta[entrancePos.direction].y, entrancePos.z); - const auto succeeded = FindPath(&pos, goal, scenario.steps, rideIndex) ? ::testing::AssertionSuccess() - : ::testing::AssertionFailure() + const auto succeeded = FindPath(&pos, goal, scenario.steps, ride->id) ? ::testing::AssertionSuccess() + : ::testing::AssertionFailure() << "Failed to find path from " << scenario.start << " to " << goal << " in " << scenario.steps << " steps; reached " << pos << " before giving up."; @@ -236,8 +235,7 @@ TEST_P(ImpossiblePathfindingTest, CannotFindPathFromStartToGoal) TileCoordsXYZ pos = scenario.start; ASSERT_PRED_FORMAT1(AssertIsStartPosition, scenario.start); - ride_id_t rideIndex; - Ride* ride = FindRideByName(scenario.name, &rideIndex); + auto ride = FindRideByName(scenario.name); ASSERT_NE(ride, nullptr); auto entrancePos = ride_get_entrance_location(ride, 0); @@ -245,7 +243,7 @@ TEST_P(ImpossiblePathfindingTest, CannotFindPathFromStartToGoal) entrancePos.x + TileDirectionDelta[entrancePos.direction].x, entrancePos.y + TileDirectionDelta[entrancePos.direction].y, entrancePos.z); - EXPECT_FALSE(FindPath(&pos, goal, 10000, rideIndex)); + EXPECT_FALSE(FindPath(&pos, goal, 10000, ride->id)); } INSTANTIATE_TEST_CASE_P( From 802221111211bc5088d84bdfb020fa1027aef961 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 16:34:57 +0100 Subject: [PATCH 5/7] Refactor guest ride consideration --- src/openrct2/peep/Guest.cpp | 231 +++++++---------------------- src/openrct2/scenario/Scenario.cpp | 7 +- 2 files changed, 58 insertions(+), 180 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 2f9f2979f8..db3c043879 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -3144,11 +3144,7 @@ static void peep_leave_park(Peep* peep) window_invalidate_by_number(WC_PEEP, peep->sprite_index); } -/** - * - * rct2: 0x00695B70 - */ -static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) +template static void peep_head_for_nearest_ride(Guest* peep, bool considerOnlyCloseRides, T predicate) { if (peep->state != PEEP_STATE_SITTING && peep->state != PEEP_STATE_WATCHING && peep->state != PEEP_STATE_WALKING) { @@ -3161,79 +3157,78 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) if (peep->guest_heading_to_ride_id != RIDE_ID_NULL) { auto ride = get_ride(peep->guest_heading_to_ride_id); - if (ride != nullptr && ride->type == rideType) + if (ride != nullptr && predicate(*ride)) { return; } } - uint32_t rideConsideration[8]{}; - - // FIX Originally checked for a toy,.likely a mistake and should be a map - if ((peep->item_standard_flags & PEEP_ITEM_MAP) && rideType != RIDE_TYPE_FIRST_AID) + std::bitset rideConsideration; + if (!considerOnlyCloseRides && (peep->item_standard_flags & PEEP_ITEM_MAP)) { // Consider all rides in the park - for (auto& ride : GetRideManager()) + for (const auto& ride : GetRideManager()) { - if (ride.type == rideType) + if (predicate(ride)) { - rideConsideration[ride.id >> 5] |= (1u << (ride.id & 0x1F)); + rideConsideration[ride.id] = true; } } } else { // Take nearby rides into consideration + constexpr auto searchRadius = 10 * 32; int32_t cx = floor2(peep->x, 32); int32_t cy = floor2(peep->y, 32); - for (int32_t x = cx - 320; x <= cx + 320; x += 32) + for (auto x = cx - searchRadius; x <= cx + searchRadius; x += 32) { - for (int32_t y = cy - 320; y <= cy + 320; y += 32) + for (auto y = cy - searchRadius; y <= cy + searchRadius; y += 32) { - if (x >= 0 && y >= 0 && x < (256 * 32) && y < (256 * 32)) + if (map_is_location_valid({ x, y })) { - TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); - do + auto tileElement = map_get_first_element_at(x >> 5, y >> 5); + if (tileElement != nullptr) { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - - ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - auto ride = get_ride(rideIndex); - if (ride != nullptr && ride->type == rideType) + do { - rideConsideration[rideIndex >> 5] |= (1u << (rideIndex & 0x1F)); - } - } while (!(tileElement++)->IsLastForTile()); + if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK) + { + auto rideIndex = tileElement->AsTrack()->GetRideIndex(); + auto ride = get_ride(rideIndex); + if (ride != nullptr && predicate(*ride)) + { + rideConsideration[rideIndex] = true; + } + } + } while (!(tileElement++)->IsLastForTile()); + } } } } } // Filter the considered rides - uint8_t potentialRides[256]; - uint8_t* nextPotentialRide = &potentialRides[0]; - int32_t numPotentialRides = 0; - for (int32_t i = 0; i < MAX_RIDES; i++) + uint8_t potentialRides[MAX_RIDES]; + size_t numPotentialRides = 0; + for (auto& ride : GetRideManager()) { - if (!(rideConsideration[i >> 5] & (1u << (i & 0x1F)))) - continue; - - auto ride = get_ride(i); - if (ride != nullptr && !(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) + if (rideConsideration[ride.id]) { - if (peep->ShouldGoOnRide(ride, 0, false, true)) + if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) { - *nextPotentialRide++ = i; - numPotentialRides++; + if (peep->ShouldGoOnRide(&ride, 0, false, true)) + { + potentialRides[numPotentialRides++] = ride.id; + } } } } // Pick the closest ride - ride_id_t closestRideIndex = RIDE_ID_NULL; - int32_t closestRideDistance = std::numeric_limits::max(); - for (int32_t i = 0; i < numPotentialRides; i++) + Ride* closestRide{}; + auto closestRideDistance = std::numeric_limits::max(); + for (size_t i = 0; i < numPotentialRides; i++) { auto ride = get_ride(potentialRides[i]); if (ride != nullptr) @@ -3243,151 +3238,37 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); if (distance < closestRideDistance) { - closestRideIndex = potentialRides[i]; + closestRide = ride; closestRideDistance = distance; } } } - if (closestRideIndex == RIDE_ID_NULL) - return; - - // Head to that ride - peep->guest_heading_to_ride_id = closestRideIndex; - peep->peep_is_lost_countdown = 200; - peep_reset_pathfind_goal(peep); - peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; - - peep->time_lost = 0; + if (closestRide != nullptr) + { + // Head to that ride + peep->guest_heading_to_ride_id = closestRide->id; + peep->peep_is_lost_countdown = 200; + peep_reset_pathfind_goal(peep); + peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; + peep->time_lost = 0; + } +} + +static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) +{ + auto considerOnlyCloseRides = rideType == RIDE_TYPE_FIRST_AID; + return peep_head_for_nearest_ride( + peep, considerOnlyCloseRides, [rideType](const Ride& ride) { return ride.type == rideType; }); } -/** - * - * rct2: 0x006958D0 - */ static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeFlags) { - if (peep->state != PEEP_STATE_SITTING && peep->state != PEEP_STATE_WATCHING && peep->state != PEEP_STATE_WALKING) - { - return; - } - if (peep->peep_flags & PEEP_FLAGS_LEAVING_PARK) - return; - if (peep->x == LOCATION_NULL) - return; - if (peep->guest_heading_to_ride_id != RIDE_ID_NULL) - { - auto ride = get_ride(peep->guest_heading_to_ride_id); - if (ride != nullptr - && ride_type_has_flag( - ride->type, RIDE_TYPE_FLAG_IS_BATHROOM | RIDE_TYPE_FLAG_SELLS_DRINKS | RIDE_TYPE_FLAG_SELLS_FOOD)) - { - return; - } - } - if ((rideTypeFlags & RIDE_TYPE_FLAG_IS_BATHROOM) && peep->HasFood()) { return; } - - uint32_t rideConsideration[8]{}; - - // FIX Originally checked for a toy,.likely a mistake and should be a map - if (peep->item_standard_flags & PEEP_ITEM_MAP) - { - // Consider all rides in the park - for (auto& ride : GetRideManager()) - { - if (ride_type_has_flag(ride.type, rideTypeFlags)) - { - rideConsideration[ride.id >> 5] |= (1u << (ride.id & 0x1F)); - } - } - } - else - { - // Take nearby rides into consideration - int32_t cx = floor2(peep->x, 32); - int32_t cy = floor2(peep->y, 32); - for (int32_t x = cx - 320; x <= cx + 320; x += 32) - { - for (int32_t y = cy - 320; y <= cy + 320; y += 32) - { - if (x >= 0 && y >= 0 && x < (256 * 32) && y < (256 * 32)) - { - TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); - do - { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - - ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - auto ride = get_ride(rideIndex); - if (ride != nullptr && ride_type_has_flag(ride->type, rideTypeFlags)) - { - rideConsideration[rideIndex >> 5] |= (1u << (rideIndex & 0x1F)); - } - } while (!(tileElement++)->IsLastForTile()); - } - } - } - } - - // Filter the considered rides - uint8_t potentialRides[256]; - uint8_t* nextPotentialRide = &potentialRides[0]; - int32_t numPotentialRides = 0; - for (int32_t i = 0; i < MAX_RIDES; i++) - { - if (!(rideConsideration[i >> 5] & (1u << (i & 0x1F)))) - continue; - - auto ride = get_ride(i); - if (ride != nullptr && !(ride->lifecycle_flags & RIDE_LIFECYCLE_QUEUE_FULL)) - { - if (peep->ShouldGoOnRide(ride, 0, false, true)) - { - *nextPotentialRide++ = i; - numPotentialRides++; - } - } - } - - // Pick the closest ride - ride_id_t closestRideIndex = RIDE_ID_NULL; - int32_t closestRideDistance = std::numeric_limits::max(); - for (int32_t i = 0; i < numPotentialRides; i++) - { - auto ride = get_ride(potentialRides[i]); - if (ride != nullptr) - { - int32_t rideX = ride->stations[0].Start.x * 32; - int32_t rideY = ride->stations[0].Start.y * 32; - int32_t distance = abs(rideX - peep->x) + abs(rideY - peep->y); - if (distance < closestRideDistance) - { - closestRideIndex = potentialRides[i]; - closestRideDistance = distance; - } - } - } - if (closestRideIndex == RIDE_ID_NULL) - return; - - // Head to that ride - peep->guest_heading_to_ride_id = closestRideIndex; - peep->peep_is_lost_countdown = 200; - peep_reset_pathfind_goal(peep); - - // Invalidate windows - rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - window_invalidate(w); - } - - peep->time_lost = 0; + peep_head_for_nearest_ride( + peep, false, [rideTypeFlags](const Ride& ride) { return ride_type_has_flag(ride.type, rideTypeFlags); }); } /** diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 6e11911143..0d1c135039 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -646,12 +646,9 @@ void scenario_fix_ghosts(rct_s6_data* s6) } } -static void ride_all_has_any_track_elements(bool* rideIndexArray) +static void ride_all_has_any_track_elements(std::array rideIndexArray) { tile_element_iterator it; - - std::fill_n(rideIndexArray, MAX_RIDES, false); - tile_element_iterator_begin(&it); while (tile_element_iterator_next(&it)) { @@ -666,7 +663,7 @@ static void ride_all_has_any_track_elements(bool* rideIndexArray) void scenario_remove_trackless_rides(rct_s6_data* s6) { - bool rideHasTrack[RCT12_MAX_RIDES_IN_PARK]; + std::array rideHasTrack{}; ride_all_has_any_track_elements(rideHasTrack); for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++) { From f49447bed5119c1a8bc0dcdd544274950b0759cc Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 17:12:34 +0100 Subject: [PATCH 6/7] Fix compile errors --- .../windows/EditorInventionsList.cpp | 2 +- src/openrct2-ui/windows/NewCampaign.cpp | 2 +- src/openrct2-ui/windows/Ride.cpp | 5 ++--- src/openrct2-ui/windows/RideList.cpp | 4 ++-- src/openrct2/management/Award.cpp | 2 +- src/openrct2/ride/Ride.cpp | 17 ++++++++++------- test/testpaint/Compat.cpp | 4 ++-- test/testpaint/TestPaint.hpp | 3 +++ 8 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index d521bc2673..43ed228cf4 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -186,7 +186,7 @@ static void research_rides_setup() } // Set research required for rides in use - for (const auto &ride : GetRideManager()) + for (const auto& ride : GetRideManager()) { Editor::SetSelectedObject(OBJECT_TYPE_RIDE, ride.subtype, OBJECT_SELECTION_FLAG_SELECTED); } diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index e43dac459b..389865c347 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -314,7 +314,7 @@ static void window_new_campaign_dropdown(rct_window* w, rct_widgetindex widgetIn if (widgetIndex != WIDX_RIDE_DROPDOWN_BUTTON) return; - if (dropdownIndex < 0 || dropdownIndex >= window_new_campaign_rides.size()) + if (dropdownIndex < 0 || (size_t)dropdownIndex >= window_new_campaign_rides.size()) return; if (w->campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 12ac5a4312..33f4ff9b98 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2296,9 +2296,8 @@ static void populate_vehicle_type_dropdown(Ride* ride) bool selectionShouldBeExpanded; int32_t rideTypeIterator, rideTypeIteratorMax; if (gCheatsShowVehiclesFromOtherTrackTypes - && !( - ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE - || ride->type == RIDE_TYPE_MINI_GOLF)) + && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE + || ride->type == RIDE_TYPE_MINI_GOLF)) { selectionShouldBeExpanded = true; rideTypeIterator = 0; diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index 3ffab68e2b..63fd250119 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -534,10 +534,10 @@ static void window_ride_list_invalidate(rct_window* w) { auto c = (RideClassification)w->page; allClosed = std::all_of(rideManager.begin(), rideManager.end(), [c](const Ride& ride) { - return ride.GetClassification() == c&& ride.status == RIDE_STATUS_OPEN; + return ride.GetClassification() == c && ride.status == RIDE_STATUS_OPEN; }); allOpen = std::all_of(rideManager.begin(), rideManager.end(), [c](const Ride& ride) { - return ride.GetClassification() == c&& ride.status != RIDE_STATUS_OPEN; + return ride.GetClassification() == c && ride.status != RIDE_STATUS_OPEN; }); } diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index f9d04a8f04..0d01d19d3a 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -401,7 +401,7 @@ static bool award_is_deserved_best_restrooms([[maybe_unused]] int32_t activeAwar { // Count open restrooms const auto& rideManager = GetRideManager(); - auto numRestrooms = std::count_if(rideManager.begin(), rideManager.end(), [](const Ride& ride) { + auto numRestrooms = (size_t)std::count_if(rideManager.begin(), rideManager.end(), [](const Ride& ride) { return ride.type == RIDE_TYPE_TOILETS && ride.status == RIDE_STATUS_OPEN; }); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9098f1f944..12cb216280 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -143,7 +143,15 @@ RideManager GetRideManager() size_t RideManager::size() const { - return ride_get_count(); + size_t count = 0; + for (size_t i = 0; i < _rides.size(); i++) + { + if (_rides[i].type != RIDE_TYPE_NULL) + { + count++; + } + } + return count; } RideManager::Iterator RideManager::begin() @@ -297,12 +305,7 @@ uint8_t* get_ride_entry_indices_for_ride_type(uint8_t rideType) int32_t ride_get_count() { - int32_t count = 0; - for ([[maybe_unused]] auto& ride : GetRideManager()) - { - count++; - } - return count; + return (int32_t)GetRideManager().size(); } int32_t Ride::GetTotalQueueLength() const diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index d6fe6632ef..35fae2e08d 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -118,9 +118,9 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei { } -Ride* get_ride(int index) +Ride* get_ride(ride_id_t index) { - if (index < 0 || index >= MAX_RIDES) + if (index >= RCT12_MAX_RIDES_IN_PARK) { log_error("invalid index %d for ride", index); return nullptr; diff --git a/test/testpaint/TestPaint.hpp b/test/testpaint/TestPaint.hpp index 34315529c8..8098769f0c 100644 --- a/test/testpaint/TestPaint.hpp +++ b/test/testpaint/TestPaint.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #define gRideEntries RCT2_ADDRESS(0x009ACFA4, rct_ride_entry*) @@ -79,4 +80,6 @@ enum Verbosity NORMAL, }; +extern Ride gRideList[RCT12_MAX_RIDES_IN_PARK]; + int generatePaintCode(uint8_t rideType); From cbc74a3c519b673f960e290c3c09ecc9a1ca0421 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 20:44:11 +0100 Subject: [PATCH 7/7] Fix GetOrAllocateRide --- src/openrct2/ride/Ride.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 12cb216280..68c2f638ab 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -184,15 +184,12 @@ ride_id_t GetNextFreeRideId() Ride* GetOrAllocateRide(ride_id_t index) { - Ride* result{}; - if (index < _rides.size()) + if (_rides.size() <= index) { - result = &_rides[index]; - } - else - { - result = &_rides.emplace_back(); + _rides.resize(index + 1); } + + auto result = &_rides[index]; result->id = index; return result; } @@ -204,6 +201,7 @@ Ride* get_ride(ride_id_t index) auto& ride = _rides[index]; if (ride.type != RIDE_TYPE_NULL) { + assert(ride.id == index); return &ride; } }