mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor guest ride consideration
This commit is contained in:
parent
a863c7ae50
commit
8022211112
|
@ -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<typename T> 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<MAX_RIDES> 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<int32_t>::max();
|
||||
for (int32_t i = 0; i < numPotentialRides; i++)
|
||||
Ride* closestRide{};
|
||||
auto closestRideDistance = std::numeric_limits<int32_t>::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<int32_t>::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); });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<bool, RCT12_MAX_RIDES_IN_PARK> 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<bool, RCT12_MAX_RIDES_IN_PARK> rideHasTrack{};
|
||||
ride_all_has_any_track_elements(rideHasTrack);
|
||||
for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue