Merge pull request #14121 from ZehMatt/refactor/tileinspector

Refactor Tile Inspector
This commit is contained in:
Michael Steenbeek 2021-02-22 11:07:46 +01:00 committed by GitHub
commit 8e414a9d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 1038 additions and 1093 deletions

View File

@ -11,6 +11,8 @@
#include "../world/TileInspector.h"
using namespace OpenRCT2;
TileModifyAction::TileModifyAction(
CoordsXY loc, TileModifyType setting, uint32_t value1, uint32_t value2, TileElement pasteElement)
: _loc(loc)
@ -55,163 +57,163 @@ GameActions::Result::Ptr TileModifyAction::QueryExecute(bool isExecuting) const
case TileModifyType::AnyRemove:
{
const auto elementIndex = _value1;
res = tile_inspector_remove_element_at(_loc, elementIndex, isExecuting);
res = TileInspector::RemoveElementAt(_loc, elementIndex, isExecuting);
break;
}
case TileModifyType::AnySwap:
{
const auto firstIndex = _value1;
const auto secondIndex = _value2;
res = tile_inspector_swap_elements_at(_loc, firstIndex, secondIndex, isExecuting);
res = TileInspector::SwapElementsAt(_loc, firstIndex, secondIndex, isExecuting);
break;
}
case TileModifyType::AnyInsertCorrupt:
{
const auto elementIndex = _value1;
res = tile_inspector_insert_corrupt_at(_loc, elementIndex, isExecuting);
res = TileInspector::InsertCorruptElementAt(_loc, elementIndex, isExecuting);
break;
}
case TileModifyType::AnyRotate:
{
const auto elementIndex = _value1;
res = tile_inspector_rotate_element_at(_loc, elementIndex, isExecuting);
res = TileInspector::RotateElementAt(_loc, elementIndex, isExecuting);
break;
}
case TileModifyType::AnyPaste:
{
res = tile_inspector_paste_element_at(_loc, _pasteElement, isExecuting);
res = TileInspector::PasteElementAt(_loc, _pasteElement, isExecuting);
break;
}
case TileModifyType::AnySort:
{
res = tile_inspector_sort_elements_at(_loc, isExecuting);
res = TileInspector::SortElementsAt(_loc, isExecuting);
break;
}
case TileModifyType::AnyBaseHeightOffset:
{
const auto elementIndex = _value1;
const auto heightOffset = _value2;
res = tile_inspector_any_base_height_offset(_loc, elementIndex, heightOffset, isExecuting);
res = TileInspector::AnyBaseHeightOffset(_loc, elementIndex, heightOffset, isExecuting);
break;
}
case TileModifyType::SurfaceShowParkFences:
{
const bool showFences = _value1;
res = tile_inspector_surface_show_park_fences(_loc, showFences, isExecuting);
res = TileInspector::SurfaceShowParkFences(_loc, showFences, isExecuting);
break;
}
case TileModifyType::SurfaceToggleCorner:
{
const auto cornerIndex = _value1;
res = tile_inspector_surface_toggle_corner(_loc, cornerIndex, isExecuting);
res = TileInspector::SurfaceToggleCorner(_loc, cornerIndex, isExecuting);
break;
}
case TileModifyType::SurfaceToggleDiagonal:
{
res = tile_inspector_surface_toggle_diagonal(_loc, isExecuting);
res = TileInspector::SurfaceToggleDiagonal(_loc, isExecuting);
break;
}
case TileModifyType::PathSetSlope:
{
const auto elementIndex = _value1;
const bool sloped = _value2;
res = tile_inspector_path_set_sloped(_loc, elementIndex, sloped, isExecuting);
res = TileInspector::PathSetSloped(_loc, elementIndex, sloped, isExecuting);
break;
}
case TileModifyType::PathSetBroken:
{
const auto elementIndex = _value1;
const bool broken = _value2;
res = tile_inspector_path_set_broken(_loc, elementIndex, broken, isExecuting);
res = TileInspector::PathSetBroken(_loc, elementIndex, broken, isExecuting);
break;
}
case TileModifyType::PathToggleEdge:
{
const auto elementIndex = _value1;
const auto edgeIndex = _value2;
res = tile_inspector_path_toggle_edge(_loc, elementIndex, edgeIndex, isExecuting);
res = TileInspector::PathToggleEdge(_loc, elementIndex, edgeIndex, isExecuting);
break;
}
case TileModifyType::EntranceMakeUsable:
{
const auto elementIndex = _value1;
res = tile_inspector_entrance_make_usable(_loc, elementIndex, isExecuting);
res = TileInspector::EntranceMakeUsable(_loc, elementIndex, isExecuting);
break;
}
case TileModifyType::WallSetSlope:
{
const auto elementIndex = _value1;
const auto slopeValue = _value2;
res = tile_inspector_wall_set_slope(_loc, elementIndex, slopeValue, isExecuting);
res = TileInspector::WallSetSlope(_loc, elementIndex, slopeValue, isExecuting);
break;
}
case TileModifyType::WallSetAnimationFrame:
{
const auto elementIndex = _value1;
const auto animationFrameOffset = _value2;
res = tile_inspector_wall_animation_frame_offset(_loc, elementIndex, animationFrameOffset, isExecuting);
res = TileInspector::WallAnimationFrameOffset(_loc, elementIndex, animationFrameOffset, isExecuting);
break;
}
case TileModifyType::TrackBaseHeightOffset:
{
const auto elementIndex = _value1;
const auto heightOffset = _value2;
res = tile_inspector_track_base_height_offset(_loc, elementIndex, heightOffset, isExecuting);
res = TileInspector::TrackBaseHeightOffset(_loc, elementIndex, heightOffset, isExecuting);
break;
}
case TileModifyType::TrackSetChainBlock:
{
const auto elementIndex = _value1;
const bool setChain = _value2;
res = tile_inspector_track_set_chain(_loc, elementIndex, true, setChain, isExecuting);
res = TileInspector::TrackSetChain(_loc, elementIndex, true, setChain, isExecuting);
break;
}
case TileModifyType::TrackSetChain:
{
const auto elementIndex = _value1;
const bool setChain = _value2;
res = tile_inspector_track_set_chain(_loc, elementIndex, false, setChain, isExecuting);
res = TileInspector::TrackSetChain(_loc, elementIndex, false, setChain, isExecuting);
break;
}
case TileModifyType::TrackSetBlockBrake:
{
const auto elementIndex = _value1;
const bool blockBrake = _value2;
res = tile_inspector_track_set_block_brake(_loc, elementIndex, blockBrake, isExecuting);
res = TileInspector::TrackSetBlockBrake(_loc, elementIndex, blockBrake, isExecuting);
break;
}
case TileModifyType::TrackSetIndestructible:
{
const auto elementIndex = _value1;
const bool isIndestructible = _value2;
res = tile_inspector_track_set_indestructible(_loc, elementIndex, isIndestructible, isExecuting);
res = TileInspector::TrackSetIndestructible(_loc, elementIndex, isIndestructible, isExecuting);
break;
}
case TileModifyType::ScenerySetQuarterLocation:
{
const auto elementIndex = _value1;
const auto quarterIndex = _value2;
res = tile_inspector_scenery_set_quarter_location(_loc, elementIndex, quarterIndex, isExecuting);
res = TileInspector::ScenerySetQuarterLocation(_loc, elementIndex, quarterIndex, isExecuting);
break;
}
case TileModifyType::ScenerySetQuarterCollision:
{
const auto elementIndex = _value1;
const auto quarterIndex = _value2;
res = tile_inspector_scenery_set_quarter_collision(_loc, elementIndex, quarterIndex, isExecuting);
res = TileInspector::ScenerySetQuarterCollision(_loc, elementIndex, quarterIndex, isExecuting);
break;
}
case TileModifyType::BannerToggleBlockingEdge:
{
const auto elementIndex = _value1;
const auto edgeIndex = _value2;
res = tile_inspector_banner_toggle_blocking_edge(_loc, elementIndex, edgeIndex, isExecuting);
res = TileInspector::BannerToggleBlockingEdge(_loc, elementIndex, edgeIndex, isExecuting);
break;
}
case TileModifyType::CorruptClamp:
{
const auto elementIndex = _value1;
res = tile_inspector_corrupt_clamp(_loc, elementIndex, isExecuting);
res = TileInspector::CorruptClamp(_loc, elementIndex, isExecuting);
break;
}
default:

