diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 3a0da405de..996f430970 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1268,7 +1268,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_set_staff_name, nullptr, nullptr, - game_command_smooth_land, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index f62bf9e9d1..b944b2a875 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -44,16 +44,16 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_NAME, // GA GAME_COMMAND_RAISE_LAND, // GA GAME_COMMAND_LOWER_LAND, // GA - GAME_COMMAND_EDIT_LAND_SMOOTH, - GAME_COMMAND_RAISE_WATER, // GA - GAME_COMMAND_LOWER_WATER, // GA - GAME_COMMAND_SET_BRAKES_SPEED, // GA - GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA - GAME_COMMAND_SET_STAFF_PATROL, // GA - GAME_COMMAND_FIRE_STAFF_MEMBER, // GA - GAME_COMMAND_SET_STAFF_ORDERS, // GA - GAME_COMMAND_SET_PARK_NAME, // GA - GAME_COMMAND_SET_PARK_OPEN, // GA + GAME_COMMAND_EDIT_LAND_SMOOTH, // GA + GAME_COMMAND_RAISE_WATER, // GA + GAME_COMMAND_LOWER_WATER, // GA + GAME_COMMAND_SET_BRAKES_SPEED, // GA + GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA + GAME_COMMAND_SET_STAFF_PATROL, // GA + GAME_COMMAND_FIRE_STAFF_MEMBER, // GA + GAME_COMMAND_SET_STAFF_ORDERS, // GA + GAME_COMMAND_SET_PARK_NAME, // GA + GAME_COMMAND_SET_PARK_OPEN, // GA GAME_COMMAND_BUY_LAND_RIGHTS, GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 94c090c140..3d39d6e68c 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1080,571 +1080,6 @@ uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, in return max_height; } -static money32 smooth_land_tile( - int32_t direction, uint8_t flags, int32_t x, int32_t y, TileElement* tileElement, bool raiseLand) -{ - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); - if (raiseLand) - { - slope = tile_element_raise_styles[direction][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - else - { - slope = tile_element_lower_styles[direction][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - - auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); - landSetHeightAction.SetFlags(flags); - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - - if (res->Error == GA_ERROR::OK) - { - return res->Cost; - } - else - { - return MONEY32_UNDEFINED; - } -} - -static money32 smooth_land_row_by_edge( - int32_t flags, int32_t x, int32_t y, int32_t expectedLandHeight1, int32_t expectedLandHeight2, int32_t stepX, int32_t stepY, - int32_t direction1, int32_t direction2, int32_t checkDirection1, int32_t checkDirection2, bool raiseLand) -{ - uint8_t shouldContinue = 0xF; - int32_t landChangePerTile = raiseLand ? -2 : 2; - TileElement *tileElement, *nextTileElement; - money32 totalCost = 0; - - // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) - { - return 0; - } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (tileElement == nullptr || nextTileElement == nullptr) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection1) != expectedLandHeight1 + (raiseLand ? -2 : 2)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, checkDirection2) != expectedLandHeight2 + (raiseLand ? -2 : 2)) - { - shouldContinue &= ~0x2; - } - if (tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) - { - shouldContinue &= ~0x2; - } - while ((shouldContinue & 0x3) != 0) - { - shouldContinue = ((shouldContinue << 2) | 0x3) & shouldContinue; - x += stepX; - y += stepY; - // check if we need to continue after raising the current tile - // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) - { - shouldContinue &= ~0x3; - } - else - { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (nextTileElement == nullptr) - { - shouldContinue &= ~0x3; - } - if (tile_element_get_corner_height(tileElement, direction1) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection1)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, direction2) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection2)) - { - shouldContinue &= ~0x2; - } - if ((shouldContinue & 0x1) - && tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) - { - shouldContinue &= ~0x1; - } - if ((shouldContinue & 0x2) - && tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) - { - shouldContinue &= ~0x2; - } - } - expectedLandHeight1 += landChangePerTile; - - // change land of current tile - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); - int32_t oldSlope = slope; - if (raiseLand) - { - if (shouldContinue & 0x4) - { - slope = tile_element_raise_styles[direction1][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) - == map_get_corner_height(targetBaseZ, slope, direction2)) - { - slope = tile_element_raise_styles[direction2][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - } - else - { - if (shouldContinue & 0x4) - { - slope = tile_element_lower_styles[direction1][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) - == map_get_corner_height(targetBaseZ, slope, direction2)) - { - slope = tile_element_lower_styles[direction2][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - } - auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); - landSetHeightAction.SetFlags(flags); - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - if (res->Error == GA_ERROR::OK) - { - totalCost += res->Cost; - } - } - return totalCost; -} - -static money32 smooth_land_row_by_corner( - int32_t flags, int32_t x, int32_t y, int32_t expectedLandHeight, int32_t stepX, int32_t stepY, int32_t direction, - int32_t checkDirection, bool raiseLand) -{ - bool shouldContinue = true; - TileElement *tileElement, *nextTileElement; - money32 totalCost = 0; - money32 result; - int32_t landChangePerTile; - if (stepX == 0 || stepY == 0) - { - landChangePerTile = raiseLand ? -2 : 2; - } - else - { - landChangePerTile = raiseLand ? -4 : 4; - } - - // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) - { - return 0; - } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (tileElement == nullptr || nextTileElement == nullptr) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection) != expectedLandHeight + (raiseLand ? -2 : 2)) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) - { - return 0; - } - while (shouldContinue) - { - x += stepX; - y += stepY; - // check if we need to continue after raising the current tile - // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) - { - shouldContinue = false; - } - else - { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (nextTileElement == nullptr) - { - shouldContinue = false; - } - if (tile_element_get_corner_height(tileElement, direction) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection)) - { - shouldContinue = false; - } - if (shouldContinue - && tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) - { - shouldContinue = false; - } - } - if (stepX * stepY != 0) - { - totalCost += smooth_land_row_by_corner( - flags, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3, raiseLand); - totalCost += smooth_land_row_by_corner( - flags, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1, raiseLand); - } - expectedLandHeight += landChangePerTile; - // change land of current tile - result = smooth_land_tile(direction, flags, x, y, tileElement, raiseLand); - if (result != MONEY32_UNDEFINED) - { - totalCost += result; - } - } - return totalCost; -} - -static money32 smooth_land( - int32_t flags, int32_t centreX, int32_t centreY, int32_t mapLeft, int32_t mapTop, int32_t mapRight, int32_t mapBottom, - int32_t command) -{ - // break up information in command - const bool raiseLand = command < 0x7FFF; - const int32_t selectionType = command & 0x7FFF; - const int32_t heightOffset = raiseLand ? 2 : -2; - - // Cap bounds to map - mapLeft = std::max(mapLeft, 32); - mapTop = std::max(mapTop, 32); - mapRight = std::clamp(mapRight, 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); - mapBottom = std::clamp(mapBottom, 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); - - // Play sound (only once) - int32_t centreZ = tile_element_height(centreX, centreY); - if ((flags & GAME_COMMAND_FLAG_APPLY) && gGameCommandNestLevel == 1) - { - audio_play_sound_at_location(SOUND_PLACE_ITEM, centreX, centreY, centreZ); - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - LocationXYZ16 coord; - coord.x = centreX + 16; - coord.y = centreY + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - // Do the smoothing - money32 totalCost = 0; - switch (selectionType) - { - case MAP_SELECT_TYPE_FULL: - { - uint8_t minHeight = heightOffset + map_get_lowest_land_height(mapLeft, mapRight, mapTop, mapBottom); - uint8_t maxHeight = heightOffset + map_get_highest_land_height(mapLeft, mapRight, mapTop, mapBottom); - - // Smooth the 4 corners - { // top-left - TileElement* tileElement = map_get_surface_element_at({ mapLeft, mapTop }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - } - { // bottom-left - TileElement* tileElement = map_get_surface_element_at(mapLeft >> 5, mapBottom >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapBottom, z, -32, 32, 1, 3, raiseLand); - } - { // bottom-right - TileElement* tileElement = map_get_surface_element_at(mapRight >> 5, mapBottom >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapRight, mapBottom, z, 32, 32, 2, 0, raiseLand); - } - { // top-right - TileElement* tileElement = map_get_surface_element_at(mapRight >> 5, mapTop >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapRight, mapTop, z, 32, -32, 3, 1, raiseLand); - } - - // Smooth the edges - TileElement* tileElement = nullptr; - int32_t z1, z2; - for (int32_t y = mapTop; y <= mapBottom; y += 32) - { - tileElement = map_get_surface_element_at({ mapLeft, y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, mapLeft, y, z1, z2, -32, 0, 0, 1, 3, 2, raiseLand); - - tileElement = map_get_surface_element_at({ mapRight, y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, mapRight, y, z1, z2, 32, 0, 2, 3, 1, 0, raiseLand); - } - - for (int32_t x = mapLeft; x <= mapRight; x += 32) - { - tileElement = map_get_surface_element_at({ x, mapTop }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, x, mapTop, z1, z2, 0, -32, 0, 3, 1, 2, raiseLand); - - tileElement = map_get_surface_element_at({ x, mapBottom }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, x, mapBottom, z1, z2, 0, 32, 1, 2, 0, 3, raiseLand); - } - break; - } - case MAP_SELECT_TYPE_CORNER_0: - case MAP_SELECT_TYPE_CORNER_1: - case MAP_SELECT_TYPE_CORNER_2: - case MAP_SELECT_TYPE_CORNER_3: - { - TileElement* tileElement = map_get_surface_element_at({ mapLeft, mapTop }); - uint8_t newBaseZ = tileElement->base_height; - uint8_t newSlope = tileElement->AsSurface()->GetSlope(); - - if (raiseLand) - { - newSlope = tile_element_raise_styles[selectionType][newSlope]; - } - else - { - newSlope = tile_element_lower_styles[selectionType][newSlope]; - } - - if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - newBaseZ += heightOffset; - newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - - // Smooth the corners - int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 32, 2, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 32, 1, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, -32, 3, 1, raiseLand); - - // Smooth the edges - switch (selectionType) - { - case MAP_SELECT_TYPE_CORNER_0: - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 3, 0, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 1, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 0, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 0, 1, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_1: - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 2, 1, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 0, 1, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 1, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 1, 0, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_2: - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 1, 2, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 3, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 2, 1, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 2, 3, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_3: - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 0, 3, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 2, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 3, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 3, 2, raiseLand); - break; - } - break; - } - case MAP_SELECT_TYPE_EDGE_0: - case MAP_SELECT_TYPE_EDGE_1: - case MAP_SELECT_TYPE_EDGE_2: - case MAP_SELECT_TYPE_EDGE_3: - { - // TODO: Handle smoothing by edge - // Get the two corners to raise - TileElement* surfaceElement = map_get_surface_element_at({ mapLeft, mapTop }); - uint8_t newBaseZ = surfaceElement->base_height; - uint8_t oldSlope = surfaceElement->AsSurface()->GetSlope(); - uint8_t newSlope = oldSlope; - int32_t rowIndex = selectionType - (MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1); - - if (raiseLand) - { - newSlope = tile_element_raise_styles[rowIndex][oldSlope]; - } - else - { - newSlope = tile_element_lower_styles[rowIndex][oldSlope]; - } - - const bool changeBaseHeight = newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - if (changeBaseHeight) - { - newBaseZ += heightOffset; - newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - - const uint8_t edge = selectionType - MAP_SELECT_TYPE_EDGE_0; - - // Table with corners for each edge selection. The first two are the selected corners, the latter two are the - // opposites - static constexpr uint8_t cornerIndices[][4] = { - { 2, 3, 1, 0 }, // MAP_SELECT_TYPE_EDGE_0 - { 3, 0, 2, 1 }, // MAP_SELECT_TYPE_EDGE_1 - { 0, 1, 3, 2 }, // MAP_SELECT_TYPE_EDGE_2 - { 1, 2, 0, 3 }, // MAP_SELECT_TYPE_EDGE_3 - }; - // Big coordinate offsets for the neigbouring tile for the given edge selection - static constexpr sLocationXY8 stepOffsets[] = { - { -32, 0 }, - { 0, 32 }, - { 32, 0 }, - { 0, -32 }, - }; - - // Smooth higher and lower edges - uint8_t c1 = cornerIndices[edge][0]; - uint8_t c2 = cornerIndices[edge][1]; - uint8_t c3 = cornerIndices[edge][2]; - uint8_t c4 = cornerIndices[edge][3]; - uint8_t z1 = map_get_corner_height(newBaseZ, newSlope, c1); - uint8_t z2 = map_get_corner_height(newBaseZ, newSlope, c2); - uint8_t z3 = map_get_corner_height(newBaseZ, newSlope, c3); - uint8_t z4 = map_get_corner_height(newBaseZ, newSlope, c4); - // Smooth the edge at the top of the new slope - totalCost += smooth_land_row_by_edge( - flags, mapLeft, mapTop, z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, c3, c4, c1, c2, raiseLand); - // Smooth the edge at the bottom of the new slope - totalCost += smooth_land_row_by_edge( - flags, mapLeft, mapTop, z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, c1, c2, c3, c4, raiseLand); - - // Smooth corners - totalCost += smooth_land_row_by_corner( - flags, mapLeft, mapTop, z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, c1, raiseLand); - totalCost += smooth_land_row_by_corner( - flags, mapLeft, mapTop, z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, c2, raiseLand); - int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 32, 2, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 32, 1, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, -32, 3, 1, raiseLand); - break; - } - } // switch selectionType - - // Raise / lower the land tool selection area - GameActionResult::Ptr res; - if (raiseLand) - { - auto raiseLandAction = LandRaiseAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); - raiseLandAction.SetFlags(flags); - res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&raiseLandAction) - : GameActions::QueryNested(&raiseLandAction); - } - else - { - auto lowerLandAction = LandLowerAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); - lowerLandAction.SetFlags(flags); - res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&lowerLandAction) - : GameActions::QueryNested(&lowerLandAction); - } - if (res->Error != GA_ERROR::OK) - { - return MONEY32_UNDEFINED; - } - - totalCost += res->Cost; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = centreX; - gCommandPosition.y = centreY; - gCommandPosition.z = centreZ; - return totalCost; -} - -/** - * - * rct2: 0x0068BC01 - */ -void game_command_smooth_land( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t flags = *ebx & 0xFF; - int32_t centreX = *eax & 0xFFFF; - int32_t centreY = *ecx & 0xFFFF; - int32_t mapLeft = (int16_t)(*edx & 0xFFFF); - int32_t mapTop = (int16_t)(*ebp & 0xFFFF); - int32_t mapRight = (int16_t)(*edx >> 16); - int32_t mapBottom = (int16_t)(*ebp >> 16); - int32_t command = *edi; - *ebx = smooth_land(flags, centreX, centreY, mapLeft, mapTop, mapRight, mapBottom, command); -} - bool map_is_location_at_edge(int32_t x, int32_t y) { return x < 32 || y < 32 || x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32) || y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 7c7a395a05..64660ef626 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -202,7 +202,6 @@ void game_command_set_large_scenery_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_smooth_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_wall(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);