From 802221111211bc5088d84bdfb020fa1027aef961 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 4 Aug 2019 16:34:57 +0100 Subject: [PATCH] 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++) {