mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-26 16:24:35 +01:00
Fix #9557. Refactor map_is_location_at_edge and tile_element_insert
This commit is contained in:
@@ -643,7 +643,7 @@ void game_fix_save_vars()
|
||||
if (surfaceElement == nullptr)
|
||||
{
|
||||
log_error("Null map element at x = %d and y = %d. Fixing...", x, y);
|
||||
auto tileElement = tile_element_insert(x, y, 14, 0);
|
||||
auto tileElement = tile_element_insert({ x, y, 14 }, 0);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
log_error("Unable to fix: Map element limit reached.");
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE);
|
||||
}
|
||||
|
||||
TileElement* newTileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, baseHeight, 0);
|
||||
TileElement* newTileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0);
|
||||
assert(newTileElement != nullptr);
|
||||
|
||||
banner->flags = 0;
|
||||
|
||||
@@ -332,7 +332,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, zLow, 0b1111);
|
||||
auto tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, zLow }, 0b1111);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_PATH);
|
||||
PathElement* pathElement = tileElement->AsPath();
|
||||
|
||||
@@ -246,7 +246,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, zLow, 0b1111);
|
||||
auto tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, zLow }, 0b1111);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_PATH);
|
||||
PathElement* pathElement = tileElement->AsPath();
|
||||
|
||||
@@ -91,8 +91,7 @@ private:
|
||||
audio_play_sound_at_location(SoundId::PlaceItem, _coords.x, _coords.y, tile_element_height(_coords));
|
||||
}
|
||||
|
||||
uint8_t maxHeight = map_get_highest_land_height(
|
||||
validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom());
|
||||
uint8_t maxHeight = map_get_highest_land_height(validRange);
|
||||
|
||||
for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ private:
|
||||
}
|
||||
|
||||
uint8_t minHeight = map_get_lowest_land_height(
|
||||
validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom());
|
||||
validRange);
|
||||
|
||||
for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32)
|
||||
{
|
||||
|
||||
@@ -362,14 +362,8 @@ private:
|
||||
{
|
||||
case MAP_SELECT_TYPE_FULL:
|
||||
{
|
||||
uint8_t minHeight = heightOffset
|
||||
+ map_get_lowest_land_height(
|
||||
validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(),
|
||||
validRange.GetBottom());
|
||||
uint8_t maxHeight = heightOffset
|
||||
+ map_get_highest_land_height(
|
||||
validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(),
|
||||
validRange.GetBottom());
|
||||
uint8_t minHeight = heightOffset + map_get_lowest_land_height(validRange);
|
||||
uint8_t maxHeight = heightOffset + map_get_highest_land_height(validRange);
|
||||
|
||||
// Smooth the 4 corners
|
||||
{ // top-left
|
||||
|
||||
@@ -317,7 +317,7 @@ public:
|
||||
}
|
||||
|
||||
TileElement* newTileElement = tile_element_insert(
|
||||
curTile.x / 32, curTile.y / 32, zLow, quarterTile.GetBaseQuarterOccupied());
|
||||
{ curTile.x / 32, curTile.y / 32, zLow }, quarterTile.GetBaseQuarterOccupied());
|
||||
Guard::Assert(newTileElement != nullptr);
|
||||
map_animation_create(MAP_ANIMATION_TYPE_LARGE_SCENERY, curTile.x, curTile.y, zLow);
|
||||
newTileElement->SetType(TILE_ELEMENT_TYPE_LARGE_SCENERY);
|
||||
|
||||
@@ -216,7 +216,7 @@ public:
|
||||
uint16_t flooredX = floor2(_loc.x, 32);
|
||||
uint16_t flooredY = floor2(_loc.y, 32);
|
||||
|
||||
tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, baseHeight, 0xF);
|
||||
tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, baseHeight }, 0xF);
|
||||
assert(tileElement != nullptr);
|
||||
|
||||
tileElement->clearance_height = clearanceHeight;
|
||||
|
||||
@@ -146,7 +146,7 @@ public:
|
||||
surfaceElement->SetOwnership(OWNERSHIP_UNOWNED);
|
||||
}
|
||||
|
||||
TileElement* newElement = tile_element_insert(entranceLoc.x / 32, entranceLoc.y / 32, zLow, 0xF);
|
||||
TileElement* newElement = tile_element_insert({ entranceLoc.x / 32, entranceLoc.y / 32, zLow }, 0xF);
|
||||
Guard::Assert(newElement != nullptr);
|
||||
newElement->SetType(TILE_ELEMENT_TYPE_ENTRANCE);
|
||||
auto entranceElement = newElement->AsEntrance();
|
||||
|
||||
@@ -192,7 +192,7 @@ public:
|
||||
res->Position.z = tile_element_height({ _loc.x, _loc.y });
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
|
||||
TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, z / 8, 0b1111);
|
||||
TileElement* tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, z / 8 }, 0b1111);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_ENTRANCE);
|
||||
tileElement->SetDirection(_direction);
|
||||
|
||||
@@ -430,7 +430,7 @@ public:
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
|
||||
res->Cost = (sceneryEntry->small_scenery.price * 10) + clearCost;
|
||||
|
||||
TileElement* newElement = tile_element_insert(_loc.x / 32, _loc.y / 32, zLow, quarterTile.GetBaseQuarterOccupied());
|
||||
TileElement* newElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, zLow }, quarterTile.GetBaseQuarterOccupied());
|
||||
assert(newElement != nullptr);
|
||||
res->tileElement = newElement;
|
||||
newElement->SetType(TILE_ELEMENT_TYPE_SMALL_SCENERY);
|
||||
|
||||
@@ -579,7 +579,8 @@ public:
|
||||
ride->overall_view.y = mapLoc.y / 32;
|
||||
}
|
||||
|
||||
auto tileElement = tile_element_insert(mapLoc.x / 32, mapLoc.y / 32, baseZ, quarterTile.GetBaseQuarterOccupied());
|
||||
auto tileElement = tile_element_insert(
|
||||
{ mapLoc.x / 32, mapLoc.y / 32, baseZ }, quarterTile.GetBaseQuarterOccupied());
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->clearance_height = clearanceZ;
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_TRACK);
|
||||
|
||||
@@ -394,7 +394,7 @@ public:
|
||||
return std::make_unique<WallPlaceActionResult>(GA_ERROR::NO_FREE_ELEMENTS, gGameCommandErrorText);
|
||||
}
|
||||
|
||||
TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, targetHeight / 8, 0);
|
||||
TileElement* tileElement = tile_element_insert({ _loc.x / 32, _loc.y / 32, targetHeight / 8 }, 0);
|
||||
assert(tileElement != nullptr);
|
||||
|
||||
map_animation_create(MAP_ANIMATION_TYPE_WALL, _loc.x, _loc.y, targetHeight / 8);
|
||||
@@ -613,7 +613,7 @@ private:
|
||||
|
||||
*wallAcrossTrack = false;
|
||||
gMapGroundFlags = ELEMENT_IS_ABOVE_GROUND;
|
||||
if (map_is_location_at_edge(_loc.x, _loc.y))
|
||||
if (map_is_location_at_edge({ _loc.x, _loc.y }))
|
||||
{
|
||||
gGameCommandErrorText = STR_OFF_EDGE_OF_MAP;
|
||||
return false;
|
||||
|
||||
@@ -2184,7 +2184,7 @@ static money32 place_maze_design(uint8_t flags, Ride* ride, uint16_t mazeEntry,
|
||||
int32_t fx = floor2(x, 32);
|
||||
int32_t fy = floor2(y, 32);
|
||||
int32_t fz = z >> 3;
|
||||
TileElement* tileElement = tile_element_insert(fx >> 5, fy >> 5, fz, 15);
|
||||
TileElement* tileElement = tile_element_insert({ fx >> 5, fy >> 5, fz }, 15);
|
||||
tileElement->clearance_height = fz + 4;
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_TRACK);
|
||||
tileElement->AsTrack()->SetTrackType(TRACK_ELEM_MAZE);
|
||||
|
||||
@@ -914,17 +914,16 @@ int32_t tile_element_get_corner_height(const SurfaceElement* surfaceElement, int
|
||||
return map_get_corner_height(z, slope, direction);
|
||||
}
|
||||
|
||||
uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax)
|
||||
uint8_t map_get_lowest_land_height(const MapRange range)
|
||||
{
|
||||
xMin = std::max(xMin, 32);
|
||||
yMin = std::max(yMin, 32);
|
||||
xMax = std::min(xMax, (int32_t)gMapSizeMaxXY);
|
||||
yMax = std::min(yMax, (int32_t)gMapSizeMaxXY);
|
||||
MapRange validRange = { std::max(range.GetLeft(), 32), std::max(range.GetTop(), 32),
|
||||
std::min(range.GetRight(), (int32_t)gMapSizeMaxXY),
|
||||
std::min(range.GetBottom(), (int32_t)gMapSizeMaxXY) };
|
||||
|
||||
uint8_t min_height = 0xFF;
|
||||
for (int32_t yi = yMin; yi <= yMax; yi += 32)
|
||||
for (int32_t yi = validRange.GetTop(); yi <= validRange.GetBottom(); yi += 32)
|
||||
{
|
||||
for (int32_t xi = xMin; xi <= xMax; xi += 32)
|
||||
for (int32_t xi = validRange.GetLeft(); xi <= validRange.GetRight(); xi += 32)
|
||||
{
|
||||
auto* surfaceElement = map_get_surface_element_at({ xi, yi });
|
||||
if (surfaceElement != nullptr && min_height > surfaceElement->base_height)
|
||||
@@ -936,17 +935,16 @@ uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int
|
||||
return min_height;
|
||||
}
|
||||
|
||||
uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax)
|
||||
uint8_t map_get_highest_land_height(const MapRange range)
|
||||
{
|
||||
xMin = std::max(xMin, 32);
|
||||
yMin = std::max(yMin, 32);
|
||||
xMax = std::min(xMax, (int32_t)gMapSizeMaxXY);
|
||||
yMax = std::min(yMax, (int32_t)gMapSizeMaxXY);
|
||||
MapRange validRange = { std::max(range.GetLeft(), 32), std::max(range.GetTop(), 32),
|
||||
std::min(range.GetRight(), (int32_t)gMapSizeMaxXY),
|
||||
std::min(range.GetBottom(), (int32_t)gMapSizeMaxXY) };
|
||||
|
||||
uint8_t max_height = 0;
|
||||
for (int32_t yi = yMin; yi <= yMax; yi += 32)
|
||||
for (int32_t yi = validRange.GetTop(); yi <= validRange.GetBottom(); yi += 32)
|
||||
{
|
||||
for (int32_t xi = xMin; xi <= xMax; xi += 32)
|
||||
for (int32_t xi = validRange.GetLeft(); xi <= validRange.GetRight(); xi += 32)
|
||||
{
|
||||
auto* surfaceElement = map_get_surface_element_at({ xi, yi });
|
||||
if (surfaceElement != nullptr)
|
||||
@@ -964,9 +962,10 @@ uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, in
|
||||
return max_height;
|
||||
}
|
||||
|
||||
bool map_is_location_at_edge(int32_t x, int32_t y)
|
||||
bool map_is_location_at_edge(const CoordsXY loc)
|
||||
{
|
||||
return x < 32 || y < 32 || x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32) || y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32);
|
||||
return loc.x < 32 || loc.y < 32 || loc.x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32)
|
||||
|| loc.y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1203,7 +1202,7 @@ bool map_check_free_elements_and_reorganise(int32_t numElements)
|
||||
*
|
||||
* rct2: 0x0068B1F6
|
||||
*/
|
||||
TileElement* tile_element_insert(int32_t x, int32_t y, int32_t z, int32_t flags)
|
||||
TileElement* tile_element_insert(const TileCoordsXYZ loc, int32_t flags)
|
||||
{
|
||||
TileElement *originalTileElement, *newTileElement, *insertedElement;
|
||||
|
||||
@@ -1214,13 +1213,13 @@ TileElement* tile_element_insert(int32_t x, int32_t y, int32_t z, int32_t flags)
|
||||
}
|
||||
|
||||
newTileElement = gNextFreeTileElement;
|
||||
originalTileElement = gTileElementTilePointers[y * MAXIMUM_MAP_SIZE_TECHNICAL + x];
|
||||
originalTileElement = gTileElementTilePointers[loc.y * MAXIMUM_MAP_SIZE_TECHNICAL + loc.x];
|
||||
|
||||
// Set tile index pointer to point to new element block
|
||||
gTileElementTilePointers[y * MAXIMUM_MAP_SIZE_TECHNICAL + x] = newTileElement;
|
||||
gTileElementTilePointers[loc.y * MAXIMUM_MAP_SIZE_TECHNICAL + loc.x] = newTileElement;
|
||||
|
||||
// Copy all elements that are below the insert height
|
||||
while (z >= originalTileElement->base_height)
|
||||
while (loc.z >= originalTileElement->base_height)
|
||||
{
|
||||
// Copy over map element
|
||||
*newTileElement = *originalTileElement;
|
||||
@@ -1240,9 +1239,9 @@ TileElement* tile_element_insert(int32_t x, int32_t y, int32_t z, int32_t flags)
|
||||
// Insert new map element
|
||||
insertedElement = newTileElement;
|
||||
newTileElement->type = 0;
|
||||
newTileElement->base_height = z;
|
||||
newTileElement->base_height = loc.z;
|
||||
newTileElement->flags = flags;
|
||||
newTileElement->clearance_height = z;
|
||||
newTileElement->clearance_height = loc.z;
|
||||
std::memset(&newTileElement->pad_04, 0, sizeof(newTileElement->pad_04));
|
||||
newTileElement++;
|
||||
|
||||
|
||||
@@ -153,8 +153,8 @@ EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t
|
||||
EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, bool ghost);
|
||||
int16_t tile_element_height(const CoordsXY loc);
|
||||
int16_t tile_element_water_height(const CoordsXY loc);
|
||||
uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax);
|
||||
uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax);
|
||||
uint8_t map_get_highest_land_height(const MapRange range);
|
||||
uint8_t map_get_lowest_land_height(const MapRange range);
|
||||
bool map_coord_is_connected(const TileCoordsXYZ loc, uint8_t faceDirection);
|
||||
void map_remove_provisional_elements();
|
||||
void map_restore_provisional_elements();
|
||||
@@ -174,7 +174,7 @@ void map_get_bounding_box(
|
||||
void map_invalidate_selection_rect();
|
||||
void map_reorganise_elements();
|
||||
bool map_check_free_elements_and_reorganise(int32_t num_elements);
|
||||
TileElement* tile_element_insert(int32_t x, int32_t y, int32_t z, int32_t flags);
|
||||
TileElement* tile_element_insert(const TileCoordsXYZ loc, int32_t flags);
|
||||
|
||||
using CLEAR_FUNC = int32_t (*)(TileElement** tile_element, int32_t x, int32_t y, uint8_t flags, money32* price);
|
||||
|
||||
@@ -248,7 +248,7 @@ TileElement* map_get_track_element_at_from_ride(int32_t x, int32_t y, int32_t z,
|
||||
TileElement* map_get_track_element_at_with_direction_from_ride(
|
||||
int32_t x, int32_t y, int32_t z, int32_t direction, ride_id_t rideIndex);
|
||||
|
||||
bool map_is_location_at_edge(int32_t x, int32_t y);
|
||||
bool map_is_location_at_edge(const CoordsXY loc);
|
||||
void map_obstruction_set_error_text(TileElement* tileElement);
|
||||
|
||||
uint16_t check_max_allowable_land_rights_for_tile(uint8_t x, uint8_t y, uint8_t base_z);
|
||||
|
||||
@@ -237,7 +237,7 @@ static void mapgen_place_tree(int32_t type, int32_t x, int32_t y)
|
||||
}
|
||||
|
||||
surfaceZ = tile_element_height({ x * 32 + 16, y * 32 + 16 }) / 8;
|
||||
tileElement = tile_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8));
|
||||
tileElement = tile_element_insert({ x, y, surfaceZ }, (1 | 2 | 4 | 8));
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_SMALL_SCENERY);
|
||||
|
||||
@@ -89,7 +89,7 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(CoordsXY loc, int16_t ele
|
||||
{
|
||||
// Create new corrupt element
|
||||
TileElement* corruptElement = tile_element_insert(
|
||||
loc.x / 32, loc.y / 32, -1, 0); // Ugly hack: -1 guarantees this to be placed first
|
||||
{ loc.x / 32, loc.y / 32, -1 }, 0); // Ugly hack: -1 guarantees this to be placed first
|
||||
if (corruptElement == nullptr)
|
||||
{
|
||||
log_warning("Failed to insert corrupt element.");
|
||||
@@ -320,7 +320,7 @@ GameActionResult::Ptr tile_inspector_paste_element_at(CoordsXY loc, TileElement
|
||||
tile_element_set_banner_index(&element, newBannerIndex);
|
||||
}
|
||||
|
||||
TileElement* const pastedElement = tile_element_insert(loc.x / 32, loc.y / 32, element.base_height, 0);
|
||||
TileElement* const pastedElement = tile_element_insert({ loc.x / 32, loc.y / 32, element.base_height }, 0);
|
||||
|
||||
bool lastForTile = pastedElement->IsLastForTile();
|
||||
*pastedElement = element;
|
||||
|
||||
Reference in New Issue
Block a user