From 3162d4dc7510bc2a9d92b4b8e54e3e656d449ff4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 15 May 2019 21:15:23 +0100 Subject: [PATCH 1/4] Implement TileModifyAction Further work moving game commands into the game action framework --- src/openrct2-ui/windows/TileInspector.cpp | 156 ++++++----- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 4 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/TileModifyAction.hpp | 264 ++++++++++++++++++ src/openrct2/core/DataSerialiserTraits.h | 33 +++ src/openrct2/world/Map.cpp | 180 ------------ src/openrct2/world/Map.h | 2 - src/openrct2/world/TileInspector.cpp | 215 +++++++------- src/openrct2/world/TileInspector.h | 90 +++--- 10 files changed, 524 insertions(+), 424 deletions(-) create mode 100644 src/openrct2/actions/TileModifyAction.hpp diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 69b79b6755..07ef450ee8 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include // clang-format off static constexpr const rct_string_id TerrainTypeStringIds[] = { @@ -619,25 +619,25 @@ static void window_tile_inspector_load_tile(rct_window* w, TileElement* elementT static void window_tile_inspector_insert_corrupt_element(int32_t elementIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); - game_do_command( - TILE_INSPECTOR_ANY_INSERT_CORRUPT, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyInsertCorrupt, elementIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_remove_element(int32_t elementIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); - game_do_command( - TILE_INSPECTOR_ANY_REMOVE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyRemove, elementIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_rotate_element(int32_t elementIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); - game_do_command( - TILE_INSPECTOR_ANY_ROTATE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyRotate, elementIndex); + GameActions::Execute(&modifyTile); } // Swap element with its parent @@ -645,17 +645,16 @@ static void window_tile_inspector_swap_elements(int16_t first, int16_t second) { openrct2_assert(first >= 0 && first < windowTileInspectorElementCount, "first out of range"); openrct2_assert(second >= 0 && second < windowTileInspectorElementCount, "second out of range"); - game_do_command( - TILE_INSPECTOR_ANY_SWAP, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), first, - GAME_COMMAND_MODIFY_TILE, second, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnySwap, first, second); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_sort_elements() { openrct2_assert(windowTileInspectorTileSelected, "No tile selected"); - game_do_command( - TILE_INSPECTOR_ANY_SORT, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), 0, - GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction({ windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnySort); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_copy_element(rct_window* w) @@ -672,127 +671,130 @@ static void window_tile_inspector_paste_element(rct_window* w) int32_t data[2]; std::memcpy(&data[0], &tileInspectorCopiedElement, 8); assert_struct_size(data, sizeof(tileInspectorCopiedElement)); - - game_do_command( - TILE_INSPECTOR_ANY_PASTE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), data[0], - GAME_COMMAND_MODIFY_TILE, data[1], 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyPaste, 0, 0, + tileInspectorCopiedElement); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_base_height_offset(int16_t elementIndex, int8_t heightOffset) { - game_do_command( - TILE_INSPECTOR_ANY_BASE_HEIGHT_OFFSET, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, heightOffset, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyBaseHeightOffset, elementIndex, + heightOffset); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_show_park_fences(bool showFences) { - game_do_command( - TILE_INSPECTOR_SURFACE_SHOW_PARK_FENCES, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), showFences, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceShowParkFences, showFences); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_toggle_corner(int32_t cornerIndex) { - game_do_command( - TILE_INSPECTOR_SURFACE_TOGGLE_CORNER, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), cornerIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceToggleCorner, cornerIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_toggle_diagonal() { - game_do_command( - TILE_INSPECTOR_SURFACE_TOGGLE_DIAGONAL, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), 0, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceToggleDiagonal); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_path_set_sloped(int32_t elementIndex, bool sloped) { - game_do_command( - TILE_INSPECTOR_PATH_SET_SLOPE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, sloped, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathSetSlope, elementIndex, sloped); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_path_set_broken(int32_t elementIndex, bool broken) { - game_do_command( - TILE_INSPECTOR_PATH_SET_BROKEN, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, broken, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathSetBroken, elementIndex, broken); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_path_toggle_edge(int32_t elementIndex, int32_t cornerIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); openrct2_assert(cornerIndex >= 0 && cornerIndex < 8, "cornerIndex out of range"); - game_do_command( - TILE_INSPECTOR_PATH_TOGGLE_EDGE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, cornerIndex, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathToggleEdge, elementIndex, + cornerIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_entrance_make_usable(int32_t elementIndex) { Guard::ArgumentInRange(elementIndex, 0, windowTileInspectorElementCount - 1); - game_do_command( - TILE_INSPECTOR_ENTRANCE_MAKE_USABLE, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::EntranceMakeUsable, elementIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_wall_set_slope(int32_t elementIndex, int32_t slopeValue) { // Make sure only the correct bits are set openrct2_assert((slopeValue & 3) == slopeValue, "slopeValue doesn't match its mask"); - - game_do_command( - TILE_INSPECTOR_WALL_SET_SLOPE, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, slopeValue, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::WallSetSlope, elementIndex, slopeValue); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_block_height_offset(int32_t elementIndex, int8_t heightOffset) { - game_do_command( - TILE_INSPECTOR_TRACK_BASE_HEIGHT_OFFSET, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, heightOffset, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackBaseHeightOffset, elementIndex, + heightOffset); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_block_set_lift(int32_t elementIndex, bool entireTrackBlock, bool chain) { - game_do_command( - TILE_INSPECTOR_TRACK_SET_CHAIN, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, entireTrackBlock, chain); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, + entireTrackBlock ? TileModifyType::TrackSetChainBlock : TileModifyType::TrackSetChain, elementIndex, chain); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_set_block_brake(int32_t elementIndex, bool blockBrake) { - game_do_command( - TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, blockBrake, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackSetBlockBrake, elementIndex, + blockBrake); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_set_indestructible(int32_t elementIndex, bool isIndestructible) { - game_do_command( - TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, isIndestructible, - 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackSetIndestructible, elementIndex, + isIndestructible); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_quarter_tile_set(int32_t elementIndex, const int32_t quarterIndex) { // quarterIndex is widget index relative to WIDX_SCENERY_CHECK_QUARTER_N, so a value from 0-3 openrct2_assert(quarterIndex >= 0 && quarterIndex < 4, "quarterIndex out of range"); - - game_do_command( - TILE_INSPECTOR_SCENERY_SET_QUARTER_LOCATION, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, - (quarterIndex - get_current_rotation()) & 3, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::ScenerySetQuarterLocation, elementIndex, + (quarterIndex - get_current_rotation()) & 3); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_toggle_quadrant_collosion(int32_t elementIndex, const int32_t quadrantIndex) { - game_do_command( - TILE_INSPECTOR_SCENERY_SET_QUARTER_COLLISION, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, - (quadrantIndex + 2 - get_current_rotation()) & 3, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::ScenerySetQuarterCollision, elementIndex, + (quadrantIndex + 2 - get_current_rotation()) & 3); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_banner_toggle_block(int32_t elementIndex, int32_t edgeIndex) @@ -801,17 +803,17 @@ static void window_tile_inspector_banner_toggle_block(int32_t elementIndex, int3 // Make edgeIndex abstract edgeIndex = (edgeIndex - get_current_rotation()) & 3; - - game_do_command( - TILE_INSPECTOR_BANNER_TOGGLE_BLOCKING_EDGE, GAME_COMMAND_FLAG_APPLY, - windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, edgeIndex, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::BannerToggleBlockingEdge, elementIndex, + edgeIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_clamp_corrupt(int32_t elementIndex) { - game_do_command( - TILE_INSPECTOR_CORRUPT_CLAMP, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), - elementIndex, GAME_COMMAND_MODIFY_TILE, 0, 0); + auto modifyTile = TileModifyAction( + { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::CorruptClamp, elementIndex); + GameActions::Execute(&modifyTile); } static void window_tile_inspector_mouseup(rct_window* w, rct_widgetindex widgetIndex) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index f24cd83a6f..90f388f0f5 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1225,7 +1225,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_pickup_guest, game_command_pickup_staff, nullptr, - game_command_modify_tile, + nullptr, nullptr, NULL, }; diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index d9885993c3..d29f0f06b3 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -87,8 +87,8 @@ enum GAME_COMMAND GAME_COMMAND_CHEAT, // GA GAME_COMMAND_PICKUP_GUEST, GAME_COMMAND_PICKUP_STAFF, - GAME_COMMAND_BALLOON_PRESS, // GA - GAME_COMMAND_MODIFY_TILE, + GAME_COMMAND_BALLOON_PRESS, // GA + GAME_COMMAND_MODIFY_TILE, // GA GAME_COMMAND_EDIT_SCENARIO_OPTIONS, // GA GAME_COMMAND_PLACE_PEEP_SPAWN, // GA, TODO: refactor to separate array for just game actions GAME_COMMAND_SET_CLIMATE, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 4bbbabdbcd..25f0601b9a 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -74,6 +74,7 @@ #include "StaffSetOrdersAction.hpp" #include "StaffSetPatrolAreaAction.hpp" #include "SurfaceSetStyleAction.hpp" +#include "TileModifyAction.hpp" #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "TrackSetBrakeSpeedAction.hpp" @@ -151,6 +152,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/TileModifyAction.hpp b/src/openrct2/actions/TileModifyAction.hpp new file mode 100644 index 0000000000..7803e44fc6 --- /dev/null +++ b/src/openrct2/actions/TileModifyAction.hpp @@ -0,0 +1,264 @@ +/***************************************************************************** + * Copyright (c) 2014-2019 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../world/TileInspector.h" +#include "GameAction.h" + +enum class TileModifyType : uint8_t +{ + AnyRemove, + AnySwap, + AnyInsertCorrupt, + AnyRotate, + AnyPaste, + AnySort, + AnyBaseHeightOffset, + SurfaceShowParkFences, + SurfaceToggleCorner, + SurfaceToggleDiagonal, + PathSetSlope, + PathSetBroken, + PathToggleEdge, + EntranceMakeUsable, + WallSetSlope, + TrackBaseHeightOffset, + TrackSetChain, + TrackSetChainBlock, + TrackSetBlockBrake, + TrackSetIndestructible, + ScenerySetQuarterLocation, + ScenerySetQuarterCollision, + BannerToggleBlockingEdge, + CorruptClamp, + Count, +}; + +DEFINE_GAME_ACTION(TileModifyAction, GAME_COMMAND_MODIFY_TILE, GameActionResult) +{ +private: + CoordsXY _loc; + uint8_t _setting{ 0 }; + uint32_t _value1{ 0 }; + uint32_t _value2{ 0 }; + TileElement _pasteElement{ 0 }; + +public: + TileModifyAction() + { + } + TileModifyAction( + CoordsXY loc, TileModifyType setting, uint32_t value1 = { 0 }, uint32_t value2 = { 0 }, + TileElement pasteElement = { 0 }) + : _loc(loc) + , _setting(static_cast(setting)) + , _value1(value1) + , _value2(value2) + , _pasteElement(pasteElement) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_setting) << DS_TAG(_value1) << DS_TAG(_value2) + << DS_TAG(_pasteElement); + } + + GameActionResult::Ptr Query() const override + { + return QueryExecute(false); + } + + GameActionResult::Ptr Execute() const override + { + return QueryExecute(true); + } + +private: + GameActionResult::Ptr QueryExecute(bool isExecuting) const + { + auto res = MakeResult(); + switch (static_cast(_setting)) + { + case TileModifyType::AnyRemove: + { + const auto elementIndex = _value1; + res = tile_inspector_remove_element_at(_loc.x, _loc.y, elementIndex, isExecuting); + break; + } + case TileModifyType::AnySwap: + { + const auto firstIndex = _value1; + const auto secondIndex = _value2; + res = tile_inspector_swap_elements_at(_loc.x, _loc.y, firstIndex, secondIndex, isExecuting); + break; + } + case TileModifyType::AnyInsertCorrupt: + { + const auto elementIndex = _value1; + res = tile_inspector_insert_corrupt_at(_loc.x, _loc.y, elementIndex, isExecuting); + break; + } + case TileModifyType::AnyRotate: + { + const auto elementIndex = _value1; + res = tile_inspector_rotate_element_at(_loc.x, _loc.y, elementIndex, isExecuting); + break; + } + case TileModifyType::AnyPaste: + { + res = tile_inspector_paste_element_at(_loc.x, _loc.y, _pasteElement, isExecuting); + break; + } + case TileModifyType::AnySort: + { + res = tile_inspector_sort_elements_at(_loc.x, _loc.y, isExecuting); + break; + } + case TileModifyType::AnyBaseHeightOffset: + { + const auto elementIndex = _value1; + const auto heightOffset = _value2; + res = tile_inspector_any_base_height_offset(_loc.x, _loc.y, elementIndex, heightOffset, isExecuting); + break; + } + case TileModifyType::SurfaceShowParkFences: + { + const bool showFences = _value1; + res = tile_inspector_surface_show_park_fences(_loc.x, _loc.y, showFences, isExecuting); + break; + } + case TileModifyType::SurfaceToggleCorner: + { + const auto cornerIndex = _value1; + res = tile_inspector_surface_toggle_corner(_loc.x, _loc.y, cornerIndex, isExecuting); + break; + } + case TileModifyType::SurfaceToggleDiagonal: + { + res = tile_inspector_surface_toggle_diagonal(_loc.x, _loc.y, isExecuting); + break; + } + case TileModifyType::PathSetSlope: + { + const auto elementIndex = _value1; + const bool sloped = _value2; + res = tile_inspector_path_set_sloped(_loc.x, _loc.y, elementIndex, sloped, isExecuting); + break; + } + case TileModifyType::PathSetBroken: + { + const auto elementIndex = _value1; + const bool broken = _value2; + res = tile_inspector_path_set_broken(_loc.x, _loc.y, elementIndex, broken, isExecuting); + break; + } + case TileModifyType::PathToggleEdge: + { + const auto elementIndex = _value1; + const auto edgeIndex = _value2; + res = tile_inspector_path_toggle_edge(_loc.x, _loc.y, elementIndex, edgeIndex, isExecuting); + break; + } + case TileModifyType::EntranceMakeUsable: + { + const auto elementIndex = _value1; + res = tile_inspector_entrance_make_usable(_loc.x, _loc.y, elementIndex, isExecuting); + break; + } + case TileModifyType::WallSetSlope: + { + const auto elementIndex = _value1; + const auto slopeValue = _value2; + res = tile_inspector_wall_set_slope(_loc.x, _loc.y, elementIndex, slopeValue, isExecuting); + break; + } + case TileModifyType::TrackBaseHeightOffset: + { + const auto elementIndex = _value1; + const auto heightOffset = _value2; + res = tile_inspector_track_base_height_offset(_loc.x, _loc.y, elementIndex, heightOffset, isExecuting); + break; + } + case TileModifyType::TrackSetChainBlock: + { + const auto elementIndex = _value1; + const bool setChain = _value2; + res = tile_inspector_track_set_chain(_loc.x, _loc.y, elementIndex, true, setChain, isExecuting); + break; + } + case TileModifyType::TrackSetChain: + { + const auto elementIndex = _value1; + const bool setChain = _value2; + res = tile_inspector_track_set_chain(_loc.x, _loc.y, elementIndex, false, setChain, isExecuting); + break; + } + case TileModifyType::TrackSetBlockBrake: + { + const auto elementIndex = _value1; + const bool blockBrake = _value2; + res = tile_inspector_track_set_block_brake(_loc.x, _loc.y, elementIndex, blockBrake, isExecuting); + break; + } + case TileModifyType::TrackSetIndestructible: + { + const auto elementIndex = _value1; + const bool isIndestructible = _value2; + res = tile_inspector_track_set_indestructible(_loc.x, _loc.y, elementIndex, isIndestructible, isExecuting); + break; + } + case TileModifyType::ScenerySetQuarterLocation: + { + const auto elementIndex = _value1; + const auto quarterIndex = _value2; + res = tile_inspector_scenery_set_quarter_location(_loc.x, _loc.y, elementIndex, quarterIndex, isExecuting); + break; + } + case TileModifyType::ScenerySetQuarterCollision: + { + const auto elementIndex = _value1; + const auto quarterIndex = _value2; + res = tile_inspector_scenery_set_quarter_collision(_loc.x, _loc.y, elementIndex, quarterIndex, isExecuting); + break; + } + case TileModifyType::BannerToggleBlockingEdge: + { + const auto elementIndex = _value1; + const auto edgeIndex = _value2; + res = tile_inspector_banner_toggle_blocking_edge(_loc.x, _loc.y, elementIndex, edgeIndex, isExecuting); + break; + } + case TileModifyType::CorruptClamp: + { + const auto elementIndex = _value1; + res = tile_inspector_corrupt_clamp(_loc.x, _loc.y, elementIndex, isExecuting); + break; + } + default: + log_error("invalid instruction"); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + break; + } + + res->Position.x = _loc.x; + res->Position.y = _loc.y; + res->Position.z = tile_element_height(_loc.x, _loc.y); + + return res; + } +}; diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index fe69c07e84..19d8040385 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -16,6 +16,7 @@ #include "../network/network.h" #include "../ride/Ride.h" #include "../world/Location.hpp" +#include "../world/TileElement.h" #include "DataSerialiserTag.h" #include "Endianness.h" #include "MemoryStream.h" @@ -381,6 +382,38 @@ template<> struct DataSerializerTraits } }; +template<> struct DataSerializerTraits +{ + static void encode(IStream* stream, const TileElement& tileElement) + { + stream->WriteValue(tileElement.type); + stream->WriteValue(tileElement.flags); + stream->WriteValue(tileElement.base_height); + stream->WriteValue(tileElement.clearance_height); + for (int i = 0; i < 4; ++i) + { + stream->WriteValue(tileElement.pad_04[i]); + } + } + static void decode(IStream* stream, TileElement& tileElement) + { + tileElement.type = stream->ReadValue(); + tileElement.flags = stream->ReadValue(); + tileElement.base_height = stream->ReadValue(); + tileElement.clearance_height = stream->ReadValue(); + for (int i = 0; i < 4; ++i) + { + tileElement.pad_04[i] = stream->ReadValue(); + } + } + static void log(IStream* stream, const TileElement& tileElement) + { + char msg[128] = {}; + snprintf(msg, sizeof(msg), "TileElement(type = %u, flags = %u, base_height = %u)", tileElement.type, tileElement.flags, tileElement.base_height); + stream->Write(msg, strlen(msg)); + } +}; + template<> struct DataSerializerTraits { static void encode(IStream* stream, const CoordsXY& coords) diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 115395cd1b..f778a907cd 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2245,186 +2245,6 @@ void map_clear_all_elements() } } -void game_command_modify_tile( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - const int32_t flags = *ebx; - const int32_t x = *ecx & 0xFF; - const int32_t y = (*ecx >> 8) & 0xFF; - const TILE_INSPECTOR_INSTRUCTION_TYPE instruction = static_cast(*eax); - - switch (instruction) - { - case TILE_INSPECTOR_ANY_REMOVE: - { - const int16_t elementIndex = *edx; - *ebx = tile_inspector_remove_element_at(x, y, elementIndex, flags); - break; - } - case TILE_INSPECTOR_ANY_SWAP: - { - const int32_t firstIndex = *edx; - const int32_t secondIndex = *edi; - *ebx = tile_inspector_swap_elements_at(x, y, firstIndex, secondIndex, flags); - break; - } - case TILE_INSPECTOR_ANY_INSERT_CORRUPT: - { - const int16_t elementIndex = *edx; - *ebx = tile_inspector_insert_corrupt_at(x, y, elementIndex, flags); - break; - } - case TILE_INSPECTOR_ANY_ROTATE: - { - const int16_t elementIndex = *edx; - *ebx = tile_inspector_rotate_element_at(x, y, elementIndex, flags); - break; - } - case TILE_INSPECTOR_ANY_PASTE: - { - TileElement elementToPaste; - const int32_t data[] = { *edx, *edi }; - assert_struct_size(data, sizeof(elementToPaste)); - std::memcpy(&elementToPaste, data, 8); - *ebx = tile_inspector_paste_element_at(x, y, elementToPaste, flags); - break; - } - case TILE_INSPECTOR_ANY_SORT: - { - *ebx = tile_inspector_sort_elements_at(x, y, flags); - break; - } - case TILE_INSPECTOR_ANY_BASE_HEIGHT_OFFSET: - { - const int16_t elementIndex = *edx; - const int8_t heightOffset = *edi; - *ebx = tile_inspector_any_base_height_offset(x, y, elementIndex, heightOffset, flags); - break; - } - case TILE_INSPECTOR_SURFACE_SHOW_PARK_FENCES: - { - const bool showFences = *edx; - *ebx = tile_inspector_surface_show_park_fences(x, y, showFences, flags); - break; - } - case TILE_INSPECTOR_SURFACE_TOGGLE_CORNER: - { - const int32_t cornerIndex = *edx; - *ebx = tile_inspector_surface_toggle_corner(x, y, cornerIndex, flags); - break; - } - case TILE_INSPECTOR_SURFACE_TOGGLE_DIAGONAL: - { - *ebx = tile_inspector_surface_toggle_diagonal(x, y, flags); - break; - } - case TILE_INSPECTOR_PATH_SET_SLOPE: - { - const int32_t elementIndex = *edx; - const bool sloped = *edi; - *ebx = tile_inspector_path_set_sloped(x, y, elementIndex, sloped, flags); - break; - } - case TILE_INSPECTOR_PATH_SET_BROKEN: - { - const int32_t elementIndex = *edx; - const bool broken = *edi; - *ebx = tile_inspector_path_set_broken(x, y, elementIndex, broken, flags); - break; - } - case TILE_INSPECTOR_PATH_TOGGLE_EDGE: - { - const int32_t elementIndex = *edx; - const int32_t edgeIndex = *edi; - *ebx = tile_inspector_path_toggle_edge(x, y, elementIndex, edgeIndex, flags); - break; - } - case TILE_INSPECTOR_ENTRANCE_MAKE_USABLE: - { - const int32_t elementIndex = *edx; - *ebx = tile_inspector_entrance_make_usable(x, y, elementIndex, flags); - break; - } - case TILE_INSPECTOR_WALL_SET_SLOPE: - { - const int32_t elementIndex = *edx; - const int32_t slopeValue = *edi; - *ebx = tile_inspector_wall_set_slope(x, y, elementIndex, slopeValue, flags); - break; - } - case TILE_INSPECTOR_TRACK_BASE_HEIGHT_OFFSET: - { - const int32_t elementIndex = *edx; - const int8_t heightOffset = *edi; - *ebx = tile_inspector_track_base_height_offset(x, y, elementIndex, heightOffset, flags); - break; - } - case TILE_INSPECTOR_TRACK_SET_CHAIN: - { - const int32_t elementIndex = *edx; - const bool entireTrackBlock = *edi; - const bool setChain = *ebp; - *ebx = tile_inspector_track_set_chain(x, y, elementIndex, entireTrackBlock, setChain, flags); - break; - } - case TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE: - { - const int32_t elementIndex = *edx; - const bool blockBrake = *edi; - *ebx = tile_inspector_track_set_block_brake(x, y, elementIndex, blockBrake, flags); - break; - } - case TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE: - { - const int32_t elementIndex = *edx; - const bool isIndestructible = *edi; - *ebx = tile_inspector_track_set_indestructible(x, y, elementIndex, isIndestructible, flags); - break; - } - case TILE_INSPECTOR_SCENERY_SET_QUARTER_LOCATION: - { - const int32_t elementIndex = *edx; - const int32_t quarterIndex = *edi; - *ebx = tile_inspector_scenery_set_quarter_location(x, y, elementIndex, quarterIndex, flags); - break; - } - case TILE_INSPECTOR_SCENERY_SET_QUARTER_COLLISION: - { - const int32_t elementIndex = *edx; - const int32_t quarterIndex = *edi; - *ebx = tile_inspector_scenery_set_quarter_collision(x, y, elementIndex, quarterIndex, flags); - break; - } - case TILE_INSPECTOR_BANNER_TOGGLE_BLOCKING_EDGE: - { - const int32_t elementIndex = *edx; - const int32_t edgeIndex = *edi; - *ebx = tile_inspector_banner_toggle_blocking_edge(x, y, elementIndex, edgeIndex, flags); - break; - } - case TILE_INSPECTOR_CORRUPT_CLAMP: - { - const int32_t elementIndex = *edx; - *ebx = tile_inspector_corrupt_clamp(x, y, elementIndex, flags); - break; - } - default: - log_error("invalid instruction"); - *ebx = MONEY32_UNDEFINED; - break; - } - - if (flags & GAME_COMMAND_FLAG_APPLY && gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST) - && *ebx != MONEY32_UNDEFINED) - { - LocationXYZ16 coord; - coord.x = (x << 5) + 16; - coord.y = (y << 5) + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } -} - /** * Gets the track element at x, y, z. * @param x x units, not tiles. diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index b50068d3cd..bf54aa9a46 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -187,8 +187,6 @@ int32_t map_can_construct_at(int32_t x, int32_t y, int32_t zLow, int32_t zHigh, void rotate_map_coordinates(int16_t* x, int16_t* y, int32_t rotation); LocationXY16 coordinate_3d_to_2d(const LocationXYZ16* coordinate_3d, int32_t rotation); -void game_command_modify_tile(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - struct tile_element_iterator { int32_t x; diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index a8266a0cc6..0764073784 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -12,6 +12,7 @@ #include "../Context.h" #include "../Game.h" #include "../common.h" +#include "../actions/GameAction.h" #include "../core/Guard.hpp" #include "../interface/Window.h" #include "../localisation/Localisation.h" @@ -77,20 +78,20 @@ static bool map_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t se * @param elementIndex The nth element on this tile * Returns 0 on success, MONEY_UNDEFINED otherwise. */ -int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting) { // Make sure there is enough space for the new element if (!map_check_free_elements_and_reorganise(1)) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Create new corrupt element TileElement* corruptElement = tile_element_insert(x, y, -1, 0); // Ugly hack: -1 guarantees this to be placed first if (corruptElement == nullptr) { log_warning("Failed to insert corrupt element."); - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } corruptElement->SetType(TILE_ELEMENT_TYPE_CORRUPT); @@ -98,7 +99,7 @@ int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIn TileElement* const selectedElement = map_get_nth_element_at(x, y, elementIndex + 1); if (!selectedElement) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } corruptElement->base_height = corruptElement->clearance_height = selectedElement->base_height; @@ -135,7 +136,7 @@ int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIn } // Nothing went wrong - return 0; + return std::make_unique(); } /** @@ -144,15 +145,15 @@ int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIn * @param y The y coordinate of the tile * @param elementIndex The nth element on this tile */ -int32_t tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting) { - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Forcefully remove the element TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); if (!tileElement) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } tile_element_remove(tileElement); map_invalidate_tile_full(x << 5, y << 5); @@ -177,16 +178,16 @@ int32_t tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIn } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, int32_t flags) +GameActionResult::Ptr tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, bool isExecuting) { - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (!map_swap_elements_at(x, y, first, second)) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } map_invalidate_tile_full(x << 5, y << 5); @@ -205,19 +206,19 @@ int32_t tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) { - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t newRotation, pathEdges, pathCorners; TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); if (!tileElement) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } switch (tileElement->GetType()) { @@ -281,28 +282,28 @@ int32_t tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIn } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, int32_t flags) +GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, bool isExecuting) { // Make sure there is enough space for the new element if (!map_check_free_elements_and_reorganise(1)) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, STR_NONE); } - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Check if the element to be pasted refers to a banner index BannerIndex bannerIndex = tile_element_get_banner_index(&element); if (bannerIndex != BANNER_INDEX_NULL) { // The element to be pasted refers to a banner index - make a copy of it - BannerIndex newBannerIndex = create_new_banner(flags); + BannerIndex newBannerIndex = create_new_banner(GAME_COMMAND_FLAG_APPLY); if (newBannerIndex == BANNER_INDEX_NULL) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } rct_banner& newBanner = gBanners[newBannerIndex]; newBanner = gBanners[bannerIndex]; @@ -321,7 +322,7 @@ int32_t tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement elemen rct_string_id newStringIdx = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); if (newStringIdx == 0) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, STR_NONE); } gBanners[newBannerIndex].string_idx = newStringIdx; } @@ -356,12 +357,12 @@ int32_t tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement elemen } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_sort_elements_at(int32_t x, int32_t y, int32_t flags) +GameActionResult::Ptr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool isExecuting) { - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { const TileElement* const firstElement = map_get_first_element_at(x, y); @@ -413,23 +414,23 @@ int32_t tile_inspector_sort_elements_at(int32_t x, int32_t y, int32_t flags) } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_any_base_height_offset(int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, int32_t flags) +GameActionResult::Ptr tile_inspector_any_base_height_offset(int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, bool isExecuting) { TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); if (tileElement == nullptr) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); int16_t newBaseHeight = (int16_t)tileElement->base_height + heightOffset; int16_t newClearanceHeight = (int16_t)tileElement->clearance_height + heightOffset; if (newBaseHeight < 0 || newBaseHeight > 0xff || newClearanceHeight < 0 || newClearanceHeight > 0xff) { - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (tileElement->GetType() == TILE_ELEMENT_TYPE_ENTRANCE) { @@ -465,18 +466,18 @@ int32_t tile_inspector_any_base_height_offset(int32_t x, int32_t y, int16_t elem } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool showFences, int32_t flags) +GameActionResult::Ptr tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool showFences, bool isExecuting) { TileElement* const surfaceelement = map_get_surface_element_at(x, y); // No surface element on tile if (surfaceelement == nullptr) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (!showFences) surfaceelement->AsSurface()->SetParkFences(0); @@ -493,18 +494,18 @@ int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool showF } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, bool isExecuting) { TileElement* const surfaceElement = map_get_surface_element_at(x, y); // No surface element on tile if (surfaceElement == nullptr) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { const uint8_t originalSlope = surfaceElement->AsSurface()->GetSlope(); const bool diagonal = (originalSlope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) >> 4; @@ -560,18 +561,18 @@ int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t corne } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, int32_t flags) +GameActionResult::Ptr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, bool isExecuting) { TileElement* const surfaceElement = map_get_surface_element_at(x, y); // No surface element on tile if (surfaceElement == nullptr) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t newSlope = surfaceElement->AsSurface()->GetSlope() ^ TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT; surfaceElement->AsSurface()->SetSlope(newSlope); @@ -598,17 +599,17 @@ int32_t tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, int32_t fla } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, int32_t flags) +GameActionResult::Ptr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, bool isExecuting) { TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { pathElement->AsPath()->SetSloped(sloped); @@ -622,17 +623,17 @@ int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementInde } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, int32_t flags) +GameActionResult::Ptr tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, bool isExecuting) { TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { pathElement->AsPath()->SetIsBroken(broken); @@ -646,17 +647,17 @@ int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementInde } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) { TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t newEdges = pathElement->AsPath()->GetEdgesAndCorners() ^ (1 << edgeIndex); pathElement->AsPath()->SetEdgesAndCorners(newEdges); @@ -671,22 +672,22 @@ int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementInd } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) { TileElement* const entranceElement = map_get_nth_element_at(x, y, elementIndex); if (entranceElement == nullptr || entranceElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); Ride* ride = get_ride(entranceElement->AsEntrance()->GetRideIndex()); if (ride == nullptr) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t stationIndex = entranceElement->AsEntrance()->GetStationIndex(); @@ -710,17 +711,17 @@ int32_t tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elemen } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, int32_t flags) +GameActionResult::Ptr tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, bool isExecuting) { TileElement* const wallElement = map_get_nth_element_at(x, y, elementIndex); if (wallElement == nullptr || wallElement->GetType() != TILE_ELEMENT_TYPE_WALL) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Set new slope value wallElement->AsWall()->SetSlope(slopeValue); @@ -735,22 +736,22 @@ int32_t tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex } } - return 0; + return std::make_unique(); } // 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 -int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t elementIndex, int8_t offset, int32_t flags) +GameActionResult::Ptr tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t elementIndex, int8_t offset, bool isExecuting) { TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); if (offset == 0) - return 0; + return std::make_unique(); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t type = trackElement->AsTrack()->GetTrackType(); int16_t originX = x << 5; @@ -809,7 +810,7 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el if (!found) { log_error("Track map element part not found!"); - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::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 @@ -827,20 +828,20 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el // TODO: Only invalidate when one of the affected tiles is selected window_invalidate_by_class(WC_TILE_INSPECTOR); - return 0; + return std::make_unique(); } // 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 -int32_t tile_inspector_track_set_chain( - int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, int32_t flags) +GameActionResult::Ptr tile_inspector_track_set_chain( + int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting) { TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (!entireTrackBlock) { @@ -850,7 +851,7 @@ int32_t tile_inspector_track_set_chain( trackElement->AsTrack()->SetHasChain(setChain); } - return 0; + return std::make_unique(); } uint8_t type = trackElement->AsTrack()->GetTrackType(); @@ -910,7 +911,7 @@ int32_t tile_inspector_track_set_chain( if (!found) { log_error("Track map element part not found!"); - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::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 @@ -930,17 +931,17 @@ int32_t tile_inspector_track_set_chain( // TODO: Only invalidate when one of the affected tiles is selected window_invalidate_by_class(WC_TILE_INSPECTOR); - return 0; + return std::make_unique(); } -int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, int32_t flags) +GameActionResult::Ptr tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, bool isExecuting) { TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { trackElement->AsTrack()->SetBlockBrakeClosed(blockBrake); @@ -954,18 +955,18 @@ int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t eleme } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_track_set_indestructible( - int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, int32_t flags) +GameActionResult::Ptr tile_inspector_track_set_indestructible( + int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, bool isExecuting) { TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { trackElement->AsTrack()->SetIsIndestructible(isIndestructible); @@ -979,18 +980,18 @@ int32_t tile_inspector_track_set_indestructible( } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_scenery_set_quarter_location( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_scenery_set_quarter_location( + int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) { TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); if (tileElement == nullptr || tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Set quadrant index tileElement->AsSmallScenery()->SetSceneryQuadrant(quarterIndex); @@ -1006,18 +1007,18 @@ int32_t tile_inspector_scenery_set_quarter_location( } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_scenery_set_quarter_collision( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_scenery_set_quarter_collision( + int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) { TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); if (tileElement == nullptr || tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { tileElement->flags ^= 1 << quarterIndex; @@ -1028,17 +1029,17 @@ int32_t tile_inspector_scenery_set_quarter_collision( } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_banner_toggle_blocking_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_banner_toggle_blocking_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) { TileElement* const bannerElement = map_get_nth_element_at(x, y, elementIndex); if (bannerElement == nullptr || bannerElement->GetType() != TILE_ELEMENT_TYPE_BANNER) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { uint8_t edges = bannerElement->AsBanner()->GetAllowedEdges(); edges ^= (1 << edgeIndex); @@ -1050,20 +1051,20 @@ int32_t tile_inspector_banner_toggle_blocking_edge(int32_t x, int32_t y, int32_t } } - return 0; + return std::make_unique(); } -int32_t tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, int32_t flags) +GameActionResult::Ptr tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) { TileElement* const corruptElement = map_get_nth_element_at(x, y, elementIndex); if (corruptElement == nullptr || corruptElement->GetType() != TILE_ELEMENT_TYPE_CORRUPT) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); if (corruptElement->IsLastForTile()) - return MONEY32_UNDEFINED; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); - if (flags & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { TileElement* const nextElement = corruptElement + 1; corruptElement->base_height = corruptElement->clearance_height = nextElement->base_height; @@ -1074,5 +1075,5 @@ int32_t tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, } } - return 0; + return std::make_unique(); } diff --git a/src/openrct2/world/TileInspector.h b/src/openrct2/world/TileInspector.h index 90262a2959..35b7e49e2b 100644 --- a/src/openrct2/world/TileInspector.h +++ b/src/openrct2/world/TileInspector.h @@ -26,58 +26,38 @@ enum TILE_INSPECTOR_ELEMENT_TYPE TILE_INSPECTOR_ELEMENT_CORRUPT, }; -enum TILE_INSPECTOR_INSTRUCTION_TYPE -{ - TILE_INSPECTOR_ANY_REMOVE, - TILE_INSPECTOR_ANY_SWAP, - TILE_INSPECTOR_ANY_INSERT_CORRUPT, - TILE_INSPECTOR_ANY_ROTATE, - TILE_INSPECTOR_ANY_PASTE, - TILE_INSPECTOR_ANY_SORT, - TILE_INSPECTOR_ANY_BASE_HEIGHT_OFFSET, - TILE_INSPECTOR_SURFACE_SHOW_PARK_FENCES, - TILE_INSPECTOR_SURFACE_TOGGLE_CORNER, - TILE_INSPECTOR_SURFACE_TOGGLE_DIAGONAL, - TILE_INSPECTOR_PATH_SET_SLOPE, - TILE_INSPECTOR_PATH_SET_BROKEN, - TILE_INSPECTOR_PATH_TOGGLE_EDGE, - TILE_INSPECTOR_ENTRANCE_MAKE_USABLE, - TILE_INSPECTOR_WALL_SET_SLOPE, - TILE_INSPECTOR_TRACK_BASE_HEIGHT_OFFSET, - TILE_INSPECTOR_TRACK_SET_CHAIN, - TILE_INSPECTOR_SCENERY_SET_QUARTER_LOCATION, - TILE_INSPECTOR_SCENERY_SET_QUARTER_COLLISION, - TILE_INSPECTOR_BANNER_TOGGLE_BLOCKING_EDGE, - TILE_INSPECTOR_CORRUPT_CLAMP, - TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE, - TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE, -}; - -int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, int32_t flags); -int32_t tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, int32_t flags); -int32_t tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, int32_t flags); -int32_t tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, int32_t flags); -int32_t tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, int32_t flags); -int32_t tile_inspector_sort_elements_at(int32_t x, int32_t y, int32_t flags); -int32_t tile_inspector_any_base_height_offset(int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, int32_t flags); -int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool enabled, int32_t flags); -int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, int32_t flags); -int32_t tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, int32_t flags); -int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, int32_t flags); -int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, int32_t flags); -int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t cornerIndex, int32_t flags); -int32_t tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, int32_t flags); -int32_t tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, int32_t flags); -int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t elementIndex, int8_t offset, int32_t flags); -int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, int32_t flags); -int32_t tile_inspector_track_set_indestructible( - int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, int32_t flags); -int32_t tile_inspector_track_set_chain( - int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, int32_t flags); -int32_t tile_inspector_scenery_set_quarter_location( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags); -int32_t tile_inspector_scenery_set_quarter_collision( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags); -int32_t tile_inspector_banner_toggle_blocking_edge( - int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, int32_t flags); -int32_t tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, int32_t flags); +class GameActionResult; +using GameActionResultPtr = std::unique_ptr; +GameActionResultPtr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, bool isExecuting); +GameActionResultPtr tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, bool isExecuting); +GameActionResultPtr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool isExecuting); +GameActionResultPtr tile_inspector_any_base_height_offset( + int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, bool isExecuting); +GameActionResultPtr tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool enabled, bool isExecuting); +GameActionResultPtr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, bool isExecuting); +GameActionResultPtr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, bool isExecuting); +GameActionResultPtr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, bool isExecuting); +GameActionResultPtr tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, bool isExecuting); +GameActionResultPtr tile_inspector_path_toggle_edge( + int32_t x, int32_t y, int32_t elementIndex, int32_t cornerIndex, bool isExecuting); +GameActionResultPtr tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_wall_set_slope( + int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, bool isExecuting); +GameActionResultPtr tile_inspector_track_base_height_offset( + int32_t x, int32_t y, int32_t elementIndex, int8_t offset, bool isExecuting); +GameActionResultPtr tile_inspector_track_set_block_brake( + int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, bool isExecuting); +GameActionResultPtr tile_inspector_track_set_indestructible( + int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, bool isExecuting); +GameActionResultPtr tile_inspector_track_set_chain( + int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting); +GameActionResultPtr tile_inspector_scenery_set_quarter_location( + int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); +GameActionResultPtr tile_inspector_scenery_set_quarter_collision( + int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); +GameActionResultPtr tile_inspector_banner_toggle_blocking_edge( + int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting); +GameActionResultPtr tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); From afca838f17baff7c6797cce7dddd58030536839a Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 18 May 2019 08:06:09 +0100 Subject: [PATCH 2/4] Provide a game command translation --- src/openrct2/ReplayManager.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index 157be538b0..ad5cde11ae 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -19,6 +19,7 @@ #include "actions/RideEntranceExitPlaceAction.hpp" #include "actions/RideSetSetting.hpp" #include "actions/SetCheatAction.hpp" +#include "actions/TileModifyAction.hpp" #include "actions/TrackPlaceAction.hpp" #include "config/Config.h" #include "core/DataSerialiser.h" @@ -537,6 +538,27 @@ namespace OpenRCT2 result.action->SetFlags(command.ebx & 0xFF); break; } + case GAME_COMMAND_MODIFY_TILE: + { + int32_t param1 = command.edx; + int32_t param2 = command.edi; + CoordsXY loc = { (command.ecx & 0xFF) * 32, ((command.ecx >> 8) & 0xFF) * 32 }; + TileModifyType type = static_cast(command.eax & 0xFF); + + if (type == TileModifyType::AnyPaste) + { + TileElement copiedElement{}; + int32_t data[2] = { command.edx, command.edi }; + std::memcpy(&copiedElement, &data[0], 8); + result.action = std::make_unique(loc, type, 0, 0, copiedElement); + } + else + { + result.action = std::make_unique(loc, type, param1, param2); + } + result.action->SetFlags(command.ebx & 0xFF); + break; + } default: throw std::runtime_error("Deprecated game command requires replay translation."); } From 96ec0123caf7cec8a0281c06599b1895e82ce4eb Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 18 May 2019 09:23:33 +0100 Subject: [PATCH 3/4] Refactor and clean up for CI's. --- src/openrct2-ui/windows/TileInspector.cpp | 2 +- src/openrct2/ReplayManager.cpp | 5 +- src/openrct2/actions/TileModifyAction.hpp | 56 +++-- src/openrct2/core/DataSerialiserTraits.h | 4 +- src/openrct2/world/TileInspector.cpp | 253 +++++++++++----------- src/openrct2/world/TileInspector.h | 49 ++--- 6 files changed, 188 insertions(+), 181 deletions(-) diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 07ef450ee8..49832fcb9a 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index ad5cde11ae..eb4ec432bf 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -542,13 +542,14 @@ namespace OpenRCT2 { int32_t param1 = command.edx; int32_t param2 = command.edi; - CoordsXY loc = { (command.ecx & 0xFF) * 32, ((command.ecx >> 8) & 0xFF) * 32 }; + CoordsXY loc = { static_cast((command.ecx & 0xFF) * 32), + static_cast(((command.ecx >> 8) & 0xFF) * 32) }; TileModifyType type = static_cast(command.eax & 0xFF); if (type == TileModifyType::AnyPaste) { TileElement copiedElement{}; - int32_t data[2] = { command.edx, command.edi }; + uint32_t data[2] = { command.edx, command.edi }; std::memcpy(&copiedElement, &data[0], 8); result.action = std::make_unique(loc, type, 0, 0, copiedElement); } diff --git a/src/openrct2/actions/TileModifyAction.hpp b/src/openrct2/actions/TileModifyAction.hpp index 7803e44fc6..ef063b3856 100644 --- a/src/openrct2/actions/TileModifyAction.hpp +++ b/src/openrct2/actions/TileModifyAction.hpp @@ -48,15 +48,14 @@ private: uint8_t _setting{ 0 }; uint32_t _value1{ 0 }; uint32_t _value2{ 0 }; - TileElement _pasteElement{ 0 }; + TileElement _pasteElement{}; public: TileModifyAction() { } TileModifyAction( - CoordsXY loc, TileModifyType setting, uint32_t value1 = { 0 }, uint32_t value2 = { 0 }, - TileElement pasteElement = { 0 }) + CoordsXY loc, TileModifyType setting, uint32_t value1 = 0, uint32_t value2 = 0, TileElement pasteElement = {}) : _loc(loc) , _setting(static_cast(setting)) , _value1(value1) @@ -74,8 +73,7 @@ public: { GameAction::Serialise(stream); - stream << DS_TAG(_loc) << DS_TAG(_setting) << DS_TAG(_value1) << DS_TAG(_value2) - << DS_TAG(_pasteElement); + stream << DS_TAG(_loc) << DS_TAG(_setting) << DS_TAG(_value1) << DS_TAG(_value2) << DS_TAG(_pasteElement); } GameActionResult::Ptr Query() const override @@ -97,156 +95,156 @@ private: case TileModifyType::AnyRemove: { const auto elementIndex = _value1; - res = tile_inspector_remove_element_at(_loc.x, _loc.y, elementIndex, isExecuting); + res = tile_inspector_remove_element_at(_loc, elementIndex, isExecuting); break; } case TileModifyType::AnySwap: { const auto firstIndex = _value1; const auto secondIndex = _value2; - res = tile_inspector_swap_elements_at(_loc.x, _loc.y, firstIndex, secondIndex, isExecuting); + res = tile_inspector_swap_elements_at(_loc, firstIndex, secondIndex, isExecuting); break; } case TileModifyType::AnyInsertCorrupt: { const auto elementIndex = _value1; - res = tile_inspector_insert_corrupt_at(_loc.x, _loc.y, elementIndex, isExecuting); + res = tile_inspector_insert_corrupt_at(_loc, elementIndex, isExecuting); break; } case TileModifyType::AnyRotate: { const auto elementIndex = _value1; - res = tile_inspector_rotate_element_at(_loc.x, _loc.y, elementIndex, isExecuting); + res = tile_inspector_rotate_element_at(_loc, elementIndex, isExecuting); break; } case TileModifyType::AnyPaste: { - res = tile_inspector_paste_element_at(_loc.x, _loc.y, _pasteElement, isExecuting); + res = tile_inspector_paste_element_at(_loc, _pasteElement, isExecuting); break; } case TileModifyType::AnySort: { - res = tile_inspector_sort_elements_at(_loc.x, _loc.y, isExecuting); + res = tile_inspector_sort_elements_at(_loc, isExecuting); break; } case TileModifyType::AnyBaseHeightOffset: { const auto elementIndex = _value1; const auto heightOffset = _value2; - res = tile_inspector_any_base_height_offset(_loc.x, _loc.y, elementIndex, heightOffset, isExecuting); + res = tile_inspector_any_base_height_offset(_loc, elementIndex, heightOffset, isExecuting); break; } case TileModifyType::SurfaceShowParkFences: { const bool showFences = _value1; - res = tile_inspector_surface_show_park_fences(_loc.x, _loc.y, showFences, isExecuting); + res = tile_inspector_surface_show_park_fences(_loc, showFences, isExecuting); break; } case TileModifyType::SurfaceToggleCorner: { const auto cornerIndex = _value1; - res = tile_inspector_surface_toggle_corner(_loc.x, _loc.y, cornerIndex, isExecuting); + res = tile_inspector_surface_toggle_corner(_loc, cornerIndex, isExecuting); break; } case TileModifyType::SurfaceToggleDiagonal: { - res = tile_inspector_surface_toggle_diagonal(_loc.x, _loc.y, isExecuting); + res = tile_inspector_surface_toggle_diagonal(_loc, isExecuting); break; } case TileModifyType::PathSetSlope: { const auto elementIndex = _value1; const bool sloped = _value2; - res = tile_inspector_path_set_sloped(_loc.x, _loc.y, elementIndex, sloped, isExecuting); + res = tile_inspector_path_set_sloped(_loc, elementIndex, sloped, isExecuting); break; } case TileModifyType::PathSetBroken: { const auto elementIndex = _value1; const bool broken = _value2; - res = tile_inspector_path_set_broken(_loc.x, _loc.y, elementIndex, broken, isExecuting); + res = tile_inspector_path_set_broken(_loc, elementIndex, broken, isExecuting); break; } case TileModifyType::PathToggleEdge: { const auto elementIndex = _value1; const auto edgeIndex = _value2; - res = tile_inspector_path_toggle_edge(_loc.x, _loc.y, elementIndex, edgeIndex, isExecuting); + res = tile_inspector_path_toggle_edge(_loc, elementIndex, edgeIndex, isExecuting); break; } case TileModifyType::EntranceMakeUsable: { const auto elementIndex = _value1; - res = tile_inspector_entrance_make_usable(_loc.x, _loc.y, elementIndex, isExecuting); + res = tile_inspector_entrance_make_usable(_loc, elementIndex, isExecuting); break; } case TileModifyType::WallSetSlope: { const auto elementIndex = _value1; const auto slopeValue = _value2; - res = tile_inspector_wall_set_slope(_loc.x, _loc.y, elementIndex, slopeValue, isExecuting); + res = tile_inspector_wall_set_slope(_loc, elementIndex, slopeValue, isExecuting); break; } case TileModifyType::TrackBaseHeightOffset: { const auto elementIndex = _value1; const auto heightOffset = _value2; - res = tile_inspector_track_base_height_offset(_loc.x, _loc.y, elementIndex, heightOffset, isExecuting); + res = tile_inspector_track_base_height_offset(_loc, elementIndex, heightOffset, isExecuting); break; } case TileModifyType::TrackSetChainBlock: { const auto elementIndex = _value1; const bool setChain = _value2; - res = tile_inspector_track_set_chain(_loc.x, _loc.y, elementIndex, true, setChain, isExecuting); + res = tile_inspector_track_set_chain(_loc, elementIndex, true, setChain, isExecuting); break; } case TileModifyType::TrackSetChain: { const auto elementIndex = _value1; const bool setChain = _value2; - res = tile_inspector_track_set_chain(_loc.x, _loc.y, elementIndex, false, setChain, isExecuting); + res = tile_inspector_track_set_chain(_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.x, _loc.y, elementIndex, blockBrake, isExecuting); + res = tile_inspector_track_set_block_brake(_loc, elementIndex, blockBrake, isExecuting); break; } case TileModifyType::TrackSetIndestructible: { const auto elementIndex = _value1; const bool isIndestructible = _value2; - res = tile_inspector_track_set_indestructible(_loc.x, _loc.y, elementIndex, isIndestructible, isExecuting); + res = tile_inspector_track_set_indestructible(_loc, elementIndex, isIndestructible, isExecuting); break; } case TileModifyType::ScenerySetQuarterLocation: { const auto elementIndex = _value1; const auto quarterIndex = _value2; - res = tile_inspector_scenery_set_quarter_location(_loc.x, _loc.y, elementIndex, quarterIndex, isExecuting); + res = tile_inspector_scenery_set_quarter_location(_loc, elementIndex, quarterIndex, isExecuting); break; } case TileModifyType::ScenerySetQuarterCollision: { const auto elementIndex = _value1; const auto quarterIndex = _value2; - res = tile_inspector_scenery_set_quarter_collision(_loc.x, _loc.y, elementIndex, quarterIndex, isExecuting); + res = tile_inspector_scenery_set_quarter_collision(_loc, elementIndex, quarterIndex, isExecuting); break; } case TileModifyType::BannerToggleBlockingEdge: { const auto elementIndex = _value1; const auto edgeIndex = _value2; - res = tile_inspector_banner_toggle_blocking_edge(_loc.x, _loc.y, elementIndex, edgeIndex, isExecuting); + res = tile_inspector_banner_toggle_blocking_edge(_loc, elementIndex, edgeIndex, isExecuting); break; } case TileModifyType::CorruptClamp: { const auto elementIndex = _value1; - res = tile_inspector_corrupt_clamp(_loc.x, _loc.y, elementIndex, isExecuting); + res = tile_inspector_corrupt_clamp(_loc, elementIndex, isExecuting); break; } default: diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index 19d8040385..7d16b0c847 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -409,7 +409,9 @@ template<> struct DataSerializerTraits static void log(IStream* stream, const TileElement& tileElement) { char msg[128] = {}; - snprintf(msg, sizeof(msg), "TileElement(type = %u, flags = %u, base_height = %u)", tileElement.type, tileElement.flags, tileElement.base_height); + snprintf( + msg, sizeof(msg), "TileElement(type = %u, flags = %u, base_height = %u)", tileElement.type, tileElement.flags, + tileElement.base_height); stream->Write(msg, strlen(msg)); } }; diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 0764073784..5278f341ef 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -11,8 +11,8 @@ #include "../Context.h" #include "../Game.h" -#include "../common.h" #include "../actions/GameAction.h" +#include "../common.h" #include "../core/Guard.hpp" #include "../interface/Window.h" #include "../localisation/Localisation.h" @@ -35,10 +35,10 @@ uint32_t windowTileInspectorTileY; int32_t windowTileInspectorElementCount = 0; int32_t windowTileInspectorSelectedIndex; -static bool map_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second) +static bool map_swap_elements_at(CoordsXY loc, int16_t first, int16_t second) { - TileElement* const firstElement = map_get_nth_element_at(x, y, first); - TileElement* const secondElement = map_get_nth_element_at(x, y, second); + TileElement* const firstElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, first); + TileElement* const secondElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, second); if (firstElement == nullptr) { @@ -78,7 +78,7 @@ static bool map_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t se * @param elementIndex The nth element on this tile * Returns 0 on success, MONEY_UNDEFINED otherwise. */ -GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_insert_corrupt_at(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)) @@ -87,7 +87,8 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int if (isExecuting) { // Create new corrupt element - TileElement* corruptElement = tile_element_insert(x, y, -1, 0); // Ugly hack: -1 guarantees this to be placed first + TileElement* corruptElement = tile_element_insert( + 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."); @@ -96,7 +97,7 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int corruptElement->SetType(TILE_ELEMENT_TYPE_CORRUPT); // Set the base height to be the same as the selected element - TileElement* const selectedElement = map_get_nth_element_at(x, y, elementIndex + 1); + TileElement* const selectedElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex + 1); if (!selectedElement) { return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -107,7 +108,7 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int // 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(x, y, i, i + 1)) + if (!map_swap_elements_at(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 @@ -116,12 +117,12 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int } } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); // 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 && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { windowTileInspectorElementCount++; @@ -145,23 +146,23 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int * @param y The y coordinate of the tile * @param elementIndex The nth element on this tile */ -GameActionResult::Ptr tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_remove_element_at(CoordsXY loc, int16_t elementIndex, bool isExecuting) { if (isExecuting) { // Forcefully remove the element - TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const tileElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (!tileElement) { return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } tile_element_remove(tileElement); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); // Update the window rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { windowTileInspectorElementCount--; @@ -181,20 +182,20 @@ GameActionResult::Ptr tile_inspector_remove_element_at(int32_t x, int32_t y, int return std::make_unique(); } -GameActionResult::Ptr tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, bool isExecuting) +GameActionResult::Ptr tile_inspector_swap_elements_at(CoordsXY loc, int16_t first, int16_t second, bool isExecuting) { if (isExecuting) { - if (!map_swap_elements_at(x, y, first, second)) + if (!map_swap_elements_at(loc, first, second)) { return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); // Update the window rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { // If one of them was selected, update selected list item if (windowTileInspectorSelectedIndex == first) @@ -209,13 +210,13 @@ GameActionResult::Ptr tile_inspector_swap_elements_at(int32_t x, int32_t y, int1 return std::make_unique(); } -GameActionResult::Ptr tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_rotate_element_at(CoordsXY loc, int32_t elementIndex, bool isExecuting) { if (isExecuting) { uint8_t newRotation, pathEdges, pathCorners; - TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const tileElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (!tileElement) { return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -248,11 +249,12 @@ GameActionResult::Ptr tile_inspector_rotate_element_at(int32_t x, int32_t y, int uint8_t z = tileElement->base_height; // Make sure this is the correct entrance or exit - if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE && entrance.x == x && entrance.y == y && entrance.z == z) + if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE && entrance.x == loc.x / 32 && entrance.y == loc.y / 32 + && entrance.z == z) { ride_set_entrance_location(ride, stationIndex, { entrance.x, entrance.y, entrance.z, newRotation }); } - else if (entranceType == ENTRANCE_TYPE_RIDE_EXIT && exit.x == x && exit.y == y && exit.z == z) + else if (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 }); } @@ -274,9 +276,9 @@ GameActionResult::Ptr tile_inspector_rotate_element_at(int32_t x, int32_t y, int } } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); - if ((uint32_t)x == windowTileInspectorTileX && (uint32_t)y == windowTileInspectorTileY) + if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate_by_class(WC_TILE_INSPECTOR); } @@ -285,7 +287,7 @@ GameActionResult::Ptr tile_inspector_rotate_element_at(int32_t x, int32_t y, int return std::make_unique(); } -GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, bool isExecuting) +GameActionResult::Ptr tile_inspector_paste_element_at(CoordsXY loc, TileElement element, bool isExecuting) { // Make sure there is enough space for the new element if (!map_check_free_elements_and_reorganise(1)) @@ -307,8 +309,8 @@ GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, Tile } rct_banner& newBanner = gBanners[newBannerIndex]; newBanner = gBanners[bannerIndex]; - newBanner.x = x; - newBanner.y = y; + newBanner.x = loc.x / 32; + newBanner.y = loc.y / 32; // Use the new banner index tile_element_set_banner_index(&element, newBannerIndex); @@ -328,7 +330,7 @@ GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, Tile } } - TileElement* const pastedElement = tile_element_insert(x, y, 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; @@ -338,16 +340,16 @@ GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, Tile pastedElement->flags |= TILE_ELEMENT_FLAG_LAST_TILE; } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { windowTileInspectorElementCount++; // Select new element if there was none selected already - int16_t newIndex = (int16_t)(pastedElement - map_get_first_element_at(x, y)); + int16_t newIndex = (int16_t)(pastedElement - map_get_first_element_at(loc.x / 32, loc.y / 32)); if (windowTileInspectorSelectedIndex == -1) windowTileInspectorSelectedIndex = newIndex; else if (windowTileInspectorSelectedIndex >= newIndex) @@ -360,11 +362,11 @@ GameActionResult::Ptr tile_inspector_paste_element_at(int32_t x, int32_t y, Tile return std::make_unique(); } -GameActionResult::Ptr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool isExecuting) +GameActionResult::Ptr tile_inspector_sort_elements_at(CoordsXY loc, bool isExecuting) { if (isExecuting) { - const TileElement* const firstElement = map_get_first_element_at(x, y); + const TileElement* const firstElement = map_get_first_element_at(loc.x / 32, loc.y / 32); // Count elements on tile int32_t numElement = 0; @@ -388,7 +390,7 @@ GameActionResult::Ptr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool || (otherElement->base_height == currentElement->base_height && otherElement->clearance_height > currentElement->clearance_height))) { - if (!map_swap_elements_at(x, y, currentId - 1, currentId)) + if (!map_swap_elements_at(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 @@ -402,12 +404,12 @@ GameActionResult::Ptr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool } } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); // Deselect tile for clients who had it selected rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { windowTileInspectorSelectedIndex = -1; window_invalidate(tileInspectorWindow); @@ -417,9 +419,10 @@ GameActionResult::Ptr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool return std::make_unique(); } -GameActionResult::Ptr tile_inspector_any_base_height_offset(int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, bool isExecuting) +GameActionResult::Ptr tile_inspector_any_base_height_offset( + CoordsXY loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting) { - TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const tileElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (tileElement == nullptr) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -445,10 +448,11 @@ GameActionResult::Ptr tile_inspector_any_base_height_offset(int32_t x, int32_t y uint8_t z = tileElement->base_height; // Make sure this is the correct entrance or exit - if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE && entrance.x == x && entrance.y == y && entrance.z == z) + if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE && entrance.x == loc.x / 32 && entrance.y == loc.y / 32 + && entrance.z == z) ride_set_entrance_location( ride, entranceIndex, { entrance.x, entrance.y, z + heightOffset, entrance.direction }); - else if (entranceType == ENTRANCE_TYPE_RIDE_EXIT && exit.x == x && exit.y == y && exit.z == z) + else if (entranceType == ENTRANCE_TYPE_RIDE_EXIT && exit.x == loc.x / 32 && exit.y == loc.y / 32 && exit.z == z) ride_set_exit_location(ride, entranceIndex, { exit.x, exit.y, z + heightOffset, exit.direction }); } } @@ -456,11 +460,11 @@ GameActionResult::Ptr tile_inspector_any_base_height_offset(int32_t x, int32_t y tileElement->base_height += heightOffset; tileElement->clearance_height += heightOffset; - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -469,9 +473,9 @@ GameActionResult::Ptr tile_inspector_any_base_height_offset(int32_t x, int32_t y return std::make_unique(); } -GameActionResult::Ptr tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool showFences, bool isExecuting) +GameActionResult::Ptr tile_inspector_surface_show_park_fences(CoordsXY loc, bool showFences, bool isExecuting) { - TileElement* const surfaceelement = map_get_surface_element_at(x, y); + TileElement* const surfaceelement = map_get_surface_element_at(loc); // No surface element on tile if (surfaceelement == nullptr) @@ -482,13 +486,13 @@ GameActionResult::Ptr tile_inspector_surface_show_park_fences(int32_t x, int32_t if (!showFences) surfaceelement->AsSurface()->SetParkFences(0); else - update_park_fences({ x << 5, y << 5 }); + update_park_fences(loc); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -497,9 +501,9 @@ GameActionResult::Ptr tile_inspector_surface_show_park_fences(int32_t x, int32_t return std::make_unique(); } -GameActionResult::Ptr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_surface_toggle_corner(CoordsXY loc, int32_t cornerIndex, bool isExecuting) { - TileElement* const surfaceElement = map_get_surface_element_at(x, y); + TileElement* const surfaceElement = map_get_surface_element_at(loc); // No surface element on tile if (surfaceElement == nullptr) @@ -551,11 +555,11 @@ GameActionResult::Ptr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, surfaceElement->clearance_height = surfaceElement->base_height + (diagonal ? 2 : 0); } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -564,9 +568,9 @@ GameActionResult::Ptr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, return std::make_unique(); } -GameActionResult::Ptr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, bool isExecuting) +GameActionResult::Ptr tile_inspector_surface_toggle_diagonal(CoordsXY loc, bool isExecuting) { - TileElement* const surfaceElement = map_get_surface_element_at(x, y); + TileElement* const surfaceElement = map_get_surface_element_at(loc); // No surface element on tile if (surfaceElement == nullptr) @@ -589,11 +593,11 @@ GameActionResult::Ptr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t surfaceElement->clearance_height = surfaceElement->base_height; } - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -602,9 +606,9 @@ GameActionResult::Ptr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t return std::make_unique(); } -GameActionResult::Ptr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, bool isExecuting) +GameActionResult::Ptr tile_inspector_path_set_sloped(CoordsXY loc, int32_t elementIndex, bool sloped, bool isExecuting) { - TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const pathElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -613,11 +617,11 @@ GameActionResult::Ptr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32 { pathElement->AsPath()->SetSloped(sloped); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -626,9 +630,9 @@ GameActionResult::Ptr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32 return std::make_unique(); } -GameActionResult::Ptr tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, bool isExecuting) +GameActionResult::Ptr tile_inspector_path_set_broken(CoordsXY loc, int32_t elementIndex, bool broken, bool isExecuting) { - TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const pathElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -637,11 +641,11 @@ GameActionResult::Ptr tile_inspector_path_set_broken(int32_t x, int32_t y, int32 { pathElement->AsPath()->SetIsBroken(broken); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -650,9 +654,9 @@ GameActionResult::Ptr tile_inspector_path_set_broken(int32_t x, int32_t y, int32 return std::make_unique(); } -GameActionResult::Ptr tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_path_toggle_edge(CoordsXY loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) { - TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const pathElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -662,11 +666,11 @@ GameActionResult::Ptr tile_inspector_path_toggle_edge(int32_t x, int32_t y, int3 uint8_t newEdges = pathElement->AsPath()->GetEdgesAndCorners() ^ (1 << edgeIndex); pathElement->AsPath()->SetEdgesAndCorners(newEdges); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -675,9 +679,9 @@ GameActionResult::Ptr tile_inspector_path_toggle_edge(int32_t x, int32_t y, int3 return std::make_unique(); } -GameActionResult::Ptr tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_entrance_make_usable(CoordsXY loc, int32_t elementIndex, bool isExecuting) { - TileElement* const entranceElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const entranceElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (entranceElement == nullptr || entranceElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -695,17 +699,19 @@ GameActionResult::Ptr tile_inspector_entrance_make_usable(int32_t x, int32_t y, { case ENTRANCE_TYPE_RIDE_ENTRANCE: ride_set_entrance_location( - ride, stationIndex, { x, y, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() }); + ride, stationIndex, + { loc.x / 32, loc.y / 32, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() }); break; case ENTRANCE_TYPE_RIDE_EXIT: ride_set_exit_location( - ride, stationIndex, { x, y, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() }); + ride, stationIndex, + { loc.x / 32, loc.y / 32, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() }); break; } rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -714,9 +720,9 @@ GameActionResult::Ptr tile_inspector_entrance_make_usable(int32_t x, int32_t y, return std::make_unique(); } -GameActionResult::Ptr tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, bool isExecuting) +GameActionResult::Ptr tile_inspector_wall_set_slope(CoordsXY loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting) { - TileElement* const wallElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const wallElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (wallElement == nullptr || wallElement->GetType() != TILE_ELEMENT_TYPE_WALL) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -726,11 +732,11 @@ GameActionResult::Ptr tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_ // Set new slope value wallElement->AsWall()->SetSlope(slopeValue); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -741,9 +747,10 @@ GameActionResult::Ptr tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_ // 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 -GameActionResult::Ptr tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t elementIndex, int8_t offset, bool isExecuting) +GameActionResult::Ptr tile_inspector_track_base_height_offset( + CoordsXY loc, int32_t elementIndex, int8_t offset, bool isExecuting) { - TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const trackElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (offset == 0) return std::make_unique(); @@ -754,8 +761,8 @@ GameActionResult::Ptr tile_inspector_track_base_height_offset(int32_t x, int32_t if (isExecuting) { uint8_t type = trackElement->AsTrack()->GetTrackType(); - int16_t originX = x << 5; - int16_t originY = y << 5; + int16_t originX = loc.x; + int16_t originY = loc.y; int16_t originZ = trackElement->base_height * 8; uint8_t rotation = trackElement->GetDirection(); ride_id_t rideIndex = trackElement->AsTrack()->GetRideIndex(); @@ -834,9 +841,9 @@ GameActionResult::Ptr tile_inspector_track_base_height_offset(int32_t x, int32_t // 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 GameActionResult::Ptr tile_inspector_track_set_chain( - int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting) + CoordsXY loc, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting) { - TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const trackElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -855,8 +862,8 @@ GameActionResult::Ptr tile_inspector_track_set_chain( } uint8_t type = trackElement->AsTrack()->GetTrackType(); - int16_t originX = x << 5; - int16_t originY = y << 5; + int16_t originX = loc.x; + int16_t originY = loc.y; int16_t originZ = trackElement->base_height * 8; uint8_t rotation = trackElement->GetDirection(); ride_id_t rideIndex = trackElement->AsTrack()->GetRideIndex(); @@ -934,9 +941,10 @@ GameActionResult::Ptr tile_inspector_track_set_chain( return std::make_unique(); } -GameActionResult::Ptr tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, bool isExecuting) +GameActionResult::Ptr tile_inspector_track_set_block_brake( + CoordsXY loc, int32_t elementIndex, bool blockBrake, bool isExecuting) { - TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const trackElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -945,11 +953,11 @@ GameActionResult::Ptr tile_inspector_track_set_block_brake(int32_t x, int32_t y, { trackElement->AsTrack()->SetBlockBrakeClosed(blockBrake); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -959,9 +967,9 @@ GameActionResult::Ptr tile_inspector_track_set_block_brake(int32_t x, int32_t y, } GameActionResult::Ptr tile_inspector_track_set_indestructible( - int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, bool isExecuting) + CoordsXY loc, int32_t elementIndex, bool isIndestructible, bool isExecuting) { - TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const trackElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -970,11 +978,11 @@ GameActionResult::Ptr tile_inspector_track_set_indestructible( { trackElement->AsTrack()->SetIsIndestructible(isIndestructible); - map_invalidate_tile_full(x << 5, y << 5); + map_invalidate_tile_full(loc.x, loc.y); rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); - if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX - && (uint32_t)y == windowTileInspectorTileY) + if (tileInspectorWindow != nullptr && (uint32_t)(loc.x / 32) == windowTileInspectorTileX + && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate(tileInspectorWindow); } @@ -984,9 +992,9 @@ GameActionResult::Ptr tile_inspector_track_set_indestructible( } GameActionResult::Ptr tile_inspector_scenery_set_quarter_location( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) + CoordsXY loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) { - TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const tileElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (tileElement == nullptr || tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -1000,8 +1008,8 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_location( tileElement->flags &= 0xF0; tileElement->flags |= 1 << ((quarterIndex + 2) & 3); - map_invalidate_tile_full(x << 5, y << 5); - if ((uint32_t)x == windowTileInspectorTileX && (uint32_t)y == windowTileInspectorTileY) + map_invalidate_tile_full(loc.x, loc.y); + if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate_by_class(WC_TILE_INSPECTOR); } @@ -1011,9 +1019,9 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_location( } GameActionResult::Ptr tile_inspector_scenery_set_quarter_collision( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) + CoordsXY loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting) { - TileElement* const tileElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const tileElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (tileElement == nullptr || tileElement->GetType() != TILE_ELEMENT_TYPE_SMALL_SCENERY) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -1022,8 +1030,8 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_collision( { tileElement->flags ^= 1 << quarterIndex; - map_invalidate_tile_full(x << 5, y << 5); - if ((uint32_t)x == windowTileInspectorTileX && (uint32_t)y == windowTileInspectorTileY) + map_invalidate_tile_full(loc.x, loc.y); + if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate_by_class(WC_TILE_INSPECTOR); } @@ -1032,9 +1040,10 @@ GameActionResult::Ptr tile_inspector_scenery_set_quarter_collision( return std::make_unique(); } -GameActionResult::Ptr tile_inspector_banner_toggle_blocking_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_banner_toggle_blocking_edge( + CoordsXY loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting) { - TileElement* const bannerElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const bannerElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (bannerElement == nullptr || bannerElement->GetType() != TILE_ELEMENT_TYPE_BANNER) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -1045,7 +1054,7 @@ GameActionResult::Ptr tile_inspector_banner_toggle_blocking_edge(int32_t x, int3 edges ^= (1 << edgeIndex); bannerElement->AsBanner()->SetAllowedEdges(edges); - if ((uint32_t)x == windowTileInspectorTileX && (uint32_t)y == windowTileInspectorTileY) + if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate_by_class(WC_TILE_INSPECTOR); } @@ -1054,9 +1063,9 @@ GameActionResult::Ptr tile_inspector_banner_toggle_blocking_edge(int32_t x, int3 return std::make_unique(); } -GameActionResult::Ptr tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting) +GameActionResult::Ptr tile_inspector_corrupt_clamp(CoordsXY loc, int32_t elementIndex, bool isExecuting) { - TileElement* const corruptElement = map_get_nth_element_at(x, y, elementIndex); + TileElement* const corruptElement = map_get_nth_element_at(loc.x / 32, loc.y / 32, elementIndex); if (corruptElement == nullptr || corruptElement->GetType() != TILE_ELEMENT_TYPE_CORRUPT) return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); @@ -1069,7 +1078,7 @@ GameActionResult::Ptr tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t TileElement* const nextElement = corruptElement + 1; corruptElement->base_height = corruptElement->clearance_height = nextElement->base_height; - if ((uint32_t)x == windowTileInspectorTileX && (uint32_t)y == windowTileInspectorTileY) + if ((uint32_t)(loc.x / 32) == windowTileInspectorTileX && (uint32_t)(loc.y / 32) == windowTileInspectorTileY) { window_invalidate_by_class(WC_TILE_INSPECTOR); } diff --git a/src/openrct2/world/TileInspector.h b/src/openrct2/world/TileInspector.h index 35b7e49e2b..05a24484c9 100644 --- a/src/openrct2/world/TileInspector.h +++ b/src/openrct2/world/TileInspector.h @@ -28,36 +28,33 @@ enum TILE_INSPECTOR_ELEMENT_TYPE class GameActionResult; using GameActionResultPtr = std::unique_ptr; -GameActionResultPtr tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting); -GameActionResultPtr tile_inspector_remove_element_at(int32_t x, int32_t y, int16_t elementIndex, bool isExecuting); -GameActionResultPtr tile_inspector_swap_elements_at(int32_t x, int32_t y, int16_t first, int16_t second, bool isExecuting); -GameActionResultPtr tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); -GameActionResultPtr tile_inspector_paste_element_at(int32_t x, int32_t y, TileElement element, bool isExecuting); -GameActionResultPtr tile_inspector_sort_elements_at(int32_t x, int32_t y, bool isExecuting); +GameActionResultPtr tile_inspector_insert_corrupt_at(CoordsXY loc, int16_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_remove_element_at(CoordsXY loc, int16_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_swap_elements_at(CoordsXY loc, int16_t first, int16_t second, bool isExecuting); +GameActionResultPtr tile_inspector_rotate_element_at(CoordsXY loc, int32_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_paste_element_at(CoordsXY loc, TileElement element, bool isExecuting); +GameActionResultPtr tile_inspector_sort_elements_at(CoordsXY loc, bool isExecuting); GameActionResultPtr tile_inspector_any_base_height_offset( - int32_t x, int32_t y, int16_t elementIndex, int8_t heightOffset, bool isExecuting); -GameActionResultPtr tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool enabled, bool isExecuting); -GameActionResultPtr tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, bool isExecuting); -GameActionResultPtr tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, bool isExecuting); -GameActionResultPtr tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, bool isExecuting); -GameActionResultPtr tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, bool isExecuting); -GameActionResultPtr tile_inspector_path_toggle_edge( - int32_t x, int32_t y, int32_t elementIndex, int32_t cornerIndex, bool isExecuting); -GameActionResultPtr tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); -GameActionResultPtr tile_inspector_wall_set_slope( - int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, bool isExecuting); + CoordsXY loc, int16_t elementIndex, int8_t heightOffset, bool isExecuting); +GameActionResultPtr tile_inspector_surface_show_park_fences(CoordsXY loc, bool enabled, bool isExecuting); +GameActionResultPtr tile_inspector_surface_toggle_corner(CoordsXY loc, int32_t cornerIndex, bool isExecuting); +GameActionResultPtr tile_inspector_surface_toggle_diagonal(CoordsXY loc, bool isExecuting); +GameActionResultPtr tile_inspector_path_set_sloped(CoordsXY loc, int32_t elementIndex, bool sloped, bool isExecuting); +GameActionResultPtr tile_inspector_path_set_broken(CoordsXY loc, int32_t elementIndex, bool broken, bool isExecuting); +GameActionResultPtr tile_inspector_path_toggle_edge(CoordsXY loc, int32_t elementIndex, int32_t cornerIndex, bool isExecuting); +GameActionResultPtr tile_inspector_entrance_make_usable(CoordsXY loc, int32_t elementIndex, bool isExecuting); +GameActionResultPtr tile_inspector_wall_set_slope(CoordsXY loc, int32_t elementIndex, int32_t slopeValue, bool isExecuting); GameActionResultPtr tile_inspector_track_base_height_offset( - int32_t x, int32_t y, int32_t elementIndex, int8_t offset, bool isExecuting); -GameActionResultPtr tile_inspector_track_set_block_brake( - int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, bool isExecuting); + CoordsXY loc, int32_t elementIndex, int8_t offset, bool isExecuting); +GameActionResultPtr tile_inspector_track_set_block_brake(CoordsXY loc, int32_t elementIndex, bool blockBrake, bool isExecuting); GameActionResultPtr tile_inspector_track_set_indestructible( - int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, bool isExecuting); + CoordsXY loc, int32_t elementIndex, bool isIndestructible, bool isExecuting); GameActionResultPtr tile_inspector_track_set_chain( - int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting); + CoordsXY loc, int32_t elementIndex, bool entireTrackBlock, bool setChain, bool isExecuting); GameActionResultPtr tile_inspector_scenery_set_quarter_location( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); + CoordsXY loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); GameActionResultPtr tile_inspector_scenery_set_quarter_collision( - int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); + CoordsXY loc, int32_t elementIndex, int32_t quarterIndex, bool isExecuting); GameActionResultPtr tile_inspector_banner_toggle_blocking_edge( - int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, bool isExecuting); -GameActionResultPtr tile_inspector_corrupt_clamp(int32_t x, int32_t y, int32_t elementIndex, bool isExecuting); + CoordsXY loc, int32_t elementIndex, int32_t edgeIndex, bool isExecuting); +GameActionResultPtr tile_inspector_corrupt_clamp(CoordsXY loc, int32_t elementIndex, bool isExecuting); From 9cd3119897e4b8b2c22d44f6dd3c9513649e2743 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 11 Jun 2019 18:44:23 +0100 Subject: [PATCH 4/4] Increment network version --- src/openrct2/network/Network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 927e2a5858..aa1f25d998 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -33,7 +33,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "40" +#define NETWORK_STREAM_VERSION "41" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr;