Generalise peep entrance station selection

Remove gPeepFindAltStationNum replacing it with numEntranceStations, which is much simpler to understand.

For rides with multiple entrance stations that sync with adjacent stations, generalise cycling the station entrance selected by the peep through all of the ride's entrance stations (not limited to only stations 0 and 1) to enable this entrance cycling behaviour for rides with >= 2 entrance stations including rides with split entrance/exit stations (where the entrance stations are not stations 0 & 1).
This commit is contained in:
zaxcav 2016-08-18 15:04:31 +02:00
parent fa2e16e42a
commit e559e2ce68
1 changed files with 39 additions and 60 deletions

View File

@ -46,7 +46,7 @@ rct_xyz16 gPeepPathFindGoalPosition;
bool gPeepPathFindIgnoreForeignQueues; bool gPeepPathFindIgnoreForeignQueues;
uint8 gPeepPathFindQueueRideIndex; uint8 gPeepPathFindQueueRideIndex;
bool gPeepPathFindSingleChoiceSection; bool gPeepPathFindSingleChoiceSection;
uint32 gPeepPathFindAltStationNum; // uint32 gPeepPathFindAltStationNum;
bool _peepPathFindIsStaff; bool _peepPathFindIsStaff;
uint8 _peepPathFindQueueRideIndex; uint8 _peepPathFindQueueRideIndex;
sint8 _peepPathFindNumJunctions; sint8 _peepPathFindNumJunctions;
@ -8976,90 +8976,69 @@ static int guest_path_finding(rct_peep* peep)
gPeepPathFindQueueRideIndex = rideIndex; gPeepPathFindQueueRideIndex = rideIndex;
/* Global gPeepPathFindAltStationNum is used for storing a /* Find the ride's closest entrance station to the peep.
* ride station number that is not the nearest station to the peep. * At the same time, count how many entrance stations there are and
* In the case when the nearest ride station is not the first station, * which stations are entrance stations. */
* it will be the ride station number prior to the nearest station;
* in the case when the first station is the closest, it will be the
* next ride station number.
* For rides with a single station, its value remains unchanged from 4.
* Note that the initial value set is the game hardcoded max number of
* stations per ride = 4 */
gPeepPathFindAltStationNum = 4;
uint16 closestDist = 0xFFFF; uint16 closestDist = 0xFFFF;
uint8 closestStationNum = 4; uint8 closestStationNum;
int numEntranceStations = 0;
uint entranceStations = 0;
for (uint8 stationNum = 0; stationNum < 4; ++stationNum){ for (uint8 stationNum = 0; stationNum < 4; ++stationNum){
if (ride->entrances[stationNum] == 0xFFFF) if (ride->entrances[stationNum] == 0xFFFF) // stationNum has no entrance (so presumably an exit only station).
continue; continue;
numEntranceStations++;
entranceStations |= (1 << stationNum);
sint16 stationX = (ride->entrances[stationNum] & 0xFF) * 32; sint16 stationX = (ride->entrances[stationNum] & 0xFF) * 32;
sint16 stationY = (ride->entrances[stationNum] & 0xFF00) / 8; sint16 stationY = (ride->entrances[stationNum] & 0xFF00) / 8;
uint16 dist = abs(stationX - peep->next_x) + abs(stationY - peep->next_y); uint16 dist = abs(stationX - peep->next_x) + abs(stationY - peep->next_y);
if (dist < closestDist){ if (dist < closestDist){
closestDist = dist; closestDist = dist;
gPeepPathFindAltStationNum = closestStationNum;
closestStationNum = stationNum; closestStationNum = stationNum;
continue; continue;
} }
if (gPeepPathFindAltStationNum == 4){
gPeepPathFindAltStationNum = stationNum;
}
} }
if (closestStationNum == 4) // Ride has no stations with an entrance, so head to station 0.
if (numEntranceStations == 0)
closestStationNum = 0; closestStationNum = 0;
/* For rides with 2 stations (and those being stations 0 and 1) /* If a ride has multiple entrance stations and is set to sync with
* that are snychronised with adjacent stations, make the peep alternate * adjacent stations, cycle through the entrance stations (based on
* between going to station 0 and station 1. */ * number of rides the peep has been on) so the peep will try the
/* FUTURE: expand this beyond just 2 ride stations. * different sections of the ride.
* i.e. randomly pick between all available ride stations. * In this case, the ride's various entrance stations will typically,
* Also check whether this applies to Transport rides, since it would * though not necessarily, be adjacent to one another and consequently
* be better if this behaviour did not apply to transport rides. */ * not too far for the peep to walk when cycling between them.
if (gPeepPathFindAltStationNum != 4) { * Note: the same choice of station must made while the peep navigates
if ( * to the station. Consequently a random station selection here is not
(ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS) && * appropriate. */
ride->num_stations == 2 && if (numEntranceStations > 1 &&
ride->entrances[0] != 0xFFFF && (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)) {
ride->entrances[1] != 0xFFFF int select = peep->no_of_rides % numEntranceStations;
) { while (select > 0) {
closestStationNum = 0; closestStationNum = bitscanforward(entranceStations);
if (peep->no_of_rides & 1) entranceStations &= ~(1 << closestStationNum);
closestStationNum++; select--;
} }
closestStationNum = bitscanforward(entranceStations);
} }
/* FUTURE: this needs to be iterated to correctly loop around uint16 entranceXY;
* all four potential stations depending on which was closest. if (numEntranceStations == 0)
* As is, some unexpected behaviour or errors could result. entranceXY = ride->station_starts[closestStationNum]; // closestStationNum is always 0 here.
* Need to understand when entranceXY == 0xFFFF will occur. else
* Should only be when the ride has no stations... but can such a entranceXY = ride->entrances[closestStationNum];
* ride be open? Possibly covers the case when the ride station was
* removed after the peep chose it.
* Also, for getting the correct z value later on, closestStationNum
* should be updated.
*/
uint16 entranceXY = ride->entrances[closestStationNum];
if (entranceXY == 0xFFFF){
entranceXY = ride->entrances[closestStationNum + 1];
if (entranceXY == 0xFFFF){
entranceXY = ride->entrances[closestStationNum + 2];
}
}
if (closestDist == 0xFFFF){
entranceXY = ride->station_starts[closestStationNum];
}
x = (entranceXY & 0xFF) * 32; x = (entranceXY & 0xFF) * 32;
y = (entranceXY & 0xFF00) / 8; y = (entranceXY & 0xFF00) / 8;
z = ride->station_heights[closestStationNum]; // FUTURE: closestStationNum could be wrong (see above) z = ride->station_heights[closestStationNum];
get_ride_queue_end(&x, &y, &z, closestDist); get_ride_queue_end(&x, &y, &z);
gPeepPathFindGoalPosition = (rct_xyz16) { x, y, z }; gPeepPathFindGoalPosition = (rct_xyz16) { x, y, z };
gPeepPathFindIgnoreForeignQueues = true; gPeepPathFindIgnoreForeignQueues = true;