View File

@ -30,13 +30,16 @@
#include "Scenery.h"
#include "Surface.h"
using namespace OpenRCT2;
#include <algorithm>
#include <optional>
TileCoordsXY windowTileInspectorTile;
int32_t windowTileInspectorElementCount = 0;
int32_t windowTileInspectorSelectedIndex;
static bool map_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t second)
namespace OpenRCT2::TileInspector
{
static bool SwapTileElements(const CoordsXY& loc, int16_t first, int16_t second)
{
TileElement* const firstElement = map_get_nth_element_at(loc, first);
TileElement* const secondElement = map_get_nth_element_at(loc, second);
@ -58,9 +61,7 @@ static bool map_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t sec
}
// Swap their memory
TileElement temp = *firstElement;
*firstElement = *secondElement;
*secondElement = temp;
std::swap(*firstElement, *secondElement);
// Swap the 'last map element for tile' flag if either one of them was last
if ((firstElement)->IsLastForTile() || (secondElement)->IsLastForTile())
@ -72,6 +73,17 @@ static bool map_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t sec
return true;
}
static rct_window* GetTileInspectorWithPos(const CoordsXY& loc)
{
// Return the tile inspector window for everyone who has the tile selected
auto* window = window_find_by_class(WC_TILE_INSPECTOR);
if (window != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
{
return window;
}
return nullptr;
}
/**
* Inserts a corrupt element under a given element on a given tile
* @param x The x coordinate of the tile
@ -79,7 +91,7 @@ static bool map_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t sec
* @param elementIndex The nth element on this tile
* Returns 0 on success, MONEY_UNDEFINED otherwise.
*/
GameActionResultPtr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int16_t elementIndex, bool isExecuting)
GameActionResultPtr InsertCorruptElementAt(const CoordsXY& loc, int16_t elementIndex, bool isExecuting)
{
// Make sure there is enough space for the new element
if (!map_check_free_elements_and_reorganise(1))
@ -109,7 +121,7 @@ GameActionResultPtr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int16_
// this way it's placed under the selected element, even when there are multiple elements with the same base height
for (int16_t i = 0; i < elementIndex; i++)
{
if (!map_swap_elements_at(loc, i, i + 1))
if (!SwapTileElements(loc, i, i + 1))
{
// don't return error here, we've already inserted an element
// and moved it as far as we could, the only sensible thing left
@ -120,19 +132,14 @@ GameActionResultPtr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int16_
map_invalidate_tile_full(loc);
// Update the tile inspector's list for everyone who has the tile selected
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
windowTileInspectorElementCount++;
// Keep other elements (that are not being hidden) selected
if (windowTileInspectorSelectedIndex > elementIndex)
{
windowTileInspectorSelectedIndex++;
}
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
@ -143,13 +150,13 @@ GameActionResultPtr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int16_
static int32_t numLargeScenerySequences(const CoordsXY& loc, const LargeSceneryElement* const largeScenery)
{
const rct_scenery_entry* const largeEntry = largeScenery->GetEntry();
const auto* const tiles = largeEntry->large_scenery.tiles;
const auto direction = largeScenery->GetDirection();
const auto sequenceIndex = largeScenery->GetSequenceIndex();
const auto* tiles = largeEntry->large_scenery.tiles;
const auto& tile = tiles[sequenceIndex];
const auto rotatedFirstTile = CoordsXYZ{
CoordsXY{ tiles[largeScenery->GetSequenceIndex()].x_offset, tiles[largeScenery->GetSequenceIndex()].y_offset }.Rotate(
direction),
tiles[largeScenery->GetSequenceIndex()].z_offset
CoordsXY{ tile.x_offset, tile.y_offset }.Rotate(direction),
tile.z_offset,
};
const auto firstTile = CoordsXYZ{ loc, largeScenery->GetBaseZ() } - rotatedFirstTile;
@ -192,7 +199,7 @@ static int32_t numLargeScenerySequences(const CoordsXY& loc, const LargeSceneryE
* @param y The y coordinate of the tile
* @param elementIndex The nth element on this tile
*/
GameActionResultPtr tile_inspector_remove_element_at(const CoordsXY& loc, int16_t elementIndex, bool isExecuting)
GameActionResultPtr RemoveElementAt(const CoordsXY& loc, int16_t elementIndex, bool isExecuting)
{
if (isExecuting)
{
@ -221,10 +228,9 @@ GameActionResultPtr tile_inspector_remove_element_at(const CoordsXY& loc, int16_
tile_element_remove(tileElement);
map_invalidate_tile_full(loc);
// Update the window
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
// Update the window
windowTileInspectorElementCount--;
if (windowTileInspectorSelectedIndex > elementIndex)
@ -236,26 +242,24 @@ GameActionResultPtr tile_inspector_remove_element_at(const CoordsXY& loc, int16_
windowTileInspectorSelectedIndex = -1;
}
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t second, bool isExecuting)
GameActionResultPtr SwapElementsAt(const CoordsXY& loc, int16_t first, int16_t second, bool isExecuting)
{
if (isExecuting)
{
if (!map_swap_elements_at(loc, first, second))
if (!SwapTileElements(loc, first, second))
{
return std::make_unique<GameActions::Result>(GameActions::Status::Unknown, STR_NONE);
}
map_invalidate_tile_full(loc);
// Update the window
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
// If one of them was selected, update selected list item
if (windowTileInspectorSelectedIndex == first)
@ -263,14 +267,14 @@ GameActionResultPtr tile_inspector_swap_elements_at(const CoordsXY& loc, int16_t
else if (windowTileInspectorSelectedIndex == second)
windowTileInspectorSelectedIndex = first;
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_rotate_element_at(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
GameActionResultPtr RotateElementAt(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
{
if (isExecuting)
{
@ -317,7 +321,8 @@ GameActionResultPtr tile_inspector_rotate_element_at(const CoordsXY& loc, int32_
ride_set_entrance_location(ride, stationIndex, { entrance.x, entrance.y, entrance.z, newRotation });
}
else if (
entranceType == ENTRANCE_TYPE_RIDE_EXIT && exit.x == loc.x / 32 && exit.y == loc.y / 32 && exit.z == z)
entranceType == ENTRANCE_TYPE_RIDE_EXIT && exit.x == loc.x / 32 && exit.y == loc.y / 32
&& exit.z == z)
{
ride_set_exit_location(ride, stationIndex, { exit.x, exit.y, exit.z, newRotation });
}
@ -342,16 +347,16 @@ GameActionResultPtr tile_inspector_rotate_element_at(const CoordsXY& loc, int32_
map_invalidate_tile_full(loc);
if (loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
window_invalidate_by_class(WC_TILE_INSPECTOR);
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_paste_element_at(const CoordsXY& loc, TileElement element, bool isExecuting)
GameActionResultPtr PasteElementAt(const CoordsXY& loc, TileElement element, bool isExecuting)
{
// Make sure there is enough space for the new element
if (!map_check_free_elements_and_reorganise(1))
@ -381,9 +386,10 @@ GameActionResultPtr tile_inspector_paste_element_at(const CoordsXY& loc, TileEle
element.SetBannerIndex(newBannerIndex);
}
// The occupiedQuadrants will be automatically set when the element is copied over, so it's not necessary to set them
// correctly _here_.
TileElement* const pastedElement = tile_element_insert({ loc, element.GetBaseZ() }, 0b0000, TileElementType::Surface);
// The occupiedQuadrants will be automatically set when the element is copied over, so it's not necessary to set
// them correctly _here_.
TileElement* const pastedElement = tile_element_insert(
{ loc, element.GetBaseZ() }, 0b0000, TileElementType::Surface);
bool lastForTile = pastedElement->IsLastForTile();
*pastedElement = element;
@ -391,8 +397,7 @@ GameActionResultPtr tile_inspector_paste_element_at(const CoordsXY& loc, TileEle
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && tileLoc == windowTileInspectorTile)
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
windowTileInspectorElementCount++;
@ -403,14 +408,14 @@ GameActionResultPtr tile_inspector_paste_element_at(const CoordsXY& loc, TileEle
else if (windowTileInspectorSelectedIndex >= newIndex)
windowTileInspectorSelectedIndex++;
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_sort_elements_at(const CoordsXY& loc, bool isExecuting)
GameActionResultPtr SortElementsAt(const CoordsXY& loc, bool isExecuting)
{
if (isExecuting)
{
@ -440,7 +445,7 @@ GameActionResultPtr tile_inspector_sort_elements_at(const CoordsXY& loc, bool is
|| (otherElement->base_height == currentElement->base_height
&& otherElement->clearance_height > currentElement->clearance_height)))
{
if (!map_swap_elements_at(loc, currentId - 1, currentId))
if (!SwapTileElements(loc, currentId - 1, currentId))
{
// don't return error here, we've already ran some actions
// and moved things as far as we could, the only sensible
@ -456,12 +461,12 @@ GameActionResultPtr tile_inspector_sort_elements_at(const CoordsXY& loc, bool is
map_invalidate_tile_full(loc);
// Deselect tile for clients who had it selected
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
// Deselect tile for clients who had it selected
windowTileInspectorSelectedIndex = -1;
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
@ -478,7 +483,8 @@ static GameActionResultPtr ValidateTileHeight(TileElement* const tileElement, in
}
else if (newBaseHeight > MAX_ELEMENT_HEIGHT)
{
return std::make_unique<GameActions::Result>(GameActions::Status::TooHigh, STR_CANT_RAISE_ELEMENT_HERE, STR_TOO_HIGH);
return std::make_unique<GameActions::Result>(
GameActions::Status::TooHigh, STR_CANT_RAISE_ELEMENT_HERE, STR_TOO_HIGH);
}
else if (newClearanceHeight < 0)
{
@ -493,8 +499,7 @@ static GameActionResultPtr ValidateTileHeight(TileElement* const tileElement, in
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_any_base_height_offset(
const CoordsXY& loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting)
GameActionResultPtr AnyBaseHeightOffset(const CoordsXY& loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting)
{
TileElement* const tileElement = map_get_nth_element_at(loc, elementIndex);
if (tileElement == nullptr)
@ -535,17 +540,16 @@ GameActionResultPtr tile_inspector_any_base_height_offset(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_surface_show_park_fences(const CoordsXY& loc, bool showFences, bool isExecuting)
GameActionResultPtr SurfaceShowParkFences(const CoordsXY& loc, bool showFences, bool isExecuting)
{
auto* const surfaceelement = map_get_surface_element_at(loc);
@ -562,17 +566,16 @@ GameActionResultPtr tile_inspector_surface_show_park_fences(const CoordsXY& loc,
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_surface_toggle_corner(const CoordsXY& loc, int32_t cornerIndex, bool isExecuting)
GameActionResultPtr SurfaceToggleCorner(const CoordsXY& loc, int32_t cornerIndex, bool isExecuting)
{
auto* const surfaceElement = map_get_surface_element_at(loc);
@ -628,17 +631,16 @@ GameActionResultPtr tile_inspector_surface_toggle_corner(const CoordsXY& loc, in
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_surface_toggle_diagonal(const CoordsXY& loc, bool isExecuting)
GameActionResultPtr SurfaceToggleDiagonal(const CoordsXY& loc, bool isExecuting)
{
auto* const surfaceElement = map_get_surface_element_at(loc);
@ -665,17 +667,16 @@ GameActionResultPtr tile_inspector_surface_toggle_diagonal(const CoordsXY& loc,
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_path_set_sloped(const CoordsXY& loc, int32_t elementIndex, bool sloped, bool isExecuting)
GameActionResultPtr PathSetSloped(const CoordsXY& loc, int32_t elementIndex, bool sloped, bool isExecuting)
{
TileElement* const pathElement = map_get_nth_element_at(loc, elementIndex);
@ -688,17 +689,16 @@ GameActionResultPtr tile_inspector_path_set_sloped(const CoordsXY& loc, int32_t
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_path_set_broken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting)
GameActionResultPtr PathSetBroken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting)
{
TileElement* const pathElement = map_get_nth_element_at(loc, elementIndex);
@ -711,18 +711,16 @@ GameActionResultPtr tile_inspector_path_set_broken(const CoordsXY& loc, int32_t
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_path_toggle_edge(
const CoordsXY& loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting)
GameActionResultPtr PathToggleEdge(const CoordsXY& loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting)
{
TileElement* const pathElement = map_get_nth_element_at(loc, elementIndex);
@ -736,17 +734,16 @@ GameActionResultPtr tile_inspector_path_toggle_edge(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_entrance_make_usable(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
GameActionResultPtr EntranceMakeUsable(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
{
TileElement* const entranceElement = map_get_nth_element_at(loc, elementIndex);
@ -777,18 +774,16 @@ GameActionResultPtr tile_inspector_entrance_make_usable(const CoordsXY& loc, int
break;
}
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_wall_set_slope(
const CoordsXY& loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting)
GameActionResultPtr WallSetSlope(const CoordsXY& loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting)
{
TileElement* const wallElement = map_get_nth_element_at(loc, elementIndex);
@ -802,17 +797,16 @@ GameActionResultPtr tile_inspector_wall_set_slope(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_wall_animation_frame_offset(
GameActionResultPtr WallAnimationFrameOffset(
const CoordsXY& loc, int16_t elementIndex, int8_t animationFrameOffset, bool isExecuting)
{
TileElement* const wallElement = map_get_nth_element_at(loc, elementIndex);
@ -827,10 +821,9 @@ GameActionResultPtr tile_inspector_wall_animation_frame_offset(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
@ -839,8 +832,7 @@ GameActionResultPtr tile_inspector_wall_animation_frame_offset(
// Changes the height of all track elements that belong to the same track piece
// Broxzier: Copied from track_remove and stripped of unneeded code, but I think this should be smaller
GameActionResultPtr tile_inspector_track_base_height_offset(
const CoordsXY& loc, int32_t elementIndex, int8_t offset, bool isExecuting)
GameActionResultPtr TrackBaseHeightOffset(const CoordsXY& loc, int32_t elementIndex, int8_t offset, bool isExecuting)
{
if (offset == 0)
return std::make_unique<GameActions::Result>();
@ -877,68 +869,44 @@ GameActionResultPtr tile_inspector_track_base_height_offset(
trackBlock = TrackBlocks[type];
for (; trackBlock->index != 255; trackBlock++)
{
CoordsXY elem = { originX, originY };
int16_t elemZ = originZ;
CoordsXYZD elem = { originX, originY, originZ + trackBlock->z, rotation };
offsets.x = trackBlock->x;
offsets.y = trackBlock->y;
elem += offsets.Rotate(originDirection);
elemZ += trackBlock->z;
map_invalidate_tile_full(elem);
bool found = false;
TileElement* tileElement = map_get_first_element_at({ elem.x, elem.y });
do
{
TrackElement* tileElement = map_get_track_element_at_of_type_seq(elem, type, trackBlock->index);
if (tileElement == nullptr)
break;
if (tileElement->GetBaseZ() != elemZ)
continue;
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if (tileElement->GetDirection() != rotation)
continue;
if (tileElement->AsTrack()->GetSequenceIndex() != trackBlock->index)
continue;
if (tileElement->AsTrack()->GetTrackType() != type)
continue;
found = true;
break;
} while (!(tileElement++)->IsLastForTile());
if (!found)
{
log_error("Track map element part not found!");
return std::make_unique<GameActions::Result>(GameActions::Status::Unknown, STR_NONE);
}
// track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is for when
// you decrease the map size.
// track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is
// for when you decrease the map size.
openrct2_assert(map_get_surface_element_at(elem) != nullptr, "No surface at %d,%d", elem.x >> 5, elem.y >> 5);
map_invalidate_tile_full(elem);
// Keep?
// invalidate_test_results(ride);
tileElement->base_height += offset;
tileElement->clearance_height += offset;
}
}
// TODO: Only invalidate when one of the affected tiles is selected
window_invalidate_by_class(WC_TILE_INSPECTOR);
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
// Sets chainlift, optionally for an entire track block
// Broxzier: Basically a copy of the above function, with just two different lines... should probably be combined somehow
GameActionResultPtr tile_inspector_track_set_chain(
// Broxzier: Basically a copy of the above function, with just two different lines... should probably be combined
// somehow
GameActionResultPtr TrackSetChain(
const CoordsXY& loc, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting)
{
TileElement* const trackElement = map_get_nth_element_at(loc, elementIndex);
@ -984,51 +952,24 @@ GameActionResultPtr tile_inspector_track_set_chain(
trackBlock = TrackBlocks[type];
for (; trackBlock->index != 255; trackBlock++)
{
CoordsXY elem = { originX, originY };
int16_t elemZ = originZ;
CoordsXYZD elem = { originX, originY, originZ + trackBlock->z, rotation };
offsets.x = trackBlock->x;
offsets.y = trackBlock->y;
elem += offsets.Rotate(originDirection);
elemZ += trackBlock->z;
map_invalidate_tile_full(elem);
bool found = false;
TileElement* tileElement = map_get_first_element_at({ elem.x, elem.y });
do
{
TrackElement* tileElement = map_get_track_element_at_of_type_seq(elem, type, trackBlock->index);
if (tileElement == nullptr)
break;
if (tileElement->GetBaseZ() != elemZ)
continue;
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if (tileElement->GetDirection() != rotation)
continue;
if (tileElement->AsTrack()->GetSequenceIndex() != trackBlock->index)
continue;
if (tileElement->AsTrack()->GetTrackType() != type)
continue;
found = true;
break;
} while (!(tileElement++)->IsLastForTile());
if (!found)
{
log_error("Track map element part not found!");
return std::make_unique<GameActions::Result>(GameActions::Status::Unknown, STR_NONE);
}
// track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is for when
// you decrease the map size.
// track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is
// for when you decrease the map size.
openrct2_assert(map_get_surface_element_at(elem) != nullptr, "No surface at %d,%d", elem.x >> 5, elem.y >> 5);
map_invalidate_tile_full(elem);
// Keep?
// invalidate_test_results(ride);
@ -1037,16 +978,17 @@ GameActionResultPtr tile_inspector_track_set_chain(
tileElement->AsTrack()->SetHasChain(setChain);
}
}
}
// TODO: Only invalidate when one of the affected tiles is selected
window_invalidate_by_class(WC_TILE_INSPECTOR);
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_track_set_block_brake(
const CoordsXY& loc, int32_t elementIndex, bool blockBrake, bool isExecuting)
GameActionResultPtr TrackSetBlockBrake(const CoordsXY& loc, int32_t elementIndex, bool blockBrake, bool isExecuting)
{
TileElement* const trackElement = map_get_nth_element_at(loc, elementIndex);
@ -1059,17 +1001,16 @@ GameActionResultPtr tile_inspector_track_set_block_brake(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_track_set_indestructible(
GameActionResultPtr TrackSetIndestructible(
const CoordsXY& loc, int32_t elementIndex, bool isIndestructible, bool isExecuting)
{
TileElement* const trackElement = map_get_nth_element_at(loc, elementIndex);
@ -1083,17 +1024,16 @@ GameActionResultPtr tile_inspector_track_set_indestructible(
map_invalidate_tile_full(loc);
rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR);
if (tileInspectorWindow != nullptr && loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
tileInspectorWindow->Invalidate();
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_scenery_set_quarter_location(
GameActionResultPtr ScenerySetQuarterLocation(
const CoordsXY& loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting)
{
TileElement* const tileElement = map_get_nth_element_at(loc, elementIndex);
@ -1110,16 +1050,17 @@ GameActionResultPtr tile_inspector_scenery_set_quarter_location(
tileElement->SetOccupiedQuadrants(1 << ((quarterIndex + 2) & 3));
map_invalidate_tile_full(loc);
if (loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
window_invalidate_by_class(WC_TILE_INSPECTOR);
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_scenery_set_quarter_collision(
GameActionResultPtr ScenerySetQuarterCollision(
const CoordsXY& loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting)
{
TileElement* const tileElement = map_get_nth_element_at(loc, elementIndex);
@ -1134,17 +1075,17 @@ GameActionResultPtr tile_inspector_scenery_set_quarter_collision(
tileElement->SetOccupiedQuadrants(occupiedQuadrants);
map_invalidate_tile_full(loc);
if (loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
window_invalidate_by_class(WC_TILE_INSPECTOR);
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_banner_toggle_blocking_edge(
const CoordsXY& loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting)
GameActionResultPtr BannerToggleBlockingEdge(const CoordsXY& loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting)
{
TileElement* const bannerElement = map_get_nth_element_at(loc, elementIndex);
@ -1157,16 +1098,16 @@ GameActionResultPtr tile_inspector_banner_toggle_blocking_edge(
edges ^= (1 << edgeIndex);
bannerElement->AsBanner()->SetAllowedEdges(edges);
if (loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
window_invalidate_by_class(WC_TILE_INSPECTOR);
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
GameActionResultPtr tile_inspector_corrupt_clamp(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
GameActionResultPtr CorruptClamp(const CoordsXY& loc, int32_t elementIndex, bool isExecuting)
{
TileElement* const corruptElement = map_get_nth_element_at(loc, elementIndex);
@ -1181,11 +1122,13 @@ GameActionResultPtr tile_inspector_corrupt_clamp(const CoordsXY& loc, int32_t el
TileElement* const nextElement = corruptElement + 1;
corruptElement->base_height = corruptElement->clearance_height = nextElement->base_height;
if (loc == windowTileInspectorTile.ToCoordsXY())
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
window_invalidate_by_class(WC_TILE_INSPECTOR);
inspector->Invalidate();
}
}
return std::make_unique<GameActions::Result>();
}
} // namespace OpenRCT2::TileInspector

View File

@ -17,39 +17,39 @@ namespace GameActions
class Result;
}
namespace OpenRCT2::TileInspector
{
using GameActionResultPtr = std::unique_ptr<GameActions::Result>;
GameActionResultPtr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int16_t elementIndex, bool isExecuting);
GameActionResultPtr tile_inspector_remove_element_at(const CoordsXY& loc, int16_t elementIndex, bool isExecuting);
GameActionResultPtr tile_inspector_swap_elements_at(const CoordsXY& loc, int16_t first, int16_t second, bool isExecuting);
GameActionResultPtr tile_inspector_rotate_element_at(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
GameActionResultPtr tile_inspector_paste_element_at(const CoordsXY& loc, TileElement element, bool isExecuting);
GameActionResultPtr tile_inspector_sort_elements_at(const CoordsXY& loc, bool isExecuting);
GameActionResultPtr tile_inspector_any_base_height_offset(
const CoordsXY& loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting);
GameActionResultPtr tile_inspector_surface_show_park_fences(const CoordsXY& loc, bool enabled, bool isExecuting);
GameActionResultPtr tile_inspector_surface_toggle_corner(const CoordsXY& loc, int32_t cornerIndex, bool isExecuting);
GameActionResultPtr tile_inspector_surface_toggle_diagonal(const CoordsXY& loc, bool isExecuting);
GameActionResultPtr tile_inspector_path_set_sloped(const CoordsXY& loc, int32_t elementIndex, bool sloped, bool isExecuting);
GameActionResultPtr tile_inspector_path_set_broken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting);
GameActionResultPtr tile_inspector_path_toggle_edge(
const CoordsXY& loc, int32_t elementIndex, int32_t cornerIndex, bool isExecuting);
GameActionResultPtr tile_inspector_entrance_make_usable(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
GameActionResultPtr tile_inspector_wall_set_slope(
const CoordsXY& loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting);
GameActionResultPtr tile_inspector_wall_animation_frame_offset(
GameActionResultPtr InsertCorruptElementAt(const CoordsXY& loc, int16_t elementIndex, bool isExecuting);
GameActionResultPtr RemoveElementAt(const CoordsXY& loc, int16_t elementIndex, bool isExecuting);
GameActionResultPtr SwapElementsAt(const CoordsXY& loc, int16_t first, int16_t second, bool isExecuting);
GameActionResultPtr RotateElementAt(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
GameActionResultPtr PasteElementAt(const CoordsXY& loc, TileElement element, bool isExecuting);
GameActionResultPtr SortElementsAt(const CoordsXY& loc, bool isExecuting);
GameActionResultPtr AnyBaseHeightOffset(const CoordsXY& loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting);
GameActionResultPtr SurfaceShowParkFences(const CoordsXY& loc, bool enabled, bool isExecuting);
GameActionResultPtr SurfaceToggleCorner(const CoordsXY& loc, int32_t cornerIndex, bool isExecuting);
GameActionResultPtr SurfaceToggleDiagonal(const CoordsXY& loc, bool isExecuting);
GameActionResultPtr PathSetSloped(const CoordsXY& loc, int32_t elementIndex, bool sloped, bool isExecuting);
GameActionResultPtr PathSetBroken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting);
GameActionResultPtr PathToggleEdge(const CoordsXY& loc, int32_t elementIndex, int32_t cornerIndex, bool isExecuting);
GameActionResultPtr EntranceMakeUsable(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
GameActionResultPtr WallSetSlope(const CoordsXY& loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting);
GameActionResultPtr WallAnimationFrameOffset(
const CoordsXY& loc, int16_t elementIndex, int8_t animationFrameOffset, bool isExecuting);
GameActionResultPtr tile_inspector_track_base_height_offset(
const CoordsXY& loc, int32_t elementIndex, int8_t offset, bool isExecuting);
GameActionResultPtr tile_inspector_track_set_block_brake(
const CoordsXY& loc, int32_t elementIndex, bool blockBrake, bool isExecuting);
GameActionResultPtr tile_inspector_track_set_indestructible(
GameActionResultPtr TrackBaseHeightOffset(const CoordsXY& loc, int32_t elementIndex, int8_t offset, bool isExecuting);
GameActionResultPtr TrackSetBlockBrake(const CoordsXY& loc, int32_t elementIndex, bool blockBrake, bool isExecuting);
GameActionResultPtr TrackSetIndestructible(
const CoordsXY& loc, int32_t elementIndex, bool isIndestructible, bool isExecuting);
GameActionResultPtr tile_inspector_track_set_chain(
GameActionResultPtr TrackSetChain(
const CoordsXY& loc, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting);
GameActionResultPtr tile_inspector_scenery_set_quarter_location(
GameActionResultPtr ScenerySetQuarterLocation(
const CoordsXY& loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting);
GameActionResultPtr tile_inspector_scenery_set_quarter_collision(
GameActionResultPtr ScenerySetQuarterCollision(
const CoordsXY& loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting);
GameActionResultPtr tile_inspector_banner_toggle_blocking_edge(
GameActionResultPtr BannerToggleBlockingEdge(
const CoordsXY& loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting);
GameActionResultPtr tile_inspector_corrupt_clamp(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
GameActionResultPtr CorruptClamp(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);
} // namespace OpenRCT2::TileInspector