From d63919c0ccb385dfc1a846506531ec33cab6c1fa Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 5 Apr 2019 19:16:23 +0100 Subject: [PATCH 1/7] Implement LargeSceneryPlaceAction --- src/openrct2-ui/windows/TopToolbar.cpp | 72 ++-- src/openrct2/Game.cpp | 7 +- src/openrct2/Game.h | 8 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/LargeSceneryPlaceAction.hpp | 366 ++++++++++++++++++ src/openrct2/ride/TrackDesign.cpp | 16 +- src/openrct2/world/Map.cpp | 242 ------------ src/openrct2/world/Map.h | 2 - 8 files changed, 432 insertions(+), 283 deletions(-) create mode 100644 src/openrct2/actions/LargeSceneryPlaceAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 7d605ddb15..36e535df48 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1859,31 +1860,46 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo for (; zAttemptRange != 0; zAttemptRange--) { - int32_t flags = (parameter_1 & 0xFF00) | GAME_COMMAND_FLAG_APPLY; + auto primaryColour = parameter_2 & 0xFF; + auto secondaryColour = (parameter_2 >> 8) & 0xFF; + auto largeSceneryType = parameter_3 & 0xFF; + CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; - gDisableErrorWindowSound = true; - gGameCommandErrorTitle = STR_CANT_POSITION_THIS_HERE; - int32_t cost = game_do_command( - gridX, flags, gridY, parameter_2, GAME_COMMAND_PLACE_LARGE_SCENERY, parameter_3, gSceneryPlaceZ); - gDisableErrorWindowSound = false; + auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour); - if (cost != MONEY32_UNDEFINED) - { - window_close_by_class(WC_ERROR); - audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); - return; - } - - if (gGameCommandErrorText == STR_NOT_ENOUGH_CASH_REQUIRES - || gGameCommandErrorText == STR_CAN_ONLY_BUILD_THIS_ON_WATER) + auto res = GameActions::Query(&sceneryPlaceAction); + if (res->Error == GA_ERROR::OK) { break; } - gSceneryPlaceZ += 8; - } + if (res->ErrorMessage == STR_NOT_ENOUGH_CASH_REQUIRES || res->ErrorMessage == STR_CAN_ONLY_BUILD_THIS_ON_WATER) + { + break; + } - audio_play_sound_at_location(SOUND_ERROR, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); + if (zAttemptRange != 1) + { + gSceneryPlaceZ += 8; + } + } + auto primaryColour = parameter_2 & 0xFF; + auto secondaryColour = (parameter_2 >> 8) & 0xFF; + auto largeSceneryType = parameter_3 & 0xFF; + CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; + + auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour); + sceneryPlaceAction.SetCallback([](const GameAction* ga, const GameActionResult* result) { + if (result->Error == GA_ERROR::OK) + { + audio_play_sound_at_location(SOUND_PLACE_ITEM, result->Position.x, result->Position.y, result->Position.z); + } + else + { + audio_play_sound_at_location(SOUND_ERROR, result->Position.x, result->Position.y, result->Position.z); + } + }); + auto res = GameActions::Execute(&sceneryPlaceAction); break; } case SCENERY_TYPE_BANNER: @@ -2540,18 +2556,25 @@ static money32 try_place_ghost_scenery( break; } case 3: + { // Large Scenery // 6e25a7 - cost = game_do_command( - map_tile.x, parameter_1 | 0x69, map_tile.y, parameter_2, GAME_COMMAND_PLACE_LARGE_SCENERY, parameter_3, - gSceneryPlaceZ); + auto primaryColour = parameter_2 & 0xFF; + auto secondaryColour = (parameter_2 >> 8) & 0xFF; + auto sceneryType = parameter_3 & 0xFF; + CoordsXYZD loc = { map_tile.x, map_tile.y, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; - if (cost == MONEY32_UNDEFINED) - return cost; + auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, sceneryType, primaryColour, secondaryColour); + sceneryPlaceAction.SetFlags( + GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); + auto res = GameActions::Execute(&sceneryPlaceAction); + + if (res->Error != GA_ERROR::OK) + return res->Cost; gSceneryGhostPosition.x = map_tile.x; gSceneryGhostPosition.y = map_tile.y; - gSceneryPlaceRotation = ((parameter_1 >> 8) & 0xFF); + gSceneryPlaceRotation = loc.direction; tileElement = gSceneryTileElement; gSceneryGhostPosition.z = tileElement->base_height; @@ -2569,6 +2592,7 @@ static money32 try_place_ghost_scenery( gSceneryGhostType |= SCENERY_GHOST_FLAG_3; break; + } case 4: // Banners // 6e2612 diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 0620e3d32f..bdd54f9fd2 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -409,8 +409,7 @@ int32_t game_do_command_p( // Remove ghost scenery so it doesn't interfere with incoming network command if ((flags & GAME_COMMAND_FLAG_NETWORKED) && !(flags & GAME_COMMAND_FLAG_GHOST) - && (command == GAME_COMMAND_PLACE_SCENERY || command == GAME_COMMAND_PLACE_LARGE_SCENERY - || command == GAME_COMMAND_PLACE_BANNER || command == GAME_COMMAND_PLACE_PATH)) + && (command == GAME_COMMAND_PLACE_BANNER)) { scenery_remove_ghost_tool_placement(); } @@ -610,7 +609,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_DEMOLISH_RIDE, args); network_append_server_log(log_msg); } - else if (command == GAME_COMMAND_PLACE_LARGE_SCENERY || command == GAME_COMMAND_PLACE_BANNER) + else if (command == GAME_COMMAND_PLACE_BANNER) { uint8_t flags = *ebx & 0xFF; if (flags & GAME_COMMAND_FLAG_GHOST) @@ -1247,7 +1246,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_place_large_scenery, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 6b80e1c6d5..bd7e0b674d 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -62,10 +62,10 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_COLOUR, // GA GAME_COMMAND_PLACE_WALL, // GA GAME_COMMAND_REMOVE_WALL, // GA - GAME_COMMAND_PLACE_LARGE_SCENERY, - GAME_COMMAND_REMOVE_LARGE_SCENERY, // GA - GAME_COMMAND_SET_CURRENT_LOAN, // GA - GAME_COMMAND_SET_RESEARCH_FUNDING, // GA + GAME_COMMAND_PLACE_LARGE_SCENERY, // GA + GAME_COMMAND_REMOVE_LARGE_SCENERY, // GA + GAME_COMMAND_SET_CURRENT_LOAN, // GA + GAME_COMMAND_SET_RESEARCH_FUNDING, // GA GAME_COMMAND_PLACE_TRACK_DESIGN, GAME_COMMAND_START_MARKETING_CAMPAIGN, // GA GAME_COMMAND_PLACE_MAZE_DESIGN, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index ec7c557059..d9e69ae2e3 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -24,6 +24,7 @@ #include "LandRaiseAction.hpp" #include "LandSetHeightAction.hpp" #include "LandSmoothAction.hpp" +#include "LargeSceneryPlaceAction.hpp" #include "LargeSceneryRemoveAction.hpp" #include "LargeScenerySetColourAction.hpp" #include "LoadOrQuitAction.hpp" @@ -124,6 +125,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp new file mode 100644 index 0000000000..f54934d67e --- /dev/null +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -0,0 +1,366 @@ +/***************************************************************************** + * 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 "../ride/Ride.h" +#include "../world/Banner.h" +#include "../world/LargeScenery.h" +#include "../world/MapAnimation.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GAME_COMMAND_PLACE_LARGE_SCENERY, GameActionResult) +{ +private: + CoordsXYZD _loc; + uint8_t _sceneryType{ std::numeric_limits::max() }; + uint8_t _primaryColour; + uint8_t _secondaryColour; + +public: + LargeSceneryPlaceAction() = default; + + LargeSceneryPlaceAction(CoordsXYZD loc, uint8_t sceneryType, uint8_t primaryColour, uint8_t secondaryColour) + : _loc(loc) + , _sceneryType(sceneryType) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = surfaceHeight; + + gSceneryGroundFlags = 0; + BannerIndex bannerId = BANNER_INDEX_NULL; + money32 supportsCost = 0; + + if (_primaryColour > TILE_ELEMENT_COLOUR_MASK || _secondaryColour > TILE_ELEMENT_COLOUR_MASK) + { + log_error("Invalid game command for scenery placement, primaryColour = %u, secondaryColour = %u", _primaryColour, _secondaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + if (_sceneryType >= MAX_LARGE_SCENERY_OBJECTS) + { + log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + rct_scenery_entry* sceneryEntry = get_large_scenery_entry(_sceneryType); + if (sceneryEntry == nullptr) + { + log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + uint32_t totalNumTiles = GetTotalNumTiles(sceneryEntry->large_scenery.tiles); + int16_t maxHeight = GetMaxSurfaceHeight(sceneryEntry->large_scenery.tiles); + + if (_loc.z != 0) + { + maxHeight = _loc.z; + } + + res->Position.z = maxHeight; + + if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) + { + bannerId = create_new_banner(0); + + if (bannerId == BANNER_INDEX_NULL) + { + log_error("No free banners available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + } + + if (!map_check_free_elements_and_reorganise(totalNumTiles)) + { + log_error("No free map elements available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + + uint8_t tileNum = 0; + for (rct_large_scenery_tile* tile = sceneryEntry->large_scenery.tiles; tile->x_offset != -1; tile++, tileNum++) + { + auto tempX = tile->x_offset; + auto tempY = tile->y_offset; + rotate_map_coordinates(&tempX, &tempY, _loc.direction); + CoordsXY curTile = { tempX, tempY }; + + curTile.x += _loc.x; + curTile.y += _loc.y; + + int32_t zLow = (tile->z_offset + maxHeight) / 8; + int32_t zHigh = (tile->z_clearance / 8) + zLow; + + QuarterTile quarterTile = QuarterTile{ static_cast(tile->flags >> 12), 0 }.Rotate(_loc.direction); + if (!map_can_construct_with_clear_at( + curTile.x, curTile.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags(), &supportsCost, + CREATE_CROSSING_MODE_NONE)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); + } + + if ((gMapGroundFlags & ELEMENT_IS_UNDERWATER) || (gMapGroundFlags & ELEMENT_IS_UNDERGROUND)) + { + log_error("Can't place object underwater / underground."); + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE); + } + + int32_t tempSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + if (!gCheatsDisableClearanceChecks) + { + if (gSceneryGroundFlags && !(gSceneryGroundFlags & tempSceneryGroundFlags)) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); + } + } + gSceneryGroundFlags = tempSceneryGroundFlags; + + if (curTile.x >= gMapSizeUnits || curTile.y >= gMapSizeUnits) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP); + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned(curTile.x, curTile.y, zLow * 8) + && !gCheatsSandboxMode) + { + log_error("Location not owned."); + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE); + } + } + + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + res->Cost = (sceneryEntry->large_scenery.price * 10) + supportsCost; + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; + + int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = surfaceHeight; + + gSceneryGroundFlags = 0; + BannerIndex bannerId = BANNER_INDEX_NULL; + money32 supportsCost = 0; + + rct_scenery_entry* sceneryEntry = get_large_scenery_entry(_sceneryType); + if (sceneryEntry == nullptr) + { + log_error("Invalid game command for scenery placement, sceneryType = %u", _sceneryType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + if (sceneryEntry->large_scenery.tiles == nullptr) + { + log_error("Invalid large scenery object, sceneryType = %u", _sceneryType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + uint32_t totalNumTiles = GetTotalNumTiles(sceneryEntry->large_scenery.tiles); + int16_t maxHeight = GetMaxSurfaceHeight(sceneryEntry->large_scenery.tiles); + + if (_loc.z != 0) + { + maxHeight = _loc.z; + } + + res->Position.z = maxHeight; + + if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) + { + bannerId = create_new_banner(GAME_COMMAND_FLAG_APPLY); + + if (bannerId == BANNER_INDEX_NULL) + { + log_error("No free banners available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + + rct_banner* banner = &gBanners[bannerId]; + banner->flags |= BANNER_FLAG_IS_LARGE_SCENERY; + banner->type = 0; + banner->x = _loc.x / 32; + banner->y = _loc.y / 32; + + ride_id_t rideIndex = banner_get_closest_ride_index(_loc.x, _loc.y, maxHeight); + if (rideIndex != RIDE_ID_NULL) + { + banner->ride_index = rideIndex; + banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; + } + } + + if (!map_check_free_elements_and_reorganise(totalNumTiles)) + { + log_error("No free map elements available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + + uint8_t tileNum = 0; + for (rct_large_scenery_tile* tile = sceneryEntry->large_scenery.tiles; tile->x_offset != -1; tile++, tileNum++) + { + auto tempX = tile->x_offset; + auto tempY = tile->y_offset; + rotate_map_coordinates(&tempX, &tempY, _loc.direction); + CoordsXY curTile = { tempX, tempY }; + + curTile.x += _loc.x; + curTile.y += _loc.y; + + int32_t zLow = (tile->z_offset + maxHeight) / 8; + int32_t zHigh = (tile->z_clearance / 8) + zLow; + + QuarterTile quarterTile = QuarterTile{ static_cast(tile->flags >> 12), 0 }.Rotate(_loc.direction); + if (!map_can_construct_with_clear_at( + curTile.x, curTile.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags(), &supportsCost, + CREATE_CROSSING_MODE_NONE)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); + } + + gSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + { + footpath_remove_litter(curTile.x, curTile.y, zLow * 8); + if (!gCheatsDisableClearanceChecks) + { + wall_remove_at(curTile.x, curTile.y, zLow * 8, zHigh * 8); + } + } + + TileElement* newTileElement = tile_element_insert( + curTile.x / 32, curTile.y / 32, zLow, quarterTile.GetBaseQuarterOccupied()); + Guard::Assert(newTileElement != nullptr); + map_animation_create(MAP_ANIMATION_TYPE_LARGE_SCENERY, curTile.x, curTile.y, zLow); + newTileElement->SetType(TILE_ELEMENT_TYPE_LARGE_SCENERY); + newTileElement->clearance_height = zHigh; + auto newSceneryElement = newTileElement->AsLargeScenery(); + + SetNewLargeSceneryElement(*newSceneryElement, tileNum, bannerId); + + if (tileNum == 0) + { + gSceneryTileElement = newTileElement; + } + map_invalidate_tile_full(curTile.x, curTile.y); + } + + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + res->Cost = (sceneryEntry->large_scenery.price * 10) + supportsCost; + return res; + } + +private: + int16_t GetTotalNumTiles(rct_large_scenery_tile * tiles) const + { + uint32_t totalNumTiles = 0; + for (rct_large_scenery_tile* tile = tiles; tile->x_offset != -1; tile++) + { + totalNumTiles++; + } + return totalNumTiles; + } + + int16_t GetMaxSurfaceHeight(rct_large_scenery_tile * tiles) const + { + int16_t maxHeight = -1; + for (rct_large_scenery_tile* tile = tiles; tile->x_offset != -1; tile++) + { + auto tempX = tile->x_offset; + auto tempY = tile->y_offset; + rotate_map_coordinates(&tempX, &tempY, _loc.direction); + CoordsXY curTile = { tempX, tempY }; + + curTile.x += _loc.x; + curTile.y += _loc.y; + + if (curTile.x >= 0x1FFF || curTile.y >= 0x1FFF || curTile.x < 0 || curTile.y < 0) + { + continue; + } + + TileElement* tileElement = map_get_surface_element_at({ curTile.x, curTile.y }); + if (tileElement != nullptr) + { + SurfaceElement* surfaceElement = tileElement->AsSurface(); + int32_t height = surfaceElement->base_height * 8; + int32_t slope = surfaceElement->GetSlope(); + + if (slope & 0xF) + { + height += 16; + if (slope & 0x10) + { + height += 16; + } + } + + if (height > maxHeight) + { + maxHeight = height; + } + } + } + return maxHeight; + } + + void SetNewLargeSceneryElement(LargeSceneryElement & sceneryElement, uint8_t tileNum, BannerIndex bannerId) const + { + sceneryElement.SetDirection(_loc.direction); + sceneryElement.SetEntryIndex(_sceneryType); + sceneryElement.SetSequenceIndex(tileNum); + sceneryElement.SetPrimaryColour(_primaryColour); + sceneryElement.SetSecondaryColour(_secondaryColour); + + if (bannerId != BANNER_INDEX_NULL) + { + sceneryElement.SetBannerIndex(bannerId); + } + + if (GetFlags() & GAME_COMMAND_FLAG_GHOST) + { + sceneryElement.SetGhost(true); + } + } +}; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index bc724828b5..4a529eb1f6 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -15,6 +15,7 @@ #include "../actions/FootpathPlaceFromTrackAction.hpp" #include "../actions/FootpathRemoveAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" +#include "../actions/LargeSceneryPlaceAction.hpp" #include "../actions/RideEntranceExitPlaceAction.hpp" #include "../actions/RideSetSetting.hpp" #include "../actions/RideSetVehiclesAction.hpp" @@ -887,6 +888,7 @@ static bool TrackDesignPlaceSceneryElement( break; } case OBJECT_TYPE_LARGE_SCENERY: + { if (mode != 0) { return true; @@ -917,15 +919,15 @@ static bool TrackDesignPlaceSceneryElement( flags = GAME_COMMAND_FLAG_PATH_SCENERY; } - cost = game_do_command( - mapCoord.x, flags | (rotation << 8), mapCoord.y, scenery->primary_colour | (scenery->secondary_colour << 8), - GAME_COMMAND_PLACE_LARGE_SCENERY, entry_index, z); + auto sceneryPlaceAction = LargeSceneryPlaceAction( + { mapCoord.x, mapCoord.y, z, rotation }, entry_index, scenery->primary_colour, scenery->secondary_colour); + sceneryPlaceAction.SetFlags(flags); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&sceneryPlaceAction) + : GameActions::Query(&sceneryPlaceAction); - if (cost == MONEY32_UNDEFINED) - { - cost = 0; - } + cost = res->Cost; break; + } case OBJECT_TYPE_WALLS: { if (mode != 0) diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 608b160195..1317a5831f 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1002,248 +1002,6 @@ bool map_is_location_at_edge(int32_t x, int32_t y) return x < 32 || y < 32 || x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32) || y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); } -/** - * - * rct2: 0x006B893C - */ -void game_command_place_large_scenery( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t x = (int16_t)*eax; - int32_t y = (int16_t)*ecx; - int32_t z = (int16_t)*ebp; - colour_t colour1 = *edx & TILE_ELEMENT_COLOUR_MASK; - colour_t colour2 = (*edx >> 8) & TILE_ELEMENT_COLOUR_MASK; - uint8_t flags = *ebx; - uint8_t rotation = *ebx >> 8; - uint8_t entry_index = *edi; - int32_t base_height = tile_element_height(x, y); - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = base_height; - gSceneryGroundFlags = 0; - BannerIndex banner_id = BANNER_INDEX_NULL; - money32 supportsCost = 0; - - if (game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (entry_index >= 128) - { - log_warning("Invalid game command for scenery placement, entry_index = %u", entry_index); - *ebx = MONEY32_UNDEFINED; - return; - } - - rct_scenery_entry* scenery_entry = get_large_scenery_entry(entry_index); - if (scenery_entry == nullptr) - { - log_warning("Invalid game command for scenery placement, entry_index = %u", entry_index); - *ebx = MONEY32_UNDEFINED; - return; - } - - if (scenery_entry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) - { - banner_id = create_new_banner(flags); - - if (banner_id == BANNER_INDEX_NULL) - { - *ebx = MONEY32_UNDEFINED; - return; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - rct_banner* banner = &gBanners[banner_id]; - banner->flags |= BANNER_FLAG_IS_LARGE_SCENERY; - banner->type = 0; - banner->x = x / 32; - banner->y = y / 32; - - ride_id_t rideIndex = banner_get_closest_ride_index(x, y, z); - if (rideIndex != RIDE_ID_NULL) - { - banner->ride_index = rideIndex; - banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; - } - } - } - - uint32_t num_elements = 0; - int16_t maxHeight = -1; - for (rct_large_scenery_tile* tile = scenery_entry->large_scenery.tiles; tile->x_offset != -1; tile++) - { - num_elements++; - - LocationXY16 curTile = { tile->x_offset, tile->y_offset }; - - rotate_map_coordinates(&curTile.x, &curTile.y, rotation); - - curTile.x += x; - curTile.y += y; - - if (curTile.x >= 0x1FFF || curTile.y >= 0x1FFF || curTile.x < 0 || curTile.y < 0) - { - continue; - } - - TileElement* tile_element = map_get_surface_element_at({ curTile.x, curTile.y }); - if (tile_element != nullptr) - { - int32_t height = tile_element->base_height * 8; - int32_t slope = tile_element->AsSurface()->GetSlope(); - - if (slope & 0xF) - { - height += 16; - if (slope & 0x10) - { - height += 16; - } - } - - if (height > maxHeight) - { - maxHeight = height; - } - } - } - - if (z != 0) - { - maxHeight = z; - } - - if (!map_check_free_elements_and_reorganise(num_elements)) - { - *ebx = MONEY32_UNDEFINED; - return; - } - - gCommandPosition.z = maxHeight; - uint8_t tile_num = 0; - for (rct_large_scenery_tile* tile = scenery_entry->large_scenery.tiles; tile->x_offset != -1; tile++, tile_num++) - { - LocationXY16 curTile = { tile->x_offset, tile->y_offset }; - - rotate_map_coordinates(&curTile.x, &curTile.y, rotation); - - curTile.x += x; - curTile.y += y; - - int32_t zLow = (tile->z_offset + maxHeight) / 8; - int32_t zHigh = (tile->z_clearance / 8) + zLow; - - QuarterTile quarterTile = QuarterTile{ static_cast(tile->flags >> 12), 0 }.Rotate(rotation); - if (!map_can_construct_with_clear_at( - curTile.x, curTile.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, flags, &supportsCost, - CREATE_CROSSING_MODE_NONE)) - { - *ebx = MONEY32_UNDEFINED; - return; - } - - if ((gMapGroundFlags & ELEMENT_IS_UNDERWATER) || (gMapGroundFlags & ELEMENT_IS_UNDERGROUND)) - { - *ebx = MONEY32_UNDEFINED; - return; - } - - int32_t b = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); - if (!gCheatsDisableClearanceChecks) - { - if (gSceneryGroundFlags && !(gSceneryGroundFlags & b)) - { - gGameCommandErrorText = STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND; - *ebx = MONEY32_UNDEFINED; - return; - } - } - gSceneryGroundFlags = b; - - if (curTile.x >= gMapSizeUnits || curTile.y >= gMapSizeUnits) - { - gGameCommandErrorText = STR_OFF_EDGE_OF_MAP; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned(curTile.x, curTile.y, zLow * 8) - && !gCheatsSandboxMode) - { - *ebx = MONEY32_UNDEFINED; - return; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (!(flags & GAME_COMMAND_FLAG_GHOST)) - { - footpath_remove_litter(curTile.x, curTile.y, zLow * 8); - if (!gCheatsDisableClearanceChecks) - { - wall_remove_at(curTile.x, curTile.y, zLow * 8, zHigh * 8); - } - } - if (gGameCommandNestLevel == 1 && !(*ebx & GAME_COMMAND_FLAG_GHOST)) - { - LocationXYZ16 coord; - coord.x = x + 16; - coord.y = y + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - TileElement* new_tile_element = tile_element_insert( - curTile.x / 32, curTile.y / 32, zLow, quarterTile.GetBaseQuarterOccupied()); - assert(new_tile_element != nullptr); - map_animation_create(MAP_ANIMATION_TYPE_LARGE_SCENERY, curTile.x, curTile.y, zLow); - - new_tile_element->clearance_height = zHigh; - new_tile_element->SetType(TILE_ELEMENT_TYPE_LARGE_SCENERY); - new_tile_element->SetDirection(rotation); - - auto newSceneryElement = new_tile_element->AsLargeScenery(); - newSceneryElement->SetEntryIndex(entry_index); - newSceneryElement->SetSequenceIndex(tile_num); - - newSceneryElement->SetPrimaryColour(colour1); - newSceneryElement->SetSecondaryColour(colour2); - - if (banner_id != BANNER_INDEX_NULL) - { - newSceneryElement->SetBannerIndex(banner_id); - } - - if (flags & GAME_COMMAND_FLAG_GHOST) - { - new_tile_element->SetGhost(true); - } - - if (tile_num == 0) - { - gSceneryTileElement = new_tile_element; - } - map_invalidate_tile_full(curTile.x, curTile.y); - } - } - - // Force ride construction to recheck area - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; - - *ebx = (scenery_entry->large_scenery.price * 10) + supportsCost; - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - *ebx = 0; - } -} - /** * * rct2: 0x0068B280 diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index b551f6752c..9bc2335d82 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -193,8 +193,6 @@ void game_command_remove_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_place_large_scenery( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_park_entrance( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_name( From 00cbd75641efadf1ca4fb191a302b88caf5a8343 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 5 Apr 2019 19:34:03 +0100 Subject: [PATCH 2/7] Return more useful error messages. Fix clearance checks always being on for underground placement --- src/openrct2-ui/windows/TopToolbar.cpp | 4 ++-- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 36e535df48..bbed23f703 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1889,14 +1889,14 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour); - sceneryPlaceAction.SetCallback([](const GameAction* ga, const GameActionResult* result) { + sceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { if (result->Error == GA_ERROR::OK) { audio_play_sound_at_location(SOUND_PLACE_ITEM, result->Position.x, result->Position.y, result->Position.z); } else { - audio_play_sound_at_location(SOUND_ERROR, result->Position.x, result->Position.y, result->Position.z); + audio_play_sound_at_location(SOUND_ERROR, loc.x, loc.y, gSceneryPlaceZ); } }); auto res = GameActions::Execute(&sceneryPlaceAction); diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index f54934d67e..ff205c7128 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -129,15 +129,14 @@ public: GA_ERROR::NO_CLEARANCE, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); } - if ((gMapGroundFlags & ELEMENT_IS_UNDERWATER) || (gMapGroundFlags & ELEMENT_IS_UNDERGROUND)) - { - log_error("Can't place object underwater / underground."); - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE); - } int32_t tempSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); if (!gCheatsDisableClearanceChecks) { + if ((gMapGroundFlags & ELEMENT_IS_UNDERWATER) || (gMapGroundFlags & ELEMENT_IS_UNDERGROUND)) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + } if (gSceneryGroundFlags && !(gSceneryGroundFlags & tempSceneryGroundFlags)) { return MakeResult( @@ -154,8 +153,7 @@ public: if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned(curTile.x, curTile.y, zLow * 8) && !gCheatsSandboxMode) { - log_error("Location not owned."); - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE); + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); } } From baad532c179e9578318afa3bbcf5994800fee5fe Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 08:01:22 +0100 Subject: [PATCH 3/7] Fix formatting --- src/openrct2-ui/windows/TopToolbar.cpp | 9 ++++++--- src/openrct2/Game.cpp | 3 +-- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 8 ++++++-- src/openrct2/ride/TrackDesign.cpp | 6 +++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index bbed23f703..abae61bc06 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1863,7 +1863,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo auto primaryColour = parameter_2 & 0xFF; auto secondaryColour = (parameter_2 >> 8) & 0xFF; auto largeSceneryType = parameter_3 & 0xFF; - CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; + uint8_t direction = (parameter_1 & 0xFF00) >> 8; + CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, direction }; auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour); @@ -1886,7 +1887,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo auto primaryColour = parameter_2 & 0xFF; auto secondaryColour = (parameter_2 >> 8) & 0xFF; auto largeSceneryType = parameter_3 & 0xFF; - CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; + uint8_t direction = (parameter_1 & 0xFF00) >> 8; + CoordsXYZD loc = { gridX, gridY, gSceneryPlaceZ, direction }; auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour); sceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { @@ -2562,7 +2564,8 @@ static money32 try_place_ghost_scenery( auto primaryColour = parameter_2 & 0xFF; auto secondaryColour = (parameter_2 >> 8) & 0xFF; auto sceneryType = parameter_3 & 0xFF; - CoordsXYZD loc = { map_tile.x, map_tile.y, gSceneryPlaceZ, (parameter_1 & 0xFF00) >> 8 }; + uint8_t direction = (parameter_1 & 0xFF00) >> 8; + CoordsXYZD loc = { map_tile.x, map_tile.y, gSceneryPlaceZ, direction }; auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, sceneryType, primaryColour, secondaryColour); sceneryPlaceAction.SetFlags( diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index bdd54f9fd2..6f6470aee0 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -408,8 +408,7 @@ int32_t game_do_command_p( gGameCommandNestLevel++; // Remove ghost scenery so it doesn't interfere with incoming network command - if ((flags & GAME_COMMAND_FLAG_NETWORKED) && !(flags & GAME_COMMAND_FLAG_GHOST) - && (command == GAME_COMMAND_PLACE_BANNER)) + if ((flags & GAME_COMMAND_FLAG_NETWORKED) && !(flags & GAME_COMMAND_FLAG_GHOST) && (command == GAME_COMMAND_PLACE_BANNER)) { scenery_remove_ghost_tool_placement(); } diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index ff205c7128..b72fb5161d 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -9,10 +9,13 @@ #pragma once +#include "../management/Finance.h" +#include "../object/ObjectLimits.h" #include "../ride/Ride.h" #include "../world/Banner.h" #include "../world/LargeScenery.h" #include "../world/MapAnimation.h" +#include "../world/Scenery.h" #include "GameAction.h" DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GAME_COMMAND_PLACE_LARGE_SCENERY, GameActionResult) @@ -62,7 +65,9 @@ public: if (_primaryColour > TILE_ELEMENT_COLOUR_MASK || _secondaryColour > TILE_ELEMENT_COLOUR_MASK) { - log_error("Invalid game command for scenery placement, primaryColour = %u, secondaryColour = %u", _primaryColour, _secondaryColour); + log_error( + "Invalid game command for scenery placement, primaryColour = %u, secondaryColour = %u", _primaryColour, + _secondaryColour); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); } @@ -129,7 +134,6 @@ public: GA_ERROR::NO_CLEARANCE, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); } - int32_t tempSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); if (!gCheatsDisableClearanceChecks) { diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 4a529eb1f6..559c3795c2 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -14,8 +14,8 @@ #include "../OpenRCT2.h" #include "../actions/FootpathPlaceFromTrackAction.hpp" #include "../actions/FootpathRemoveAction.hpp" -#include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/LargeSceneryPlaceAction.hpp" +#include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/RideEntranceExitPlaceAction.hpp" #include "../actions/RideSetSetting.hpp" #include "../actions/RideSetVehiclesAction.hpp" @@ -888,7 +888,7 @@ static bool TrackDesignPlaceSceneryElement( break; } case OBJECT_TYPE_LARGE_SCENERY: - { + { if (mode != 0) { return true; @@ -927,7 +927,7 @@ static bool TrackDesignPlaceSceneryElement( cost = res->Cost; break; - } + } case OBJECT_TYPE_WALLS: { if (mode != 0) From b7c3324baeea27d48062cb7d1590af1db01e2823 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 10:05:44 +0100 Subject: [PATCH 4/7] Include missing include --- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index b72fb5161d..1ee3190373 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -9,6 +9,7 @@ #pragma once +#include "../OpenRCT2.h" #include "../management/Finance.h" #include "../object/ObjectLimits.h" #include "../ride/Ride.h" From d40a22e32b363d61c2681c471e7c7a699d46de1e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 15:11:03 +0100 Subject: [PATCH 5/7] Make suggested changes --- .../actions/LargeSceneryPlaceAction.hpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 1ee3190373..29cbae6963 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -324,25 +324,25 @@ private: } TileElement* tileElement = map_get_surface_element_at({ curTile.x, curTile.y }); - if (tileElement != nullptr) - { - SurfaceElement* surfaceElement = tileElement->AsSurface(); - int32_t height = surfaceElement->base_height * 8; - int32_t slope = surfaceElement->GetSlope(); + if (tileElement == nullptr) + continue; + + SurfaceElement* surfaceElement = tileElement->AsSurface(); + int32_t height = surfaceElement->base_height * 8; + int32_t slope = surfaceElement->GetSlope(); - if (slope & 0xF) + if (slope & 0xF) + { + height += 16; + if (slope & 0x10) { height += 16; - if (slope & 0x10) - { - height += 16; - } } + } - if (height > maxHeight) - { - maxHeight = height; - } + if (height > maxHeight) + { + maxHeight = height; } } return maxHeight; From d6522f0aee6f1f36bb5fc6eb068421018e0ceaca Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 15:24:07 +0100 Subject: [PATCH 6/7] Fix formatting --- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index abae61bc06..7ad88c914d 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 29cbae6963..80111a85cf 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -326,7 +326,7 @@ private: TileElement* tileElement = map_get_surface_element_at({ curTile.x, curTile.y }); if (tileElement == nullptr) continue; - + SurfaceElement* surfaceElement = tileElement->AsSurface(); int32_t height = surfaceElement->base_height * 8; int32_t slope = surfaceElement->GetSlope(); From 2e104a00c8ddba616b6d5f2f28b5de5ad6a3f279 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 17:04:11 +0100 Subject: [PATCH 7/7] 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 b564311839..c16b37d00a 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -31,7 +31,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 "16" +#define NETWORK_STREAM_VERSION "17" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr;