Refactor map_get_path_element_at to return PathElement and use CoordsXYZ

This commit is contained in:
duncanspumpkin 2019-08-13 19:17:15 +01:00
parent c6452095ca
commit 5b92b64ec7
10 changed files with 68 additions and 67 deletions

View File

@ -71,10 +71,9 @@ public:
GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_OFF_EDGE_OF_MAP);
}
TileElement *mapElement;
// Verify footpath exists at location, and retrieve coordinates
mapElement = map_get_path_element_at(_location.x >> 5, _location.y >> 5, _location.z / 8);
if (mapElement == nullptr)
auto pathElement = map_get_path_element_at({ _location.x >> 5, _location.y >> 5, _location.z / 8 });
if (pathElement == nullptr)
{
return std::make_unique<GameActionResult>(
GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS);

View File

@ -274,7 +274,7 @@ private:
uint32_t count = 0;
uint16_t sprite_index;
Peep* guest = nullptr;
TileElement* guest_tile = nullptr;
PathElement* guest_tile = nullptr;
// Count number of walking guests
FOR_ALL_GUESTS (sprite_index, guest)
@ -282,7 +282,7 @@ private:
if (guest->state == PEEP_STATE_WALKING)
{
// Check the walking guest's tile. Only count them if they're on a path tile.
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
guest_tile = map_get_path_element_at({ guest->next_x / 32, guest->next_y / 32, guest->next_z });
if (guest_tile != nullptr)
++count;
}
@ -296,7 +296,7 @@ private:
{
if (guest->state == PEEP_STATE_WALKING)
{
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
guest_tile = map_get_path_element_at({ guest->next_x / 32, guest->next_y / 32, guest->next_z });
if (guest_tile != nullptr)
{
if (rand == 0)

View File

@ -7,6 +7,7 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "../core/Guard.hpp"
#include "../ride/Station.h"
#include "../ride/Track.h"
#include "../scenario/Scenario.h"
@ -77,11 +78,11 @@ static TileElement* get_banner_on_path(TileElement* path_element)
return nullptr;
}
static int32_t banner_clear_path_edges(TileElement* tileElement, int32_t edges)
static int32_t banner_clear_path_edges(PathElement* pathElement, int32_t edges)
{
if (_peepPathFindIsStaff)
return edges;
TileElement* bannerElement = get_banner_on_path(tileElement);
TileElement* bannerElement = get_banner_on_path(reinterpret_cast<TileElement*>(pathElement));
if (bannerElement != nullptr)
{
do
@ -95,9 +96,9 @@ static int32_t banner_clear_path_edges(TileElement* tileElement, int32_t edges)
/**
* Gets the connected edges of a path that are permitted (i.e. no 'no entry' signs)
*/
static int32_t path_get_permitted_edges(TileElement* tileElement)
static int32_t path_get_permitted_edges(PathElement* pathElement)
{
return banner_clear_path_edges(tileElement, tileElement->AsPath()->GetEdgesAndCorners()) & 0x0F;
return banner_clear_path_edges(pathElement, pathElement->GetEdgesAndCorners()) & 0x0F;
}
/**
@ -222,13 +223,13 @@ static int32_t guest_surface_path_finding(Peep* peep)
* Returns the type of the next footpath tile a peep can get to from x,y,z /
* inputTileElement in the given direction.
*/
static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, TileElement* tileElement, uint8_t chosenDirection)
static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement* pathElement, uint8_t chosenDirection)
{
TileElement* nextTileElement;
if (tileElement->AsPath()->IsSloped())
if (pathElement->IsSloped())
{
if (tileElement->AsPath()->GetSlopeDirection() == chosenDirection)
if (pathElement->GetSlopeDirection() == chosenDirection)
{
loc.z += 2;
}
@ -275,7 +276,7 @@ static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, TileElement
* This is the recursive portion of footpath_element_destination_in_direction().
*/
static uint8_t footpath_element_dest_in_dir(
TileCoordsXYZ loc, [[maybe_unused]] TileElement* inputTileElement, uint8_t chosenDirection, ride_id_t* outRideIndex,
TileCoordsXYZ loc, uint8_t chosenDirection, ride_id_t* outRideIndex,
int32_t level)
{
TileElement* tileElement;
@ -341,7 +342,7 @@ static uint8_t footpath_element_dest_in_dir(
if (tileElement->AsPath()->IsWide())
return PATH_SEARCH_WIDE;
uint8_t edges = path_get_permitted_edges(tileElement);
uint8_t edges = path_get_permitted_edges(tileElement->AsPath());
edges &= ~(1 << direction_reverse(chosenDirection));
loc.z = tileElement->base_height;
@ -361,7 +362,7 @@ static uint8_t footpath_element_dest_in_dir(
loc.z += 2;
}
}
return footpath_element_dest_in_dir(loc, tileElement, direction, outRideIndex, level + 1);
return footpath_element_dest_in_dir(loc, direction, outRideIndex, level + 1);
}
return PATH_SEARCH_DEAD_END;
}
@ -394,17 +395,17 @@ static uint8_t footpath_element_dest_in_dir(
* width path, for example that leads from a ride exit back to the main path.
*/
static uint8_t footpath_element_destination_in_direction(
TileCoordsXYZ loc, TileElement* inputTileElement, uint8_t chosenDirection, ride_id_t* outRideIndex)
TileCoordsXYZ loc, PathElement* pathElement, uint8_t chosenDirection, ride_id_t* outRideIndex)
{
if (inputTileElement->AsPath()->IsSloped())
if (pathElement->IsSloped())
{
if (inputTileElement->AsPath()->GetSlopeDirection() == chosenDirection)
if (pathElement->GetSlopeDirection() == chosenDirection)
{
loc.z += 2;
}
}
return footpath_element_dest_in_dir(loc, inputTileElement, chosenDirection, outRideIndex, 0);
return footpath_element_dest_in_dir(loc, chosenDirection, outRideIndex, 0);
}
/**
@ -473,9 +474,9 @@ static uint8_t peep_pathfind_get_max_number_junctions(Peep* peep)
* since entrances and ride queues coming off a path should not result in
* the path being considered a junction.
*/
static bool path_is_thin_junction(TileElement* path, TileCoordsXYZ loc)
static bool path_is_thin_junction(PathElement* path, TileCoordsXYZ loc)
{
uint8_t edges = path->AsPath()->GetEdges();
uint8_t edges = path->GetEdges();
int32_t test_edge = bitscanforward(edges);
if (test_edge == -1)
@ -893,7 +894,8 @@ static void peep_pathfind_heuristic_search(
/* At this point the map element is a non-wide path.*/
/* Get all the permitted_edges of the map element. */
uint8_t edges = path_get_permitted_edges(tileElement);
Guard::Assert(tileElement->AsPath() != nullptr);
uint8_t edges = path_get_permitted_edges(tileElement->AsPath());
#if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2
if (gPathFindDebug)
@ -964,7 +966,7 @@ static void peep_pathfind_heuristic_search(
{
/* Check if this is a thin junction. And perform additional
* necessary checks. */
thin_junction = path_is_thin_junction(tileElement, loc);
thin_junction = path_is_thin_junction(tileElement->AsPath(), loc);
if (thin_junction)
{
@ -1224,10 +1226,10 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep)
* check if the combination is 'thin'!
* The junction is considered 'thin' simply if any of the
* overlaid path elements there is a 'thin junction'. */
isThin = isThin || path_is_thin_junction(dest_tile_element, loc);
isThin = isThin || path_is_thin_junction(dest_tile_element->AsPath(), loc);
// Collect the permitted edges of ALL matching path elements at this location.
permitted_edges |= path_get_permitted_edges(dest_tile_element);
permitted_edges |= path_get_permitted_edges(dest_tile_element->AsPath());
} while (!(dest_tile_element++)->IsLastForTile());
// Peep is not on a path.
if (!found)
@ -1561,7 +1563,7 @@ static uint8_t get_nearest_park_entrance_index(uint16_t x, uint16_t y)
*
* rct2: 0x006952C0
*/
static int32_t guest_path_find_entering_park(Peep* peep, [[maybe_unused]] TileElement* tile_element, uint8_t edges)
static int32_t guest_path_find_entering_park(Peep* peep, uint8_t edges)
{
// Send peeps to the nearest park entrance.
uint8_t chosenEntrance = get_nearest_park_entrance_index(peep->next_x, peep->next_y);
@ -1614,7 +1616,7 @@ static uint8_t get_nearest_peep_spawn_index(uint16_t x, uint16_t y)
*
* rct2: 0x0069536C
*/
static int32_t guest_path_find_leaving_park(Peep* peep, [[maybe_unused]] TileElement* tile_element, uint8_t edges)
static int32_t guest_path_find_leaving_park(Peep* peep, uint8_t edges)
{
// Send peeps to the nearest spawn point.
uint8_t chosenSpawn = get_nearest_peep_spawn_index(peep->next_x, peep->next_y);
@ -1649,7 +1651,7 @@ static int32_t guest_path_find_leaving_park(Peep* peep, [[maybe_unused]] TileEle
*
* rct2: 0x00695161
*/
static int32_t guest_path_find_park_entrance(Peep* peep, [[maybe_unused]] TileElement* tile_element, uint8_t edges)
static int32_t guest_path_find_park_entrance(Peep* peep, uint8_t edges)
{
// If entrance no longer exists, choose a new one
if ((peep->peep_flags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN) && peep->current_ride >= gParkEntrances.size())
@ -1870,14 +1872,14 @@ int32_t guest_path_finding(Guest* peep)
TileCoordsXYZ loc = { peep->next_x / 32, peep->next_y / 32, peep->next_z };
TileElement* tileElement = map_get_path_element_at(loc.x, loc.y, loc.z);
if (tileElement == nullptr)
auto* pathElement = map_get_path_element_at(loc);
if (pathElement == nullptr)
{
return 1;
}
_peepPathFindIsStaff = false;
uint8_t edges = path_get_permitted_edges(tileElement);
uint8_t edges = path_get_permitted_edges(pathElement);
if (edges == 0)
{
@ -1897,7 +1899,7 @@ int32_t guest_path_finding(Guest* peep)
/* If there is a wide path in that direction,
remove that edge and try another */
if (footpath_element_next_in_direction(loc, tileElement, chosenDirection) == PATH_SEARCH_WIDE)
if (footpath_element_next_in_direction(loc, pathElement, chosenDirection) == PATH_SEARCH_WIDE)
{
adjustedEdges &= ~(1 << chosenDirection);
}
@ -1954,9 +1956,9 @@ int32_t guest_path_finding(Guest* peep)
switch (peep->state)
{
case PEEP_STATE_ENTERING_PARK:
return guest_path_find_entering_park(peep, tileElement, edges);
return guest_path_find_entering_park(peep, edges);
case PEEP_STATE_LEAVING_PARK:
return guest_path_find_leaving_park(peep, tileElement, edges);
return guest_path_find_leaving_park(peep, edges);
default:
return guest_path_find_aimless(peep, edges);
}
@ -1978,7 +1980,7 @@ int32_t guest_path_finding(Guest* peep)
continue;
ride_id_t rideIndex, pathSearchResult;
pathSearchResult = footpath_element_destination_in_direction(loc, tileElement, chosenDirection, &rideIndex);
pathSearchResult = footpath_element_destination_in_direction(loc, pathElement, chosenDirection, &rideIndex);
switch (pathSearchResult)
{
case PATH_SEARCH_DEAD_END:
@ -2021,7 +2023,7 @@ int32_t guest_path_finding(Guest* peep)
}
pathfind_logging_disable();
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
return guest_path_find_park_entrance(peep, tileElement, edges);
return guest_path_find_park_entrance(peep, edges);
}
if (peep->guest_heading_to_ride_id == 0xFF)

View File

@ -763,7 +763,7 @@ void Peep::PickupAbort(int32_t old_x)
// Returns true when a peep can be dropped at the given location. When apply is set to true the peep gets dropped.
bool Peep::Place(TileCoordsXYZ location, bool apply)
{
auto* pathElement = map_get_path_element_at(location.x, location.y, location.z);
auto* pathElement = map_get_path_element_at(location);
TileElement* tileElement = reinterpret_cast<TileElement*>(pathElement);
if (!pathElement)
{

View File

@ -614,12 +614,12 @@ static bool staff_path_finding_handyman(Peep* peep)
}
else
{
TileElement* tileElement = map_get_path_element_at(peep->next_x / 32, peep->next_y / 32, peep->next_z);
auto* pathElement = map_get_path_element_at({ peep->next_x / 32, peep->next_y / 32, peep->next_z });
if (tileElement == nullptr)
if (pathElement == nullptr)
return true;
uint8_t pathDirections = (tileElement->AsPath()->GetEdges() & validDirections) & 0xF;
uint8_t pathDirections = (pathElement->GetEdges() & validDirections) & 0xF;
if (pathDirections == 0)
{
direction = staff_handyman_direction_rand_surface(peep, validDirections);
@ -782,10 +782,10 @@ static uint8_t staff_mechanic_direction_path_rand(Peep* peep, uint8_t pathDirect
*
* rct2: 0x006C0121
*/
static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections, TileElement* pathElement)
static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections, PathElement* pathElement)
{
uint8_t direction = 0xFF;
uint8_t pathDirections = pathElement->AsPath()->GetEdges();
uint8_t pathDirections = pathElement->GetEdges();
pathDirections &= validDirections;
if (pathDirections == 0)
@ -885,7 +885,7 @@ static bool staff_path_finding_mechanic(Peep* peep)
}
else
{
TileElement* pathElement = map_get_path_element_at(peep->next_x / 32, peep->next_y / 32, peep->next_z);
auto* pathElement = map_get_path_element_at({ peep->next_x / 32, peep->next_y / 32, peep->next_z });
if (pathElement == nullptr)
return true;
@ -917,10 +917,10 @@ static bool staff_path_finding_mechanic(Peep* peep)
*
* rct2: 0x006C050B
*/
static uint8_t staff_direction_path(Peep* peep, uint8_t validDirections, TileElement* pathElement)
static uint8_t staff_direction_path(Peep* peep, uint8_t validDirections, PathElement* pathElement)
{
uint8_t direction = 0xFF;
uint8_t pathDirections = pathElement->AsPath()->GetEdges();
uint8_t pathDirections = pathElement->GetEdges();
if (peep->state != PEEP_STATE_ANSWERING && peep->state != PEEP_STATE_HEADING_TO_INSPECTION)
{
pathDirections &= validDirections;
@ -973,7 +973,7 @@ static bool staff_path_finding_misc(Peep* peep)
}
else
{
TileElement* pathElement = map_get_path_element_at(peep->next_x / 32, peep->next_y / 32, peep->next_z);
auto* pathElement = map_get_path_element_at({ peep->next_x / 32, peep->next_y / 32, peep->next_z });
if (pathElement == nullptr)
return true;

View File

@ -1137,15 +1137,15 @@ static bool TrackDesignPlaceSceneryElement(
return true;
}
TileElement* tile_element = map_get_path_element_at(mapCoord.x / 32, mapCoord.y / 32, z);
auto* pathElement = map_get_path_element_at({ mapCoord.x / 32, mapCoord.y / 32, z });
if (tile_element == nullptr)
if (pathElement == nullptr)
{
return true;
}
footpath_queue_chain_reset();
footpath_remove_edges_at(mapCoord.x, mapCoord.y, tile_element);
footpath_remove_edges_at(mapCoord.x, mapCoord.y, reinterpret_cast<TileElement*>(pathElement));
flags = GAME_COMMAND_FLAG_APPLY;
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
@ -1158,7 +1158,7 @@ static bool TrackDesignPlaceSceneryElement(
| GAME_COMMAND_FLAG_GHOST;
}
footpath_connect_edges(mapCoord.x, mapCoord.y, tile_element, flags);
footpath_connect_edges(mapCoord.x, mapCoord.y, reinterpret_cast<TileElement*>(pathElement), flags);
footpath_update_queue_chains();
return true;
}

View File

@ -9917,20 +9917,20 @@ void vehicle_update_crossings(const rct_vehicle* vehicle)
while (true)
{
TileElement* tileElement = map_get_path_element_at(
xyElement.x / 32, xyElement.y / 32, xyElement.element->base_height);
auto* pathElement = map_get_path_element_at(
{ xyElement.x / 32, xyElement.y / 32, xyElement.element->base_height });
auto ride = get_ride(vehicle->ride);
// Many New Element parks have invisible rides hacked into the path.
// Limit path blocking to Miniature Railway to prevent peeps getting stuck everywhere.
if (tileElement && ride != nullptr && ride->type == RIDE_TYPE_MINIATURE_RAILWAY)
if (pathElement && ride != nullptr && ride->type == RIDE_TYPE_MINIATURE_RAILWAY)
{
if (!playedClaxon && !tileElement->AsPath()->IsBlockedByVehicle())
if (!playedClaxon && !pathElement->IsBlockedByVehicle())
{
vehicle_claxon(vehicle);
}
crossingBonus = 4;
tileElement->AsPath()->SetIsBlockedByVehicle(true);
pathElement->SetIsBlockedByVehicle(true);
}
else
{
@ -9993,11 +9993,11 @@ void vehicle_update_crossings(const rct_vehicle* vehicle)
}
}
TileElement* tileElement = map_get_path_element_at(
xyElement.x / 32, xyElement.y / 32, xyElement.element->base_height);
if (tileElement)
auto* pathElement = map_get_path_element_at(
{ xyElement.x / 32, xyElement.y / 32, xyElement.element->base_height });
if (pathElement)
{
tileElement->AsPath()->SetIsBlockedByVehicle(false);
pathElement->SetIsBlockedByVehicle(false);
}
}
}

View File

@ -1846,8 +1846,8 @@ void footpath_update_path_wide_flags(int32_t x, int32_t y)
bool footpath_is_blocked_by_vehicle(const TileCoordsXYZ& position)
{
auto pathElement = map_get_path_element_at(position.x, position.y, position.z);
return pathElement != nullptr && pathElement->AsPath()->IsBlockedByVehicle();
auto pathElement = map_get_path_element_at(position);
return pathElement != nullptr && pathElement->IsBlockedByVehicle();
}
/**

View File

@ -281,9 +281,9 @@ SurfaceElement* map_get_surface_element_at(const CoordsXY coords)
return map_get_surface_element_at(coords.x / 32, coords.y / 32);
}
TileElement* map_get_path_element_at(int32_t x, int32_t y, int32_t z)
PathElement* map_get_path_element_at(const TileCoordsXYZ loc)
{
TileElement* tileElement = map_get_first_element_at(x, y);
TileElement* tileElement = map_get_first_element_at(loc.x, loc.y);
if (tileElement == nullptr)
return nullptr;
@ -295,10 +295,10 @@ TileElement* map_get_path_element_at(int32_t x, int32_t y, int32_t z)
continue;
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
continue;
if (tileElement->base_height != z)
if (tileElement->base_height != loc.z)
continue;
return tileElement;
return tileElement->AsPath();
} while (!(tileElement++)->IsLastForTile());
return nullptr;

View File

@ -145,7 +145,7 @@ int32_t map_height_from_slope(CoordsXY coords, int32_t slope, bool isSloped);
BannerElement* map_get_banner_element_at(int32_t x, int32_t y, int32_t z, uint8_t direction);
SurfaceElement* map_get_surface_element_at(int32_t x, int32_t y);
SurfaceElement* map_get_surface_element_at(CoordsXY coords);
TileElement* map_get_path_element_at(int32_t x, int32_t y, int32_t z);
PathElement* map_get_path_element_at(const TileCoordsXYZ loc);
WallElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction);
SmallSceneryElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant);
EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost);