Refactor of Peep Update Action (#9793)

* Change the parameters of UpdateAction

* Use std::optional to make things a bit safer

* Use the core optional header to keep xcode happy
This commit is contained in:
Duncan 2019-08-15 18:32:19 +01:00 committed by GitHub
parent 9708e3a043
commit 3da62e4697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 237 additions and 302 deletions

View File

@ -3379,10 +3379,7 @@ void Guest::UpdateBuying()
{
if (action != PEEP_ACTION_NONE_2)
{
int16_t actionX;
int16_t actionY;
int16_t xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
return;
}
@ -3491,9 +3488,8 @@ void Guest::UpdateRideAtEntrance()
{
Invalidate();
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
int16_t xy_distance;
if (auto loc = UpdateAction(xy_distance))
{
int16_t actionZ = z;
if (xy_distance < 16)
@ -3501,7 +3497,7 @@ void Guest::UpdateRideAtEntrance()
auto entrance = ride_get_entrance_location(ride, current_ride_station);
actionZ = entrance.z * 8 + 2;
}
MoveTo(actionX, actionY, actionZ);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
}
else
@ -3685,10 +3681,11 @@ void Guest::UpdateRideAdvanceThroughEntrance()
if (ride == nullptr)
return;
int16_t actionZ, xy_distance;
auto ride_entry = ride->GetRideEntry();
int16_t actionX, actionY, actionZ, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction(xy_distance))
{
uint16_t distanceThreshold = 16;
if (ride_entry != nullptr)
@ -3716,7 +3713,7 @@ void Guest::UpdateRideAdvanceThroughEntrance()
actionZ += RideData5[ride->type].z;
}
MoveTo(actionX, actionY, actionZ);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
return;
}
@ -4059,16 +4056,14 @@ void Guest::UpdateRideFreeVehicleCheck()
void Guest::UpdateRideApproachVehicle()
{
int16_t actionX, actionY, xy_distance;
if (!UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
sub_state = PEEP_RIDE_ENTER_VEHICLE;
Invalidate();
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
Invalidate();
MoveTo(actionX, actionY, z);
Invalidate();
sub_state = PEEP_RIDE_ENTER_VEHICLE;
}
void Guest::UpdateRideEnterVehicle()
@ -4390,11 +4385,10 @@ static void peep_update_ride_prepare_for_exit(Peep* peep)
*/
void Guest::UpdateRideApproachExit()
{
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -4412,8 +4406,9 @@ void Guest::UpdateRideInExit()
if (ride == nullptr)
return;
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
int16_t xy_distance;
if (auto loc = UpdateAction(xy_distance))
{
Invalidate();
@ -4422,13 +4417,13 @@ void Guest::UpdateRideInExit()
int16_t actionZ = ride->stations[current_ride_station].Height * 8;
actionZ += RideData5[ride->type].z;
MoveTo(actionX, actionY, actionZ);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
return;
}
SwitchToSpecialSprite(0);
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
}
@ -4453,9 +4448,10 @@ void Guest::UpdateRideApproachVehicleWaypoints()
if (ride == nullptr)
return;
int16_t actionX, actionY, xy_distance;
int16_t xy_distance;
uint8_t waypoint = var_37 & 3;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction(xy_distance))
{
int16_t actionZ;
// Motion simulators have steps this moves the peeps up the steps
@ -4480,7 +4476,7 @@ void Guest::UpdateRideApproachVehicleWaypoints()
actionZ = z;
}
Invalidate();
MoveTo(actionX, actionY, actionZ);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
return;
}
@ -4497,13 +4493,14 @@ void Guest::UpdateRideApproachVehicleWaypoints()
rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[current_train]);
actionX = ride->stations[current_ride_station].Start.x * 32 + 16;
actionY = ride->stations[current_ride_station].Start.y * 32 + 16;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32 + 16;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32 + 16;
if (ride->type == RIDE_TYPE_ENTERPRISE)
{
actionX = vehicle->x;
actionY = vehicle->y;
targetLoc.x = vehicle->x;
targetLoc.y = vehicle->y;
}
rct_ride_entry* ride_entry = get_ride_entry(vehicle->ride_subtype);
@ -4514,11 +4511,11 @@ void Guest::UpdateRideApproachVehicleWaypoints()
rct_ride_entry_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type];
Guard::Assert(waypoint < 3);
actionX += vehicle_type->peep_loading_waypoints[var_37 / 4][waypoint].x;
actionY += vehicle_type->peep_loading_waypoints[var_37 / 4][waypoint].y;
targetLoc.x += vehicle_type->peep_loading_waypoints[var_37 / 4][waypoint].x;
targetLoc.y += vehicle_type->peep_loading_waypoints[var_37 / 4][waypoint].y;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
}
/**
@ -4531,8 +4528,9 @@ void Guest::UpdateRideApproachExitWaypoints()
if (ride == nullptr)
return;
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
int16_t xy_distance;
if (auto loc = UpdateAction(xy_distance))
{
int16_t actionZ;
if (ride->type == RIDE_TYPE_MOTION_SIMULATOR)
@ -4552,7 +4550,7 @@ void Guest::UpdateRideApproachExitWaypoints()
actionZ = z;
}
Invalidate();
MoveTo(actionX, actionY, actionZ);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
return;
}
@ -4567,40 +4565,34 @@ void Guest::UpdateRideApproachExitWaypoints()
var_37--;
rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[current_train]);
actionX = ride->stations[current_ride_station].Start.x * 32 + 16;
actionY = ride->stations[current_ride_station].Start.y * 32 + 16;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32 + 16;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32 + 16;
if (ride->type == RIDE_TYPE_ENTERPRISE)
{
actionX = vehicle->x;
actionY = vehicle->y;
targetLoc.x = vehicle->x;
targetLoc.y = vehicle->y;
}
rct_ride_entry* rideEntry = get_ride_entry(vehicle->ride_subtype);
rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
Guard::Assert((var_37 & 3) < 3);
actionX += vehicleEntry->peep_loading_waypoints[var_37 / 4][var_37 & 3].x;
actionY += vehicleEntry->peep_loading_waypoints[var_37 / 4][var_37 & 3].y;
targetLoc.x += vehicleEntry->peep_loading_waypoints[var_37 / 4][var_37 & 3].x;
targetLoc.y += vehicleEntry->peep_loading_waypoints[var_37 / 4][var_37 & 3].y;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
return;
}
var_37 |= 3;
auto exit = ride_get_exit_location(ride, current_ride_station);
actionX = exit.x;
actionY = exit.y;
CoordsXY targetLoc = { exit.x * 32 + 16, exit.y * 32 + 16 };
uint8_t exit_direction = direction_reverse(exit.direction);
actionX *= 32;
actionY *= 32;
actionX += 16;
actionY += 16;
int16_t x_shift = word_981D6C[exit_direction].x;
int16_t y_shift = word_981D6C[exit_direction].y;
@ -4619,11 +4611,11 @@ void Guest::UpdateRideApproachExitWaypoints()
x_shift *= shift_multiplier;
y_shift *= shift_multiplier;
actionX -= x_shift;
actionY -= y_shift;
targetLoc.x -= x_shift;
targetLoc.y -= y_shift;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
}
/**
@ -4636,11 +4628,10 @@ void Guest::UpdateRideApproachSpiralSlide()
if (ride == nullptr)
return;
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -4653,7 +4644,7 @@ void Guest::UpdateRideApproachSpiralSlide()
destination_x = 0;
destination_y = 0;
var_37 = (var_37 / 4) & 0xC;
MoveTo(LOCATION_NULL, actionY, z);
MoveTo(LOCATION_NULL, y, z);
return;
}
else if (waypoint == 2)
@ -4674,17 +4665,17 @@ void Guest::UpdateRideApproachSpiralSlide()
auto exit = ride_get_exit_location(ride, current_ride_station);
waypoint = 1;
var_37 = (exit.direction * 4) | (var_37 & 0x30) | waypoint;
actionX = ride->stations[current_ride_station].Start.x * 32;
actionY = ride->stations[current_ride_station].Start.y * 32;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32;
assert(ride->type == RIDE_TYPE_SPIRAL_SLIDE);
const CoordsXY slidePlatformDestination = SpiralSlideWalkingPath[var_37];
actionX += slidePlatformDestination.x;
actionY += slidePlatformDestination.y;
targetLoc += slidePlatformDestination;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
sub_state = PEEP_RIDE_LEAVE_SPIRAL_SLIDE;
return;
}
@ -4693,17 +4684,17 @@ void Guest::UpdateRideApproachSpiralSlide()
// Actually increment the real peep waypoint
var_37++;
actionX = ride->stations[current_ride_station].Start.x * 32;
actionY = ride->stations[current_ride_station].Start.y * 32;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32;
assert(ride->type == RIDE_TYPE_SPIRAL_SLIDE);
const CoordsXY slidePlatformDestination = SpiralSlideWalkingPath[var_37];
actionX += slidePlatformDestination.x;
actionY += slidePlatformDestination.y;
targetLoc += slidePlatformDestination;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
}
/** rct2: 0x00981F0C, 0x00981F0E */
@ -4780,29 +4771,27 @@ void Guest::UpdateRideOnSpiralSlide()
}
}
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
uint8_t waypoint = 2;
var_37 = (var_37 * 4 & 0x30) + waypoint;
actionX = ride->stations[current_ride_station].Start.x * 32;
actionY = ride->stations[current_ride_station].Start.y * 32;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32;
assert(ride->type == RIDE_TYPE_SPIRAL_SLIDE);
const CoordsXY slidePlatformDestination = SpiralSlideWalkingPath[var_37];
actionX += slidePlatformDestination.x;
actionY += slidePlatformDestination.y;
targetLoc += slidePlatformDestination;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
sub_state = PEEP_RIDE_APPROACH_SPIRAL_SLIDE;
}
@ -4814,12 +4803,10 @@ void Guest::UpdateRideLeaveSpiralSlide()
{
// Iterates through the spiral slide waypoints until it reaches
// waypoint 0. Then it readies to leave the ride by the entrance.
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -4841,17 +4828,17 @@ void Guest::UpdateRideLeaveSpiralSlide()
waypoint--;
// Actually decrement the peep waypoint
var_37--;
actionX = ride->stations[current_ride_station].Start.x * 32;
actionY = ride->stations[current_ride_station].Start.y * 32;
CoordsXY targetLoc;
targetLoc.x = ride->stations[current_ride_station].Start.x * 32;
targetLoc.y = ride->stations[current_ride_station].Start.y * 32;
assert(ride->type == RIDE_TYPE_SPIRAL_SLIDE);
const CoordsXY slidePlatformDestination = SpiralSlideWalkingPath[var_37];
actionX += slidePlatformDestination.x;
actionY += slidePlatformDestination.y;
targetLoc += slidePlatformDestination;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
return;
}
waypoint = 3;
@ -4859,24 +4846,21 @@ void Guest::UpdateRideLeaveSpiralSlide()
var_37 |= 3;
auto exit = ride_get_exit_location(ride, current_ride_station);
actionX = exit.x * 32 + 16;
actionY = exit.y * 32 + 16;
CoordsXY targetLoc{ exit.x * 32 + 16, exit.y * 32 + 16 };
exit.direction = direction_reverse(exit.direction);
int16_t xShift = word_981D6C[exit.direction].x;
int16_t yShift = word_981D6C[exit.direction].y;
int16_t xShift = word_981D6C[direction_reverse(exit.direction)].x;
int16_t yShift = word_981D6C[direction_reverse(exit.direction)].y;
int16_t shiftMultiplier = 20;
xShift *= shiftMultiplier;
yShift *= shiftMultiplier;
actionX -= xShift;
actionY -= yShift;
targetLoc.x -= xShift;
targetLoc.y -= yShift;
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
}
/** rct2: 0x00981FE4 */
@ -4901,11 +4885,10 @@ static constexpr const uint8_t _MazeCurrentDirectionToOpenHedge[][4] = {
*/
void Guest::UpdateRideMazePathfinding()
{
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -4932,12 +4915,12 @@ void Guest::UpdateRideMazePathfinding()
}
}
actionX = destination_x & 0xFFE0;
actionY = destination_y & 0xFFE0;
CoordsXY targetLoc = { destination_x & 0xFFE0, destination_y & 0xFFE0 };
int16_t stationHeight = ride->stations[0].Height;
// Find the station track element
auto trackElement = map_get_track_element_at(actionX, actionY, stationHeight);
auto trackElement = map_get_track_element_at(targetLoc.x, targetLoc.y, stationHeight);
if (trackElement == nullptr)
{
return;
@ -4981,11 +4964,11 @@ void Guest::UpdateRideMazePathfinding()
chosenEdge = (chosenEdge + 1) & 3;
}
actionX = CoordsDirectionDelta[chosenEdge].x / 2;
actionY = CoordsDirectionDelta[chosenEdge].y / 2;
targetLoc.x = CoordsDirectionDelta[chosenEdge].x / 2;
targetLoc.y = CoordsDirectionDelta[chosenEdge].y / 2;
actionX += destination_x;
actionY += destination_y;
targetLoc.x += destination_x;
targetLoc.y += destination_y;
enum class maze_type
{
@ -4995,7 +4978,7 @@ void Guest::UpdateRideMazePathfinding()
};
maze_type mazeType = maze_type::invalid;
auto tileElement = map_get_first_element_at(actionX / 32, actionY / 32);
auto tileElement = map_get_first_element_at(targetLoc.x / 32, targetLoc.y / 32);
do
{
if (stationHeight != tileElement->base_height)
@ -5022,36 +5005,36 @@ void Guest::UpdateRideMazePathfinding()
maze_last_edge &= 3;
return;
case maze_type::hedge:
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
var_37 = _MazeGetNewDirectionFromEdge[var_37 / 4][chosenEdge];
maze_last_edge = chosenEdge;
break;
case maze_type::entrance_or_exit:
actionX = destination_x;
actionY = destination_y;
targetLoc.x = destination_x;
targetLoc.y = destination_y;
if (chosenEdge & 1)
{
actionX &= 0xFFE0;
actionX += 16;
targetLoc.x &= 0xFFE0;
targetLoc.x += 16;
}
else
{
actionY &= 0xFFE0;
actionY += 16;
targetLoc.y &= 0xFFE0;
targetLoc.y += 16;
}
destination_x = actionX;
destination_y = actionY;
destination_x = targetLoc.x;
destination_y = targetLoc.y;
var_37 = 16;
maze_last_edge = chosenEdge;
break;
}
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -5063,18 +5046,16 @@ void Guest::UpdateRideMazePathfinding()
*/
void Guest::UpdateRideLeaveExit()
{
int16_t actionX, actionY, xy_distance;
auto ride = get_ride(current_ride);
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
if (ride != nullptr)
{
Invalidate();
MoveTo(actionX, actionY, ride->stations[current_ride_station].Height * 8);
MoveTo((*loc).x, (*loc).y, ride->stations[current_ride_station].Height * 8);
Invalidate();
}
return;
}
OnExitRide(current_ride);
@ -5093,18 +5074,17 @@ void Guest::UpdateRideLeaveExit()
interaction_ride_index = RIDE_ID_NULL;
SetState(PEEP_STATE_FALLING);
actionX = x & 0xFFE0;
actionY = y & 0xFFE0;
CoordsXY targetLoc = { x, y };
// Find the station track element
TileElement* tileElement = map_get_first_element_at(actionX / 32, actionY / 32);
TileElement* tileElement = map_get_first_element_at(targetLoc.x / 32, targetLoc.y / 32);
do
{
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
continue;
int16_t height = map_height_from_slope(
{ x, y }, tileElement->AsPath()->GetSlopeDirection(), tileElement->AsPath()->IsSloped());
targetLoc, tileElement->AsPath()->GetSlopeDirection(), tileElement->AsPath()->IsSloped());
height += tileElement->base_height * 8;
int16_t z_diff = z - height;
@ -5123,12 +5103,10 @@ void Guest::UpdateRideLeaveExit()
*/
void Guest::UpdateRideShopApproach()
{
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -5197,19 +5175,15 @@ void Guest::UpdateRideShopInteract()
*/
void Guest::UpdateRideShopLeave()
{
int16_t actionX, actionY, xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
actionX = x & 0xFFE0;
actionY = y & 0xFFE0;
if (actionX != next_x)
if ((x & 0xFFE0) != next_x)
return;
if (actionY != next_y)
if ((y & 0xFFE0) != next_y)
return;
}
@ -5780,13 +5754,10 @@ void Guest::UpdateEnteringPark()
}
return;
}
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -5816,13 +5787,10 @@ void Guest::UpdateLeavingPark()
return;
}
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
Invalidate();
MoveTo(actionX, actionY, z);
MoveTo((*loc).x, (*loc).y, z);
Invalidate();
return;
}
@ -5878,10 +5846,7 @@ void Guest::UpdateWatching()
if (action < PEEP_ACTION_NONE_1)
{
// 6917F6
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
if (action != PEEP_ACTION_NONE_2)
return;
@ -5969,8 +5934,7 @@ void Guest::UpdateUsingBin()
{
if (action != PEEP_ACTION_NONE_2)
{
int16_t actionX, actionY, xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
return;
}

View File

@ -564,12 +564,12 @@ void Peep::StateReset()
}
/** rct2: 0x00981D7C, 0x00981D7E */
static constexpr const LocationXY16 word_981D7C[4] = { { -2, 0 }, { 0, 2 }, { 2, 0 }, { 0, -2 } };
static constexpr const CoordsXY word_981D7C[4] = { { -2, 0 }, { 0, 2 }, { 2, 0 }, { 0, -2 } };
bool Peep::UpdateAction()
std::optional<CoordsXY> Peep::UpdateAction()
{
int16_t actionX, actionY, xy_distance;
return UpdateAction(&actionX, &actionY, &xy_distance);
int16_t xy_distance;
return UpdateAction(xy_distance);
}
/**
@ -580,7 +580,7 @@ bool Peep::UpdateAction()
* has not yet been reached. xy_distance is how close the
* peep is to the target.
*/
bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance)
std::optional<CoordsXY> Peep::UpdateAction(int16_t& xy_distance)
{
_unk_F1AEF0 = action_sprite_image_offset;
if (action == PEEP_ACTION_NONE_1)
@ -588,25 +588,24 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
action = PEEP_ACTION_NONE_2;
}
*actionX = x - destination_x;
*actionY = y - destination_y;
CoordsXY diffrenceLoc = { x - destination_x, y - destination_y };
int32_t x_delta = abs(*actionX);
int32_t y_delta = abs(*actionY);
int32_t x_delta = abs(diffrenceLoc.x);
int32_t y_delta = abs(diffrenceLoc.y);
*xy_distance = x_delta + y_delta;
xy_distance = x_delta + y_delta;
if (action == PEEP_ACTION_NONE_1 || action == PEEP_ACTION_NONE_2)
{
if (*xy_distance <= destination_tolerance)
if (xy_distance <= destination_tolerance)
{
return false;
return {};
}
int32_t nextDirection = 0;
if (x_delta < y_delta)
{
nextDirection = 8;
if (*actionY >= 0)
if (diffrenceLoc.y >= 0)
{
nextDirection = 24;
}
@ -614,14 +613,14 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
else
{
nextDirection = 16;
if (*actionX >= 0)
if (diffrenceLoc.x >= 0)
{
nextDirection = 0;
}
}
sprite_direction = nextDirection;
*actionX = x + word_981D7C[nextDirection / 8].x;
*actionY = y + word_981D7C[nextDirection / 8].y;
CoordsXY loc = { x, y };
loc += word_981D7C[nextDirection / 8];
no_action_frame_num++;
const rct_peep_animation* peepAnimation = g_peep_animation_entries[sprite_type].sprite_animation;
const uint8_t* imageOffset = peepAnimation[action_sprite_type].frame_offsets;
@ -630,7 +629,7 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
no_action_frame_num = 0;
}
action_sprite_image_offset = imageOffset[no_action_frame_num];
return true;
return loc;
}
const rct_peep_animation* peepAnimation = g_peep_animation_entries[sprite_type].sprite_animation;
@ -643,9 +642,7 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
action = PEEP_ACTION_NONE_2;
UpdateCurrentActionSpriteType();
Invalidate();
*actionX = x;
*actionY = y;
return true;
return { { x, y } };
}
action_sprite_image_offset = peepAnimation[action_sprite_type].frame_offsets[action_frame];
@ -653,9 +650,7 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
if (action != PEEP_ACTION_THROW_UP || action_frame != 15)
{
Invalidate();
*actionX = x;
*actionY = y;
return true;
return { { x, y } };
}
// We are throwing up
@ -677,9 +672,7 @@ bool Peep::UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance
audio_play_sound_at_location(soundId, x, y, z);
Invalidate();
*actionX = x;
*actionY = y;
return true;
return { { x, y } };
}
/**
@ -896,16 +889,14 @@ void Peep::UpdateFalling()
if (action == PEEP_ACTION_DROWNING)
{
// Check to see if we are ready to drown.
int16_t actionX, actionY, xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
if (action == PEEP_ACTION_DROWNING)
return;
if (gConfigNotifications.guest_died)
{
FormatNameTo(gCommonFormatArgs);
news_item_add_to_queue(NEWS_ITEM_BLANK, STR_NEWS_ITEM_GUEST_DROWNED, actionX | (actionY << 16));
news_item_add_to_queue(NEWS_ITEM_BLANK, STR_NEWS_ITEM_GUEST_DROWNED, x | (y << 16));
}
gParkRatingCasualtyPenalty = std::min(gParkRatingCasualtyPenalty + 25, 1000);
@ -2342,9 +2333,8 @@ static bool peep_update_queue_position(Peep* peep, uint8_t previous_action)
}
}
int16_t xy_dist, x, y;
if (peep->action < PEEP_ACTION_NONE_1)
peep->UpdateAction(&x, &y, &xy_dist);
peep->UpdateAction();
if (peep->action != PEEP_ACTION_NONE_2)
return true;
@ -3088,8 +3078,8 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
return;
}
int16_t actionX, actionY, xy_dist;
if (!UpdateAction(&actionX, &actionY, &xy_dist))
std::optional<CoordsXY> loc;
if (!(loc = UpdateAction()))
{
pathing_result |= PATHING_DESTINATION_REACHED;
uint8_t result = 0;
@ -3108,20 +3098,21 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
if (result != 0)
return;
if (!UpdateAction(&actionX, &actionY, &xy_dist))
if (!(loc = UpdateAction()))
return;
}
if ((actionX & 0xFFE0) == next_x && (actionY & 0xFFE0) == next_y)
auto newLoc = *loc;
if ((newLoc.x & 0xFFE0) == next_x && (newLoc.y & 0xFFE0) == next_y)
{
int16_t height = GetZOnSlope(actionX, actionY);
int16_t height = GetZOnSlope(newLoc.x, newLoc.y);
Invalidate();
MoveTo(actionX, actionY, height);
MoveTo(newLoc.x, newLoc.y, height);
Invalidate();
return;
}
if (actionX < 32 || actionY < 32 || actionX >= gMapSizeUnits || actionY >= gMapSizeUnits)
if (newLoc.x < 32 || newLoc.y < 32 || newLoc.x >= gMapSizeUnits || newLoc.y >= gMapSizeUnits)
{
if (outside_of_park == 1)
{
@ -3131,7 +3122,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
return;
}
TileElement* tileElement = map_get_first_element_at(actionX / 32, actionY / 32);
TileElement* tileElement = map_get_first_element_at(newLoc.x / 32, newLoc.y / 32);
int16_t base_z = std::max(0, (z / 8) - 2);
int16_t top_z = (z / 8) + 1;
@ -3146,13 +3137,13 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH)
{
peep_interact_with_path(this, actionX, actionY, tileElement);
peep_interact_with_path(this, newLoc.x, newLoc.y, tileElement);
tile_result = tileElement;
return;
}
else if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK)
{
if (peep_interact_with_shop(this, actionX, actionY, tileElement))
if (peep_interact_with_shop(this, newLoc.x, newLoc.y, tileElement))
{
tile_result = tileElement;
return;
@ -3160,7 +3151,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
}
else if (tileElement->GetType() == TILE_ELEMENT_TYPE_ENTRANCE)
{
peep_interact_with_entrance(this, actionX, actionY, tileElement, pathing_result);
peep_interact_with_entrance(this, newLoc.x, newLoc.y, tileElement, pathing_result);
tile_result = tileElement;
return;
}
@ -3168,7 +3159,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
if (type == PEEP_TYPE_STAFF || (GetNextIsSurface()))
{
int16_t height = abs(tile_element_height(actionX, actionY) - z);
int16_t height = abs(tile_element_height(newLoc.x, newLoc.y) - z);
if (height <= 3 || (type == PEEP_TYPE_STAFF && height <= 32))
{
@ -3179,13 +3170,13 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
SetState(PEEP_STATE_1);
}
if (!map_is_location_in_park({ actionX & 0xFFE0, actionY & 0xFFE0 }))
if (!map_is_location_in_park(newLoc))
{
peep_return_to_centre_of_tile(this);
return;
}
tileElement = map_get_surface_element_at({ actionX, actionY });
tileElement = map_get_surface_element_at(newLoc);
if (tileElement == nullptr)
{
peep_return_to_centre_of_tile(this);
@ -3210,14 +3201,14 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
}
// The peep is on a surface and not on a path
next_x = actionX & 0xFFE0;
next_y = actionY & 0xFFE0;
next_x = newLoc.x & 0xFFE0;
next_y = newLoc.y & 0xFFE0;
next_z = tileElement->base_height;
SetNextFlags(0, false, true);
height = GetZOnSlope(actionX, actionY);
height = GetZOnSlope(newLoc.x, newLoc.y);
Invalidate();
MoveTo(actionX, actionY, height);
MoveTo(newLoc.x, newLoc.y, height);
Invalidate();
return;
}

View File

@ -11,6 +11,7 @@
#define _PEEP_H_
#include "../common.h"
#include "../core/Optional.hpp"
#include "../rct12/RCT12.h"
#include "../ride/Ride.h"
#include "../ride/RideTypes.h"
@ -698,8 +699,8 @@ public: // Peep
Staff* AsStaff();
void Update();
bool UpdateAction(int16_t* actionX, int16_t* actionY, int16_t* xy_distance);
bool UpdateAction();
std::optional<CoordsXY> UpdateAction(int16_t& xy_distance);
std::optional<CoordsXY> UpdateAction();
void SetState(PeepState new_state);
void Remove();
void Invalidate();

View File

@ -1179,13 +1179,10 @@ void Staff::UpdateMowing()
Invalidate();
while (true)
{
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
int16_t checkZ = tile_element_height(actionX, actionY);
MoveTo(actionX, actionY, checkZ);
int16_t checkZ = tile_element_height((*loc).x, (*loc).y);
MoveTo((*loc).x, (*loc).y, checkZ);
Invalidate();
return;
}
@ -1250,8 +1247,7 @@ void Staff::UpdateWatering()
{
if (action != PEEP_ACTION_NONE_2)
{
int16_t actionX, actionY, xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
return;
}
@ -1317,10 +1313,7 @@ void Staff::UpdateEmptyingBin()
return;
}
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
if (action_frame != 11)
return;
@ -1384,13 +1377,10 @@ void Staff::UpdateSweeping()
staff_litter_swept++;
window_invalidate_flags |= PEEP_INVALIDATE_STAFF_STATS;
}
int16_t actionX = 0;
int16_t actionY = 0;
int16_t xy_distance;
if (UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
int16_t actionZ = GetZOnSlope(actionX, actionY);
MoveTo(actionX, actionY, actionZ);
int16_t actionZ = GetZOnSlope((*loc).x, (*loc).y);
MoveTo((*loc).x, (*loc).y, actionZ);
Invalidate();
return;
}
@ -1500,24 +1490,22 @@ void Staff::UpdateHeadingToInspect()
Invalidate();
int16_t delta_y = abs(y - destination_y);
int16_t actionX, actionY, xy_distance;
if (!UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
SetState(PEEP_STATE_INSPECTING);
sub_state = 0;
int32_t newZ = ride->stations[current_ride_station].Height * 8;
if (delta_y < 20)
{
newZ += RideData5[ride->type].z;
}
MoveTo((*loc).x, (*loc).y, newZ);
Invalidate();
return;
}
int32_t newZ = ride->stations[current_ride_station].Height * 8;
if (delta_y < 20)
{
newZ += RideData5[ride->type].z;
}
MoveTo(actionX, actionY, newZ);
Invalidate();
SetState(PEEP_STATE_INSPECTING);
sub_state = 0;
}
/**
@ -1556,8 +1544,7 @@ void Staff::UpdateAnswering()
peep_reset_pathfind_goal(this);
return;
}
int16_t actionX, actionY, xy_distance;
UpdateAction(&actionX, &actionY, &xy_distance);
UpdateAction();
return;
}
else if (sub_state <= 3)
@ -1617,24 +1604,22 @@ void Staff::UpdateAnswering()
Invalidate();
int16_t delta_y = abs(y - destination_y);
int16_t actionX, actionY, xy_distance;
if (!UpdateAction(&actionX, &actionY, &xy_distance))
if (auto loc = UpdateAction())
{
SetState(PEEP_STATE_FIXING);
sub_state = 0;
int32_t newZ = ride->stations[current_ride_station].Height * 8;
if (delta_y < 20)
{
newZ += RideData5[ride->type].z;
}
MoveTo((*loc).x, (*loc).y, newZ);
Invalidate();
return;
}
int32_t newZ = ride->stations[current_ride_station].Height * 8;
if (delta_y < 20)
{
newZ += RideData5[ride->type].z;
}
MoveTo(actionX, actionY, newZ);
Invalidate();
SetState(PEEP_STATE_FIXING);
sub_state = 0;
}
/** rct2: 0x00992A5C */
@ -2234,10 +2219,9 @@ bool Staff::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride)
}
Invalidate();
int16_t actionX, actionY, tmp_xy_distance;
if (UpdateAction(&actionX, &actionY, &tmp_xy_distance))
if (auto loc = UpdateAction())
{
sprite_move(actionX, actionY, z, (rct_sprite*)this);
sprite_move((*loc).x, (*loc).y, z, (rct_sprite*)this);
Invalidate();
return false;
}
@ -2392,16 +2376,15 @@ bool Staff::UpdateFixingMoveToStationEnd(bool firstRun, Ride* ride)
}
Invalidate();
int16_t actionX, actionY, tmp_distance;
if (!UpdateAction(&actionX, &actionY, &tmp_distance))
if (auto loc = UpdateAction())
{
return true;
sprite_move((*loc).x, (*loc).y, z, (rct_sprite*)this);
Invalidate();
return false;
}
sprite_move(actionX, actionY, z, (rct_sprite*)this);
Invalidate();
return false;
return true;
}
/**
@ -2508,16 +2491,15 @@ bool Staff::UpdateFixingMoveToStationStart(bool firstRun, Ride* ride)
}
Invalidate();
int16_t actionX, actionY, tmp_xy_distance;
if (!UpdateAction(&actionX, &actionY, &tmp_xy_distance))
if (auto loc = UpdateAction())
{
return true;
sprite_move((*loc).x, (*loc).y, z, (rct_sprite*)this);
Invalidate();
return false;
}
sprite_move(actionX, actionY, z, (rct_sprite*)this);
Invalidate();
return false;
return true;
}
/**
@ -2631,18 +2613,16 @@ bool Staff::UpdateFixingMoveToStationExit(bool firstRun, Ride* ride)
}
Invalidate();
int16_t actionX, actionY, tmp_xy_distance;
if (!UpdateAction(&actionX, &actionY, &tmp_xy_distance))
if (auto loc = UpdateAction())
{
return true;
sprite_move((*loc).x, (*loc).y, z, (rct_sprite*)this);
Invalidate();
return false;
}
else
{
sprite_move(actionX, actionY, z, (rct_sprite*)this);
Invalidate();
return true;
}
return false;
}
/**
@ -2726,23 +2706,22 @@ bool Staff::UpdateFixingLeaveByEntranceExit(bool firstRun, Ride* ride)
}
Invalidate();
int16_t actionX, actionY, xy_distance;
if (!UpdateAction(&actionX, &actionY, &xy_distance))
int16_t xy_distance;
if (auto loc = UpdateAction(xy_distance))
{
SetState(PEEP_STATE_FALLING);
uint16_t stationHeight = ride->stations[current_ride_station].Height * 8;
if (xy_distance >= 16)
{
stationHeight += RideData5[ride->type].z;
}
sprite_move((*loc).x, (*loc).y, stationHeight, (rct_sprite*)this);
Invalidate();
return false;
}
uint16_t stationHeight = ride->stations[current_ride_station].Height * 8;
if (xy_distance >= 16)
{
stationHeight += RideData5[ride->type].z;
}
sprite_move(actionX, actionY, stationHeight, (rct_sprite*)this);
Invalidate();
SetState(PEEP_STATE_FALLING);
return false;
}