1
0
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:
duncanspumpkin
2019-08-13 20:51:37 +01:00
parent f3db7f877a
commit fb8c42f3c2
19 changed files with 46 additions and 53 deletions

View File

@@ -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.");

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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++;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;