From e7d875dd04d8ea0a3b197a946b51fd7ebda577de Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 08:55:21 +0100 Subject: [PATCH 001/506] Always link threads, fix linking cURL Threads are currently used throughout the codebase so they need to be required. CURL is required when using HTTP, not when using Networking. --- src/openrct2/CMakeLists.txt | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index 157120fa15..a92365633e 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -34,14 +34,20 @@ else () endif () endif () -# Third party libraries (optional) -if (NOT DISABLE_HTTP_TWITCH OR NOT DISABLE_NETWORK) +if (NOT DISABLE_HTTP) if (MSVC) find_package(curl REQUIRED) set(LIBCURL_LIBRARIES ${CURL_LIBRARIES}) else () PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) endif () + if (STATIC) + target_link_libraries(${PROJECT} ${LIBCURL_STATIC_LIBRARIES} + ${SSL_STATIC_LIBRARIES}) + else () + target_link_libraries(${PROJECT} ${LIBCURL_LIBRARIES} + ${OPENSSL_LIBRARIES}) + endif () endif () if (NOT DISABLE_NETWORK) find_package(OpenSSL 1.0.0 REQUIRED) @@ -107,21 +113,12 @@ if (NOT DISABLE_NETWORK) if (WIN32) target_link_libraries(${PROJECT} ws2_32 crypt32 wldap32 version winmm imm32 advapi32 shell32 ole32) endif () - - # our HTTP implementation requires use of threads - set(THREADS_PREFER_PTHREAD_FLAG ON) - find_package(Threads REQUIRED) - target_link_libraries(${PROJECT} Threads::Threads) - - if (STATIC) - target_link_libraries(${PROJECT} ${LIBCURL_STATIC_LIBRARIES} - ${SSL_STATIC_LIBRARIES}) - else () - target_link_libraries(${PROJECT} ${LIBCURL_LIBRARIES} - ${OPENSSL_LIBRARIES}) - endif () endif () +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(${PROJECT} Threads::Threads) + if (NOT MINGW AND NOT MSVC) # For unicode code page conversion. find_package(ICU 59.0 REQUIRED COMPONENTS uc) From 73c8a0a4a8529f5fcd2e1758a884af155ed5eae5 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 09:20:25 +0100 Subject: [PATCH 002/506] Require curl include when not DISABLE_HTTP --- src/openrct2/CMakeLists.txt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index a92365633e..4ccd79a186 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -34,6 +34,14 @@ else () endif () endif () +if (NOT DISABLE_NETWORK AND NOT DISABLE_HTTP) + find_package(OpenSSL 1.0.0 REQUIRED) +endif () + +if (NOT DISABLE_NETWORK AND WIN32) + target_link_libraries(${PROJECT} ws2_32 crypt32 wldap32 version winmm imm32 advapi32 shell32 ole32) +endif () + if (NOT DISABLE_HTTP) if (MSVC) find_package(curl REQUIRED) @@ -49,9 +57,6 @@ if (NOT DISABLE_HTTP) ${OPENSSL_LIBRARIES}) endif () endif () -if (NOT DISABLE_NETWORK) - find_package(OpenSSL 1.0.0 REQUIRED) -endif () find_package(benchmark 1.4 QUIET) @@ -109,12 +114,6 @@ if (UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD") target_link_libraries(${PROJECT} dl) endif () -if (NOT DISABLE_NETWORK) - if (WIN32) - target_link_libraries(${PROJECT} ws2_32 crypt32 wldap32 version winmm imm32 advapi32 shell32 ole32) - endif () -endif () - set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(${PROJECT} Threads::Threads) @@ -159,7 +158,7 @@ target_include_directories(${PROJECT} PRIVATE ${LIBZIP_INCLUDE_DIRS}) target_include_directories(${PROJECT} PUBLIC ${JANSSON_INCLUDE_DIRS}) target_include_directories(${PROJECT} PRIVATE ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}) -if (NOT DISABLE_HTTP_TWITCH OR NOT DISABLE_NETWORK) +if (NOT DISABLE_HTTP) target_include_directories(${PROJECT} PRIVATE ${LIBCURL_INCLUDE_DIRS}) endif () if (NOT DISABLE_NETWORK) From 49d36926b4dec0e5bd3a53db3a829a436bd0ed40 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 09:21:19 +0100 Subject: [PATCH 003/506] Move find_package benchmark to appropriate place --- src/openrct2/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index 4ccd79a186..ad113fb73f 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -58,8 +58,6 @@ if (NOT DISABLE_HTTP) endif () endif () -find_package(benchmark 1.4 QUIET) - if (NOT DISABLE_TTF) if (UNIX AND NOT APPLE AND NOT MSVC) PKG_CHECK_MODULES(FONTCONFIG REQUIRED fontconfig) @@ -87,6 +85,7 @@ add_library(${PROJECT} ${OPENRCT2_CORE_SOURCES} ${OPENRCT2_CORE_MM_SOURCES} ${RC set_target_properties(${PROJECT} PROPERTIES PREFIX "") SET_CHECK_CXX_FLAGS(${PROJECT}) +find_package(benchmark 1.4 QUIET) if (benchmark_FOUND) message("Found Google benchmark, enabling support") set_target_properties(${PROJECT} PROPERTIES COMPILE_DEFINITIONS USE_BENCHMARK) From 44d47833091275afa69c8bff9498c70c729784e8 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 09:23:13 +0100 Subject: [PATCH 004/506] Split linking cURL and SSL --- src/openrct2/CMakeLists.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index ad113fb73f..fee9a053bb 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -34,8 +34,13 @@ else () endif () endif () -if (NOT DISABLE_NETWORK AND NOT DISABLE_HTTP) +if (NOT DISABLE_NETWORK OR NOT DISABLE_HTTP) find_package(OpenSSL 1.0.0 REQUIRED) + if(STATIC) + target_link_libraries(${PROJECT} ${SSL_STATIC_LIBRARIES}) + else () + target_link_libraries(${PROJECT} ${OPENSSL_LIBRARIES}) + endif() endif () if (NOT DISABLE_NETWORK AND WIN32) @@ -50,11 +55,9 @@ if (NOT DISABLE_HTTP) PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) endif () if (STATIC) - target_link_libraries(${PROJECT} ${LIBCURL_STATIC_LIBRARIES} - ${SSL_STATIC_LIBRARIES}) + target_link_libraries(${PROJECT} ${LIBCURL_STATIC_LIBRARIES}) else () - target_link_libraries(${PROJECT} ${LIBCURL_LIBRARIES} - ${OPENSSL_LIBRARIES}) + target_link_libraries(${PROJECT} ${LIBCURL_LIBRARIES}) endif () endif () From 68eec6bb5d455fb58c1956b933c797d6387e0cab Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 09:24:54 +0100 Subject: [PATCH 005/506] Include OpenSSL when not DISABLE_NETWORK/DISABLE_HTTP --- src/openrct2/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index fee9a053bb..0e4eaaa4f8 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -163,7 +163,7 @@ target_include_directories(${PROJECT} PRIVATE ${PNG_INCLUDE_DIRS} if (NOT DISABLE_HTTP) target_include_directories(${PROJECT} PRIVATE ${LIBCURL_INCLUDE_DIRS}) endif () -if (NOT DISABLE_NETWORK) +if (NOT DISABLE_NETWORK OR NOT DISABLE_HTTP) target_include_directories(${PROJECT} PUBLIC ${OPENSSL_INCLUDE_DIR}) endif () if (NOT DISABLE_TTF) From c951118eb047924c9d5d5f44145463e0b9812a1f Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 09:48:04 +0100 Subject: [PATCH 006/506] Corrected order of finding and linking --- src/openrct2/CMakeLists.txt | 203 ++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 102 deletions(-) diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index 0e4eaaa4f8..29831bc446 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -1,12 +1,86 @@ -# CMAKE project for libopenrct2 (core OpenRCT2 component) cmake_minimum_required(VERSION 3.9) +project(libopenrct2 CXX) + if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt") endif () -# Needed for linking with non-broken OpenSSL on Apple platforms +file(GLOB_RECURSE OPENRCT2_CORE_SOURCES "${CMAKE_CURRENT_LIST_DIR}/*.cpp") +file(GLOB_RECURSE OPENRCT2_CORE_HEADERS "${CMAKE_CURRENT_LIST_DIR}/*.h" + "${CMAKE_CURRENT_LIST_DIR}/*.hpp") if (APPLE) - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/openssl/lib/pkgconfig") + file(GLOB_RECURSE OPENRCT2_CORE_MM_SOURCES "${CMAKE_CURRENT_LIST_DIR}/*.mm") + set_source_files_properties(${OPENRCT2_CORE_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c++ -fmodules") +endif () + +add_library(${PROJECT_NAME} ${OPENRCT2_CORE_SOURCES} ${OPENRCT2_CORE_MM_SOURCES} ${RCT2_SECTIONS}) +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") +SET_CHECK_CXX_FLAGS(${PROJECT_NAME}) + +if (NOT DISABLE_NETWORK OR NOT DISABLE_HTTP) + if (APPLE) + # Needed for linking with non-broken OpenSSL on Apple platforms + set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/openssl/lib/pkgconfig") + endif () + + find_package(OpenSSL 1.0.0 REQUIRED) + + target_include_directories(${PROJECT_NAME} PUBLIC ${OPENSSL_INCLUDE_DIR}) + + if(STATIC) + target_link_libraries(${PROJECT_NAME} ${SSL_STATIC_LIBRARIES}) + else () + target_link_libraries(${PROJECT_NAME} ${OPENSSL_LIBRARIES}) + endif() +endif () + +if (NOT DISABLE_NETWORK AND WIN32) + target_link_libraries(${PROJECT_NAME} ws2_32 crypt32 wldap32 version winmm imm32 advapi32 shell32 ole32) +endif () + +if (NOT DISABLE_HTTP) + if (MSVC) + find_package(curl REQUIRED) + set(LIBCURL_LIBRARIES ${CURL_LIBRARIES}) + else () + PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) + endif () + + target_include_directories(${PROJECT_NAME} PRIVATE ${LIBCURL_INCLUDE_DIRS}) + + if (STATIC) + target_link_libraries(${PROJECT_NAME} ${LIBCURL_STATIC_LIBRARIES}) + else () + target_link_libraries(${PROJECT_NAME} ${LIBCURL_LIBRARIES}) + endif () +endif () + +if (NOT DISABLE_TTF) + if (UNIX AND NOT APPLE AND NOT MSVC) + PKG_CHECK_MODULES(FONTCONFIG REQUIRED fontconfig) + endif () + + if (MSVC) + find_package(freetype REQUIRED) + else () + PKG_CHECK_MODULES(FREETYPE REQUIRED freetype2) + endif () + + target_include_directories(${PROJECT_NAME} PRIVATE ${FREETYPE_INCLUDE_DIRS}) + + if (UNIX AND NOT APPLE) + target_include_directories(${PROJECT_NAME} PRIVATE ${FONTCONFIG_INCLUDE_DIRS}) + endif () +endif () + +find_package(benchmark 1.4 QUIET) +if (benchmark_FOUND) + message("Found Google benchmark, enabling support") + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS USE_BENCHMARK) + target_link_libraries(${PROJECT_NAME} benchmark::benchmark) + target_include_directories(${PROJECT_NAME} PRIVATE ${benchmark_INCLUDE_DIRS}) +else () + message("Google benchmark not found, disabling support") endif () # Third party libraries @@ -34,78 +108,13 @@ else () endif () endif () -if (NOT DISABLE_NETWORK OR NOT DISABLE_HTTP) - find_package(OpenSSL 1.0.0 REQUIRED) - if(STATIC) - target_link_libraries(${PROJECT} ${SSL_STATIC_LIBRARIES}) - else () - target_link_libraries(${PROJECT} ${OPENSSL_LIBRARIES}) - endif() -endif () - -if (NOT DISABLE_NETWORK AND WIN32) - target_link_libraries(${PROJECT} ws2_32 crypt32 wldap32 version winmm imm32 advapi32 shell32 ole32) -endif () - -if (NOT DISABLE_HTTP) - if (MSVC) - find_package(curl REQUIRED) - set(LIBCURL_LIBRARIES ${CURL_LIBRARIES}) - else () - PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) - endif () - if (STATIC) - target_link_libraries(${PROJECT} ${LIBCURL_STATIC_LIBRARIES}) - else () - target_link_libraries(${PROJECT} ${LIBCURL_LIBRARIES}) - endif () -endif () - -if (NOT DISABLE_TTF) - if (UNIX AND NOT APPLE AND NOT MSVC) - PKG_CHECK_MODULES(FONTCONFIG REQUIRED fontconfig) - endif () - if (MSVC) - find_package(freetype REQUIRED) - else () - PKG_CHECK_MODULES(FREETYPE REQUIRED freetype2) - endif () -endif () - -# Sources -file(GLOB_RECURSE OPENRCT2_CORE_SOURCES "${CMAKE_CURRENT_LIST_DIR}/*.cpp") -file(GLOB_RECURSE OPENRCT2_CORE_HEADERS "${CMAKE_CURRENT_LIST_DIR}/*.h" - "${CMAKE_CURRENT_LIST_DIR}/*.hpp") -if (APPLE) - file(GLOB_RECURSE OPENRCT2_CORE_MM_SOURCES "${CMAKE_CURRENT_LIST_DIR}/*.mm") - set_source_files_properties(${OPENRCT2_CORE_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c++ -fmodules") -endif () - -# Outputs -set(PROJECT libopenrct2) -project(${PROJECT} CXX) -add_library(${PROJECT} ${OPENRCT2_CORE_SOURCES} ${OPENRCT2_CORE_MM_SOURCES} ${RCT2_SECTIONS}) -set_target_properties(${PROJECT} PROPERTIES PREFIX "") -SET_CHECK_CXX_FLAGS(${PROJECT}) - -find_package(benchmark 1.4 QUIET) -if (benchmark_FOUND) - message("Found Google benchmark, enabling support") - set_target_properties(${PROJECT} PROPERTIES COMPILE_DEFINITIONS USE_BENCHMARK) - target_link_libraries(${PROJECT} benchmark::benchmark) - target_include_directories(${PROJECT} PRIVATE ${benchmark_INCLUDE_DIRS}) -else () - message("Google benchmark not found, disabling support") -endif () - -# Libraries if (STATIC) - target_link_libraries(${PROJECT} ${JANSSON_STATIC_LIBRARIES} + target_link_libraries(${PROJECT_NAME} ${JANSSON_STATIC_LIBRARIES} ${PNG_STATIC_LIBRARIES} ${ZLIB_STATIC_LIBRARIES} ${LIBZIP_STATIC_LIBRARIES}) else () - target_link_libraries(${PROJECT} ${JANSSON_LIBRARIES} + target_link_libraries(${PROJECT_NAME} ${JANSSON_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBZIP_LIBRARIES}) @@ -113,20 +122,23 @@ endif () if (UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD") # Include libdl for dlopen - target_link_libraries(${PROJECT} dl) + target_link_libraries(${PROJECT_NAME} dl) endif () set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -target_link_libraries(${PROJECT} Threads::Threads) +target_link_libraries(${PROJECT_NAME} Threads::Threads) if (NOT MINGW AND NOT MSVC) # For unicode code page conversion. find_package(ICU 59.0 REQUIRED COMPONENTS uc) + + target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${ICU_INCLUDE_DIRS}) + if (STATIC) - target_link_libraries(${PROJECT} ${ICU_STATIC_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${ICU_STATIC_LIBRARIES}) else () - target_link_libraries(${PROJECT} ${ICU_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${ICU_LIBRARIES}) endif () endif () @@ -134,19 +146,21 @@ if (NOT APPLE AND NOT MINGW AND NOT MSVC) # This is ugly hack to work around https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899. # Once C++17 is enabled (and thus old compilers are no longer supported, this needs to be gone. # We cannot simply detect the _compiler_ version, as the bug exists with the C++ _library_ - target_link_libraries(${PROJECT} gcc_s gcc) + target_link_libraries(${PROJECT_NAME} gcc_s gcc) endif () if (NOT DISABLE_TTF) if (STATIC) - target_link_libraries(${PROJECT} ${FREETYPE_STATIC_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${FREETYPE_STATIC_LIBRARIES}) + if (UNIX AND NOT APPLE) - target_link_libraries(${PROJECT} ${FONTCONFIG_STATIC_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${FONTCONFIG_STATIC_LIBRARIES}) endif () else () - target_link_libraries(${PROJECT} ${FREETYPE_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${FREETYPE_LIBRARIES}) + if (UNIX AND NOT APPLE) - target_link_libraries(${PROJECT} ${FONTCONFIG_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} ${FONTCONFIG_LIBRARIES}) endif () endif () endif () @@ -156,25 +170,10 @@ if (HAVE_DISCORD_RPC) endif() # Includes -target_include_directories(${PROJECT} PRIVATE ${LIBZIP_INCLUDE_DIRS}) -target_include_directories(${PROJECT} PUBLIC ${JANSSON_INCLUDE_DIRS}) -target_include_directories(${PROJECT} PRIVATE ${PNG_INCLUDE_DIRS} +target_include_directories(${PROJECT_NAME} PRIVATE ${LIBZIP_INCLUDE_DIRS}) +target_include_directories(${PROJECT_NAME} PUBLIC ${JANSSON_INCLUDE_DIRS}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}) -if (NOT DISABLE_HTTP) - target_include_directories(${PROJECT} PRIVATE ${LIBCURL_INCLUDE_DIRS}) -endif () -if (NOT DISABLE_NETWORK OR NOT DISABLE_HTTP) - target_include_directories(${PROJECT} PUBLIC ${OPENSSL_INCLUDE_DIR}) -endif () -if (NOT DISABLE_TTF) - target_include_directories(${PROJECT} PRIVATE ${FREETYPE_INCLUDE_DIRS}) - if (UNIX AND NOT APPLE) - target_include_directories(${PROJECT} PRIVATE ${FONTCONFIG_INCLUDE_DIRS}) - endif () -endif () -if (NOT MINGW AND NOT MSVC) - target_include_directories(${PROJECT} SYSTEM PRIVATE ${ICU_INCLUDE_DIRS}) -endif () # To avoid unnecessary rebuilds set the current branch and # short sha1 only for the two files that use these @@ -205,13 +204,13 @@ endif() # - GCC 8 does not support -Wno-pragma-once-outside-header # - Other compilers status unknown if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_library(${PROJECT}-headers-check OBJECT ${OPENRCT2_CORE_HEADERS}) - set_target_properties(${PROJECT}-headers-check PROPERTIES LINKER_LANGUAGE CXX) + add_library(${PROJECT_NAME}-headers-check OBJECT ${OPENRCT2_CORE_HEADERS}) + set_target_properties(${PROJECT_NAME}-headers-check PROPERTIES LINKER_LANGUAGE CXX) set_source_files_properties(${OPENRCT2_CORE_HEADERS} PROPERTIES LANGUAGE CXX) add_definitions("-x c++ -Wno-pragma-once-outside-header -Wno-unused-const-variable") - get_target_property(LIBOPENRCT2_INCLUDE_DIRS ${PROJECT} INCLUDE_DIRECTORIES) - set_target_properties(${PROJECT}-headers-check PROPERTIES INCLUDE_DIRECTORIES "${LIBOPENRCT2_INCLUDE_DIRS}") + get_target_property(LIBOPENRCT2_INCLUDE_DIRS ${PROJECT_NAME} INCLUDE_DIRECTORIES) + set_target_properties(${PROJECT_NAME}-headers-check PROPERTIES INCLUDE_DIRECTORIES "${LIBOPENRCT2_INCLUDE_DIRS}") else () # Dummy target to ease invocation - add_custom_target(${PROJECT}-headers-check) + add_custom_target(${PROJECT_NAME}-headers-check) endif () From 0070283dc2ea01e058df880684d12d5cf2fdff43 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 5 Mar 2019 19:54:17 +0000 Subject: [PATCH 007/506] Implement game action --- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 4 +- .../actions/FootpathPlaceFromTrackAction.hpp | 285 ++++++++++++++++++ .../actions/GameActionRegistration.cpp | 2 + src/openrct2/ride/TrackDesign.cpp | 19 +- src/openrct2/world/Footpath.cpp | 170 ----------- src/openrct2/world/Footpath.h | 2 - 7 files changed, 300 insertions(+), 184 deletions(-) create mode 100644 src/openrct2/actions/FootpathPlaceFromTrackAction.hpp diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 7a46e8b733..fc38e1bb4b 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1278,7 +1278,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_place_footpath_from_track, + nullptr, nullptr, game_command_change_surface_style, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 99961ed78e..35bdde7acc 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -36,8 +36,8 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_SCENERY, // GA GAME_COMMAND_SET_WATER_HEIGHT, // GA GAME_COMMAND_PLACE_PATH, // GA - GAME_COMMAND_PLACE_PATH_FROM_TRACK, - GAME_COMMAND_REMOVE_PATH, // GA + GAME_COMMAND_PLACE_PATH_FROM_TRACK, // GA + GAME_COMMAND_REMOVE_PATH, // GA GAME_COMMAND_CHANGE_SURFACE_STYLE, GAME_COMMAND_SET_RIDE_PRICE, // GA GAME_COMMAND_SET_GUEST_NAME, // GA diff --git a/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp b/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp new file mode 100644 index 0000000000..41f4e50c19 --- /dev/null +++ b/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp @@ -0,0 +1,285 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../OpenRCT2.h" +#include "../core/MemoryStream.h" +#include "../interface/Window.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../world/Footpath.h" +#include "../world/Location.hpp" +#include "../world/Park.h" +#include "../world/Surface.h" +#include "../world/Wall.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(FootpathPlaceFromTrackAction, GAME_COMMAND_PLACE_PATH_FROM_TRACK, GameActionResult) +{ +private: + CoordsXYZ _loc; + uint8_t _slope; + uint8_t _type; + uint8_t _edges; + +public: + FootpathPlaceFromTrackAction() = default; + FootpathPlaceFromTrackAction(CoordsXYZ loc, uint8_t slope, uint8_t type, uint8_t edges) + : _loc(loc) + , _slope(slope) + , _type(type) + , _edges(edges) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_slope) << DS_TAG(_type) << DS_TAG(_edges); + } + + GameActionResult::Ptr Query() const override + { + GameActionResult::Ptr res = std::make_unique(); + res->Cost = 0; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position = _loc; + res->Position.x += 16; + res->Position.y += 16; + + gFootpathGroundFlags = 0; + + if (map_is_edge({ _loc.x, _loc.y })) + { + return MakeResult( + GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_OFF_EDGE_OF_MAP); + } + + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode) + && !map_is_location_owned(_loc.x, _loc.y, _loc.z)) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + } + + if (_loc.z / 8 < 2) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_LOW); + } + + if (_loc.z / 8 > 248) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_HIGH); + } + + return ElementInsertQuery(std::move(res)); + } + + GameActionResult::Ptr Execute() const override + { + GameActionResult::Ptr res = std::make_unique(); + res->Cost = 0; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position = _loc; + res->Position.x += 16; + res->Position.y += 16; + + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + { + footpath_interrupt_peeps(_loc.x, _loc.y, _loc.z); + } + + gFootpathGroundFlags = 0; + + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + return ElementInsertExecute(std::move(res)); + } + +private: + GameActionResult::Ptr ElementInsertQuery(GameActionResult::Ptr res) const + { + bool entrancePath = false, entranceIsSamePath = false; + + if (!map_check_free_elements_and_reorganise(1)) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE); + } + + res->Cost = MONEY(12, 00); + + QuarterTile quarterTile{ 0b1111, 0 }; + auto zLow = _loc.z / 8; + auto zHigh = zLow + 4; + if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED) + { + quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & TILE_ELEMENT_DIRECTION_MASK); + zHigh += 2; + } + + auto entranceElement = map_get_park_entrance_element_at(_loc.x, _loc.y, zLow, false); + // Make sure the entrance part is the middle + if (entranceElement != nullptr && (entranceElement->GetSequenceIndex()) == 0) + { + entrancePath = true; + // Make the price the same as replacing a path + if (entranceElement->GetPathType() == (_type & 0xF)) + entranceIsSamePath = true; + else + res->Cost -= MONEY(6, 00); + } + + // Do not attempt to build a crossing with a queue or a sloped. + uint8_t crossingMode = (_type & FOOTPATH_ELEMENT_INSERT_QUEUE) || (_slope != TILE_ELEMENT_SLOPE_FLAT) + ? CREATE_CROSSING_MODE_NONE + : CREATE_CROSSING_MODE_PATH_OVER_TRACK; + if (!entrancePath + && !map_can_construct_with_clear_at( + _loc.x, _loc.y, zLow, zHigh, &map_place_non_scenery_clear_func, quarterTile, GetFlags(), &res->Cost, + crossingMode)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText, + gCommonFormatArgs); + } + + gFootpathGroundFlags = gMapGroundFlags; + if (!gCheatsDisableClearanceChecks && (gMapGroundFlags & ELEMENT_IS_UNDERWATER)) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + } + + auto tileElement = map_get_surface_element_at({ _loc.x, _loc.y }); + if (tileElement == nullptr) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE); + } + auto surfaceElement = tileElement->AsSurface(); + int32_t supportHeight = zLow - surfaceElement->base_height; + res->Cost += supportHeight < 0 ? MONEY(20, 00) : (supportHeight / 2) * MONEY(5, 00); + + // Prevent the place sound from being spammed + if (entranceIsSamePath) + res->Cost = 0; + + return res; + } + + GameActionResult::Ptr ElementInsertExecute(GameActionResult::Ptr res) const + { + bool entrancePath = false, entranceIsSamePath = false; + + if (!(GetFlags() & (GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST))) + { + footpath_remove_litter(_loc.x, _loc.y, _loc.z); + } + + res->Cost = MONEY(12, 00); + + QuarterTile quarterTile{ 0b1111, 0 }; + auto zLow = _loc.z / 8; + auto zHigh = zLow + 4; + if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED) + { + quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & TILE_ELEMENT_DIRECTION_MASK); + zHigh += 2; + } + + auto entranceElement = map_get_park_entrance_element_at(_loc.x, _loc.y, zLow, false); + // Make sure the entrance part is the middle + if (entranceElement != nullptr && (entranceElement->GetSequenceIndex()) == 0) + { + entrancePath = true; + // Make the price the same as replacing a path + if (entranceElement->GetPathType() == (_type & 0xF)) + entranceIsSamePath = true; + else + res->Cost -= MONEY(6, 00); + } + + // Do not attempt to build a crossing with a queue or a sloped. + uint8_t crossingMode = (_type & FOOTPATH_ELEMENT_INSERT_QUEUE) || (_slope != TILE_ELEMENT_SLOPE_FLAT) + ? CREATE_CROSSING_MODE_NONE + : CREATE_CROSSING_MODE_PATH_OVER_TRACK; + if (!entrancePath + && !map_can_construct_with_clear_at( + _loc.x, _loc.y, zLow, zHigh, &map_place_non_scenery_clear_func, quarterTile, + GAME_COMMAND_FLAG_APPLY | GetFlags(), &res->Cost, crossingMode)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText, + gCommonFormatArgs); + } + + gFootpathGroundFlags = gMapGroundFlags; + + auto tileElement = map_get_surface_element_at({ _loc.x, _loc.y }); + if (tileElement == nullptr) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE); + } + auto surfaceElement = tileElement->AsSurface(); + int32_t supportHeight = zLow - surfaceElement->base_height; + res->Cost += supportHeight < 0 ? MONEY(20, 00) : (supportHeight / 2) * MONEY(5, 00); + + if (entrancePath) + { + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath) + { + // Set the path type but make sure it's not a queue as that will not show up + entranceElement->SetPathType(_type & 0x7F); + map_invalidate_tile_full(_loc.x, _loc.y); + } + } + else + { + tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, zLow, 0b1111); + assert(tileElement != nullptr); + tileElement->SetType(TILE_ELEMENT_TYPE_PATH); + PathElement* pathElement = tileElement->AsPath(); + pathElement->clearance_height = zHigh; + pathElement->SetPathEntryIndex(_type); + pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK); + if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED) + { + pathElement->SetSloped(true); + } + if (_type & FOOTPATH_ELEMENT_INSERT_QUEUE) + { + pathElement->SetIsQueue(true); + } + pathElement->SetAddition(0); + pathElement->SetRideIndex(RIDE_ID_NULL); + pathElement->SetAdditionStatus(255); + pathElement->SetIsBroken(false); + pathElement->SetEdges(_edges); + pathElement->SetCorners(0); + if (GetFlags() & GAME_COMMAND_FLAG_GHOST) + { + pathElement->SetGhost(true); + } + map_invalidate_tile_full(_loc.x, _loc.y); + } + + // Prevent the place sound from being spammed + if (entranceIsSamePath) + res->Cost = 0; + + return res; + } +}; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index c24a8e0a7f..fa705b1681 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -11,6 +11,7 @@ #include "ClearAction.hpp" #include "ClimateSetAction.hpp" #include "FootpathPlaceAction.hpp" +#include "FootpathPlaceFromTrackAction.hpp" #include "FootpathRemoveAction.hpp" #include "FootpathSceneryPlaceAction.hpp" #include "FootpathSceneryRemoveAction.hpp" @@ -59,6 +60,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 049c03e316..54eff77a42 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -12,6 +12,7 @@ #include "../Cheats.h" #include "../Game.h" #include "../OpenRCT2.h" +#include "../actions/FootpathPlaceFromTrackAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/RideEntranceExitPlaceAction.hpp" #include "../actions/RideSetSetting.hpp" @@ -1098,15 +1099,15 @@ static int32_t track_design_place_scenery( flags = 0; } - gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; - cost = game_do_command( - mapCoord.x, flags | (bh << 8), mapCoord.y, z | (entry_index << 8), - GAME_COMMAND_PLACE_PATH_FROM_TRACK, 0, 0); - - if (cost == MONEY32_UNDEFINED) - { - cost = 0; - } + uint8_t slope = ((bh >> 5) & 0x3) | ((bh >> 2) & 0x4); + uint8_t edges = bh & 0xF; + auto footpathPlaceAction = FootpathPlaceFromTrackAction( + { mapCoord.x, mapCoord.y, z * 8 }, slope, entry_index, edges); + footpathPlaceAction.SetFlags(flags); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&footpathPlaceAction) + : GameActions::QueryNested(&footpathPlaceAction); + // Ignore failures + cost = res->Error == GA_ERROR::OK ? res->Cost : 0; } else { diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 7222e6bf9e..801e679203 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -124,11 +124,6 @@ TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z) return nullptr; } -/** rct2: 0x0098D7EC */ -static constexpr const QuarterTile SlopedFootpathQuarterTiles[] = { - { 0b1111, 0b1100 }, { 0b1111, 0b1001 }, { 0b1111, 0b0011 }, { 0b1111, 0b0110 } -}; - /** * * rct2: 0x006BA23E @@ -148,171 +143,6 @@ void remove_banners_at_element(int32_t x, int32_t y, TileElement* tileElement) } } -static money32 footpath_place_from_track( - int32_t type, int32_t x, int32_t y, int32_t z, int32_t slope, int32_t edges, int32_t flags) -{ - TileElement* tileElement; - EntranceElement* entranceElement; - bool entrancePath = false, entranceIsSamePath = false; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z * 8; - - if (!(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - return MONEY32_UNDEFINED; - } - - if ((flags & GAME_COMMAND_FLAG_APPLY) && !(flags & GAME_COMMAND_FLAG_GHOST)) - footpath_interrupt_peeps(x, y, z * 8); - - gFootpathPrice = 0; - gFootpathGroundFlags = 0; - - if (!map_is_location_owned(x, y, z * 8) && !gCheatsSandboxMode) - { - return MONEY32_UNDEFINED; - } - - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode) && !map_is_location_owned(x, y, z * 8)) - return MONEY32_UNDEFINED; - - if (z < 2) - { - gGameCommandErrorText = STR_TOO_LOW; - return MONEY32_UNDEFINED; - } - - if (z > 248) - { - gGameCommandErrorText = STR_TOO_HIGH; - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (!(flags & (GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST))) - { - footpath_remove_litter(x, y, z * 8); - } - } - - gFootpathPrice += 120; - QuarterTile quarterTile = { 0b1111, 0 }; - int32_t zHigh = z + 4; - if (slope & TILE_ELEMENT_SLOPE_S_CORNER_UP) - { - quarterTile = SlopedFootpathQuarterTiles[slope & TILE_ELEMENT_SLOPE_NE_SIDE_UP]; - zHigh += 2; - } - - entranceElement = map_get_park_entrance_element_at(x, y, z, false); - // Make sure the entrance part is the middle - if (entranceElement != nullptr && (entranceElement->GetSequenceIndex()) == 0) - { - entrancePath = true; - // Make the price the same as replacing a path - if (entranceElement->GetPathType() == (type & 0xF)) - entranceIsSamePath = true; - else - gFootpathPrice -= MONEY(6, 00); - } - - // Do not attempt to build a crossing with a queue or a sloped. - uint8_t crossingMode = (type & FOOTPATH_ELEMENT_INSERT_QUEUE) || (slope != TILE_ELEMENT_SLOPE_FLAT) - ? CREATE_CROSSING_MODE_NONE - : CREATE_CROSSING_MODE_PATH_OVER_TRACK; - if (!entrancePath - && !map_can_construct_with_clear_at( - x, y, z, zHigh, &map_place_non_scenery_clear_func, quarterTile, flags, &gFootpathPrice, crossingMode)) - return MONEY32_UNDEFINED; - - gFootpathGroundFlags = gMapGroundFlags; - if (!gCheatsDisableClearanceChecks && (gMapGroundFlags & ELEMENT_IS_UNDERWATER)) - { - gGameCommandErrorText = STR_CANT_BUILD_THIS_UNDERWATER; - return MONEY32_UNDEFINED; - } - - tileElement = map_get_surface_element_at({ x, y }); - - int32_t supportHeight = z - tileElement->base_height; - gFootpathPrice += supportHeight < 0 ? MONEY(20, 00) : (supportHeight / 2) * MONEY(5, 00); - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (gGameCommandNestLevel == 1 && !(flags & 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); - } - - if (entrancePath) - { - if (!(flags & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath) - { - // Set the path type but make sure it's not a queue as that will not show up - entranceElement->SetPathType(type & 0x7F); - map_invalidate_tile_full(x, y); - } - } - else - { - tileElement = tile_element_insert(x / 32, y / 32, z, 0x0F); - assert(tileElement != nullptr); - tileElement->SetType(TILE_ELEMENT_TYPE_PATH); - PathElement* pathElement = tileElement->AsPath(); - // This can NEVER happen, but GCC does not want to believe that... - if (pathElement == nullptr) - { - assert(false); - return MONEY32_UNDEFINED; - } - pathElement->clearance_height = z + 4 + ((slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED) ? 2 : 0); - pathElement->SetPathEntryIndex(type & 0xF); - pathElement->SetSlopeDirection(slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK); - if (slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED) - pathElement->SetSloped(true); - if (type & (1 << 7)) - pathElement->SetIsQueue(true); - pathElement->SetAddition(0); - pathElement->SetRideIndex(RIDE_ID_NULL); - pathElement->SetAdditionStatus(255); - pathElement->SetEdges(edges); - pathElement->SetCorners(0); - pathElement->SetIsBroken(false); - if (flags & (1 << 6)) - pathElement->SetGhost(true); - - map_invalidate_tile_full(x, y); - } - } - - if (entranceIsSamePath) - gFootpathPrice = 0; - - return gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : gFootpathPrice; -} - -/** - * - * rct2: 0x006A68AE - */ -void game_command_place_footpath_from_track( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - *ebx = footpath_place_from_track( - (*edx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, ((*ebx >> 13) & 0x3) | ((*ebx >> 10) & 0x4), - (*ebx >> 8) & 0xF, *ebx & 0xFF); -} - money32 footpath_remove(int32_t x, int32_t y, int32_t z, int32_t flags) { auto action = FootpathRemoveAction(x, y, z); diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 8364a44f72..e3e6f1bb68 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -173,8 +173,6 @@ TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z); struct PathElement; PathElement* map_get_footpath_element_slope(int32_t x, int32_t y, int32_t z, int32_t slope); void footpath_interrupt_peeps(int32_t x, int32_t y, int32_t z); -void game_command_place_footpath_from_track( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_remove_footpath( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 footpath_remove(int32_t x, int32_t y, int32_t z, int32_t flags); From e32b9482b8b1b53c8495adccce71ab769e4fae63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 11 Mar 2019 02:47:11 -0700 Subject: [PATCH 008/506] Update xcode project (#27) --- OpenRCT2.xcodeproj/project.pbxproj | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index ee856509ab..60806dbfbb 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -32,11 +32,11 @@ 2A43D2C22225B91A00E8F73B /* LoadOrQuitAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A43D2BF2225B91A00E8F73B /* LoadOrQuitAction.hpp */; }; 2A5354E922099C4F00A5440F /* Network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A5354E822099C4F00A5440F /* Network.cpp */; }; 2A5C1368221E9F9000F8C245 /* TrackRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A5C1367221E9F9000F8C245 /* TrackRemoveAction.hpp */; }; - 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */; }; - 2A61CAF92229E59F0095AD67 /* WaterSetHeightAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */; }; 2A61CAF52229E5720095AD67 /* FootpathSceneryPlaceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAF22229E5720095AD67 /* FootpathSceneryPlaceAction.hpp */; }; 2A61CAF62229E5720095AD67 /* FootpathSceneryRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAF32229E5720095AD67 /* FootpathSceneryRemoveAction.hpp */; }; 2A61CAF72229E5720095AD67 /* FootpathPlaceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAF42229E5720095AD67 /* FootpathPlaceAction.hpp */; }; + 2A61CAF92229E59F0095AD67 /* WaterSetHeightAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */; }; + 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */; }; 2AA050322209A8E300D3A922 /* StaffSetCostumeAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AA050302209A8E300D3A922 /* StaffSetCostumeAction.hpp */; }; 2AA050332209A8E300D3A922 /* StaffSetOrdersAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AA050312209A8E300D3A922 /* StaffSetOrdersAction.hpp */; }; 2AAFD7FA220DD2DC002461A4 /* TrackPlaceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AAFD7F9220DD2DC002461A4 /* TrackPlaceAction.hpp */; }; @@ -643,11 +643,11 @@ 2A5354EA22099C7200A5440F /* CircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularBuffer.h; sourceTree = ""; }; 2A5354EB22099D7700A5440F /* SignSetStyleAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SignSetStyleAction.hpp; sourceTree = ""; }; 2A5C1367221E9F9000F8C245 /* TrackRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrackRemoveAction.hpp; sourceTree = ""; }; - 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideEntranceExitPlaceAction.hpp; sourceTree = ""; }; - 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterSetHeightAction.hpp; sourceTree = ""; }; 2A61CAF22229E5720095AD67 /* FootpathSceneryPlaceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathSceneryPlaceAction.hpp; sourceTree = ""; }; 2A61CAF32229E5720095AD67 /* FootpathSceneryRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathSceneryRemoveAction.hpp; sourceTree = ""; }; 2A61CAF42229E5720095AD67 /* FootpathPlaceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceAction.hpp; sourceTree = ""; }; + 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterSetHeightAction.hpp; sourceTree = ""; }; + 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideEntranceExitPlaceAction.hpp; sourceTree = ""; }; 2AA050302209A8E300D3A922 /* StaffSetCostumeAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffSetCostumeAction.hpp; sourceTree = ""; }; 2AA050312209A8E300D3A922 /* StaffSetOrdersAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffSetOrdersAction.hpp; sourceTree = ""; }; 2AAFD7F9220DD2DC002461A4 /* TrackPlaceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrackPlaceAction.hpp; sourceTree = ""; }; @@ -1303,6 +1303,7 @@ C6E96E331E0408A80076A04F /* zip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = ""; }; C6E96E341E0408A80076A04F /* zipconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zipconf.h; sourceTree = ""; }; C6E96E351E0408B40076A04F /* libzip.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libzip.dylib; sourceTree = ""; }; + C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceFromTrackAction.hpp; sourceTree = ""; }; D41B73EE1C2101890080A7B9 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/macos/Assets.xcassets; sourceTree = SOURCE_ROOT; }; @@ -2034,6 +2035,7 @@ C6352B871F477032006CCEE3 /* actions */ = { isa = PBXGroup; children = ( + C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */, 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */, 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */, 2A61CAF42229E5720095AD67 /* FootpathPlaceAction.hpp */, From f96a1a1b5f0174e8736464a11e00ea0a3127b8d2 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 11 Mar 2019 13:44:34 +0100 Subject: [PATCH 009/506] Implement StaffHireNewAction game action. --- src/openrct2-ui/windows/StaffList.cpp | 12 +- src/openrct2/Game.cpp | 4 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/StaffHireNewAction.hpp | 345 ++++++++++++++++++ src/openrct2/peep/Staff.cpp | 330 ++--------------- src/openrct2/peep/Staff.h | 6 +- src/openrct2/windows/_legacy.cpp | 19 - 8 files changed, 385 insertions(+), 335 deletions(-) create mode 100644 src/openrct2/actions/StaffHireNewAction.hpp diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index d969fcb494..f6d945f719 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -206,13 +206,17 @@ static void window_staff_list_mouseup(rct_window* w, rct_widgetindex widgetIndex break; case WIDX_STAFF_LIST_HIRE_BUTTON: { - int32_t staffType = _windowStaffListSelectedTab; + STAFF_TYPE staffType = static_cast(_windowStaffListSelectedTab); if (staffType == STAFF_TYPE_ENTERTAINER) { - uint8_t costume = window_staff_list_get_random_entertainer_costume(); - staffType += costume; + ENTERTAINER_COSTUME costume = static_cast( + window_staff_list_get_random_entertainer_costume()); + staff_hire_new_member(staffType, costume); + } + else + { + staff_hire_new_member(staffType, ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT); } - hire_new_staff_member(staffType); break; } case WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON: diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 7a46e8b733..8606a50b59 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -94,7 +94,7 @@ static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = { nullptr, game_command_callback_place_banner, nullptr, - game_command_callback_hire_new_staff_member, + nullptr, game_command_callback_pickup_guest, game_command_callback_pickup_staff }; @@ -1290,7 +1290,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_raise_water, game_command_lower_water, game_command_set_brakes_speed, - game_command_hire_new_staff_member, + nullptr, game_command_set_staff_patrol, game_command_fire_staff_member, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 99961ed78e..bd4e54c6fc 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -48,7 +48,7 @@ enum GAME_COMMAND GAME_COMMAND_RAISE_WATER, GAME_COMMAND_LOWER_WATER, GAME_COMMAND_SET_BRAKES_SPEED, - GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, + GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA GAME_COMMAND_SET_STAFF_PATROL, GAME_COMMAND_FIRE_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_ORDERS, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index c24a8e0a7f..d78da9e082 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -43,6 +43,7 @@ #include "SignSetStyleAction.hpp" #include "SmallSceneryPlaceAction.hpp" #include "SmallSceneryRemoveAction.hpp" +#include "StaffHireNewAction.hpp" #include "StaffSetColourAction.hpp" #include "StaffSetCostumeAction.hpp" #include "StaffSetNameAction.hpp" @@ -99,5 +100,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp new file mode 100644 index 0000000000..7941f86285 --- /dev/null +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -0,0 +1,345 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../Context.h" +#include "../core/MemoryStream.h" +#include "../drawing/Drawing.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/Ride.h" +#include "../scenario/Scenario.h" +#include "../ui/UiContext.h" +#include "../ui/WindowManager.h" +#include "../world/Entrance.h" +#include "../world/Park.h" +#include "../world/Sprite.h" +#include "GameAction.h" + +static constexpr const rct_string_id staffNames[] = { + STR_HANDYMAN_X, + STR_MECHANIC_X, + STR_SECURITY_GUARD_X, + STR_ENTERTAINER_X, +}; + +/* rct2: 0x009929FC */ +static constexpr const PeepSpriteType spriteTypes[] = { + PEEP_SPRITE_TYPE_HANDYMAN, + PEEP_SPRITE_TYPE_MECHANIC, + PEEP_SPRITE_TYPE_SECURITY, + PEEP_SPRITE_TYPE_ENTERTAINER_PANDA, +}; + +class StaffHireNewActionResult final : public GameActionResult +{ +public: + StaffHireNewActionResult() + : GameActionResult(GA_ERROR::OK, 0) + { + } + StaffHireNewActionResult(GA_ERROR error, rct_string_id message) + : GameActionResult(error, STR_CANT_HIRE_NEW_STAFF, message) + { + } + + uint32_t peepSriteIndex = SPRITE_INDEX_NULL; +}; + +DEFINE_GAME_ACTION(StaffHireNewAction, GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, StaffHireNewActionResult) +{ +private: + bool _autoPosition = false; + uint8_t _staffType = STAFF_TYPE::STAFF_TYPE_COUNT; + uint8_t _entertainerType = ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT; + +public: + StaffHireNewAction() = default; + StaffHireNewAction(bool autoPosition, STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType) + : _autoPosition(autoPosition) + , _staffType(staffType) + , _entertainerType(entertainerType) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_autoPosition) << DS_TAG(_staffType) << DS_TAG(_entertainerType); + } + + GameActionResult::Ptr Query() const override + { + return QueryExecute(false); + } + + GameActionResult::Ptr Execute() const override + { + return QueryExecute(true); + } + +private: + GameActionResult::Ptr QueryExecute(bool execute) const + { + auto res = std::make_unique(); + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_WAGES; + + if (_staffType >= STAFF_TYPE_COUNT) + { + // Invalid staff type. + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + + if (gSpriteListCount[SPRITE_LIST_NULL] < 400) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME); + } + + if (_staffType == STAFF_TYPE_ENTERTAINER) + { + if (_entertainerType >= ENTERTAINER_COSTUME_COUNT) + { + // Invalid entertainer costume + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + + uint32_t availableCostumes = staff_get_available_entertainer_costumes(); + if (!(availableCostumes & (1 << _entertainerType))) + { + // Entertainer costume unavailable + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + } + + // Look for a free slot in the staff modes. + int32_t staffIndex; + for (staffIndex = 0; staffIndex < STAFF_MAX_COUNT; ++staffIndex) + { + if (!(gStaffModes[staffIndex] & 1)) + break; + } + + if (staffIndex == STAFF_MAX_COUNT) + { + // Too many staff members exist already. + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_STAFF_IN_GAME); + } + + Peep* newPeep = &(create_sprite(GetFlags())->peep); + if (newPeep == nullptr) + { + // Too many staff members exist already. + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME); + } + + if (execute == false) + { + // In query we just want to see if we can obtain a sprite slot. + sprite_remove((rct_sprite*)newPeep); + } + else + { + move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP * 2); + + newPeep->sprite_identifier = 1; + newPeep->window_invalidate_flags = 0; + newPeep->action = PEEP_ACTION_NONE_2; + newPeep->special_sprite = 0; + newPeep->action_sprite_image_offset = 0; + newPeep->no_action_frame_num = 0; + newPeep->action_sprite_type = PEEP_ACTION_SPRITE_TYPE_NONE; + newPeep->path_check_optimisation = 0; + newPeep->type = PEEP_TYPE_STAFF; + newPeep->outside_of_park = 0; + newPeep->peep_flags = 0; + newPeep->paid_to_enter = 0; + newPeep->paid_on_rides = 0; + newPeep->paid_on_food = 0; + newPeep->paid_on_souvenirs = 0; + + if (_staffType == STAFF_TYPE_HANDYMAN) + newPeep->staff_orders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS; + else if (_staffType == STAFF_TYPE_MECHANIC) + newPeep->staff_orders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES; + else + newPeep->staff_orders = 0; + + uint16_t idSearchSpriteIndex; + Peep* idSearchPeep; + + // We search for the first available id for a given staff type + uint32_t newStaffId = 0; + for (;;) + { + bool found = false; + ++newStaffId; + + FOR_ALL_STAFF (idSearchSpriteIndex, idSearchPeep) + { + if (idSearchPeep->staff_type != _staffType) + continue; + + if (idSearchPeep->id == newStaffId) + { + found = true; + break; + } + } + + if (!found) + break; + } + + newPeep->id = newStaffId; + newPeep->staff_type = _staffType; + + PeepSpriteType spriteType = spriteTypes[_staffType]; + if (_staffType == STAFF_TYPE_ENTERTAINER) + { + spriteType = static_cast(PEEP_SPRITE_TYPE_ENTERTAINER_PANDA + _entertainerType); + } + newPeep->name_string_idx = staffNames[_staffType]; + newPeep->sprite_type = spriteType; + + const rct_sprite_bounds* spriteBounds = g_peep_animation_entries[spriteType].sprite_bounds; + newPeep->sprite_width = spriteBounds->sprite_width; + newPeep->sprite_height_negative = spriteBounds->sprite_height_negative; + newPeep->sprite_height_positive = spriteBounds->sprite_height_positive; + + if (_autoPosition == true) + { + AutoPositionNewStaff(newPeep); + } + else + { + // NOTE: This state is required for the window to act. + newPeep->state = PEEP_STATE_PICKED; + + sprite_move(newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep); + invalidate_sprite_2((rct_sprite*)newPeep); + } + + // Staff uses this + newPeep->time_in_park = gDateMonthsElapsed; + newPeep->pathfind_goal.x = 0xFF; + newPeep->pathfind_goal.y = 0xFF; + newPeep->pathfind_goal.z = 0xFF; + newPeep->pathfind_goal.direction = 0xFF; + + uint8_t colour = staff_get_colour(_staffType); + newPeep->tshirt_colour = colour; + newPeep->trousers_colour = colour; + + // Staff energy determines their walking speed + newPeep->energy = 0x60; + newPeep->energy_target = 0x60; + newPeep->staff_mowing_timeout = 0; + + peep_update_name_sort(newPeep); + + newPeep->staff_id = newStaffId; + + gStaffModes[staffIndex] = STAFF_MODE_WALK; + + for (int32_t newStaffIndex = 0; newStaffIndex < STAFF_PATROL_AREA_SIZE; newStaffIndex++) + { + gStaffPatrolAreas[newStaffIndex * STAFF_PATROL_AREA_SIZE + newStaffId] = 0; + } + + res->peepSriteIndex = newPeep->sprite_index; + } + + return res; + } + + void AutoPositionNewStaff(Peep * newPeep) const + { + // Find a location to place new staff member + + newPeep->state = PEEP_STATE_FALLING; + + int16_t x, y, z; + uint32_t count = 0; + uint16_t sprite_index; + Peep* guest = nullptr; + TileElement* guest_tile = nullptr; + + // Count number of walking guests + FOR_ALL_GUESTS (sprite_index, guest) + { + if (guest->state == PEEP_STATE_WALKING) + { + // Check the walking guest's tile. Only count them if they're on a path tile. + guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z); + if (guest_tile != nullptr) + ++count; + } + } + + if (count > 0) + { + // Place staff at a random guest + uint32_t rand = scenario_rand_max(count); + FOR_ALL_GUESTS (sprite_index, guest) + { + if (guest->state == PEEP_STATE_WALKING) + { + guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z); + if (guest_tile != nullptr) + { + if (rand == 0) + break; + --rand; + } + } + } + + x = guest->x; + y = guest->y; + z = guest->z; + } + else + { + // No walking guests; pick random park entrance + if (gParkEntrances.size() > 0) + { + auto rand = scenario_rand_max((uint32_t)gParkEntrances.size()); + const auto& entrance = gParkEntrances[rand]; + auto dir = entrance.direction; + x = entrance.x; + y = entrance.y; + z = entrance.z; + x += 16 + ((dir & 1) == 0 ? ((dir & 2) ? 32 : -32) : 0); + y += 16 + ((dir & 1) == 1 ? ((dir & 2) ? -32 : 32) : 0); + } + else + { + // User must pick a location + newPeep->state = PEEP_STATE_PICKED; + x = newPeep->x; + y = newPeep->y; + z = newPeep->z; + } + } + + sprite_move(x, y, z + 16, (rct_sprite*)newPeep); + invalidate_sprite_2((rct_sprite*)newPeep); + } +}; diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 89e9e0351b..1cf3704928 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -12,6 +12,7 @@ #include "../Context.h" #include "../Game.h" #include "../Input.h" +#include "../actions/StaffHireNewAction.hpp" #include "../actions/StaffSetOrdersAction.hpp" #include "../audio/audio.h" #include "../config/Config.h" @@ -81,286 +82,6 @@ void staff_reset_modes() staff_update_greyed_patrol_areas(); } -static inline void staff_autoposition_new_staff_member(Peep* newPeep) -{ - // Find a location to place new staff member - - newPeep->state = PEEP_STATE_FALLING; - - int16_t x, y, z; - uint32_t count = 0; - uint16_t sprite_index; - Peep* guest = nullptr; - TileElement* guest_tile = nullptr; - - // Count number of walking guests - FOR_ALL_GUESTS (sprite_index, guest) - { - if (guest->state == PEEP_STATE_WALKING) - { - // Check the walking guest's tile. Only count them if they're on a path tile. - guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z); - if (guest_tile != nullptr) - ++count; - } - } - - if (count > 0) - { - // Place staff at a random guest - uint32_t rand = scenario_rand_max(count); - FOR_ALL_GUESTS (sprite_index, guest) - { - if (guest->state == PEEP_STATE_WALKING) - { - guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z); - if (guest_tile != nullptr) - { - if (rand == 0) - break; - --rand; - } - } - } - - x = guest->x; - y = guest->y; - z = guest->z; - } - else - { - // No walking guests; pick random park entrance - if (gParkEntrances.size() > 0) - { - auto rand = scenario_rand_max((uint32_t)gParkEntrances.size()); - const auto& entrance = gParkEntrances[rand]; - auto dir = entrance.direction; - x = entrance.x; - y = entrance.y; - z = entrance.z; - x += 16 + ((dir & 1) == 0 ? ((dir & 2) ? 32 : -32) : 0); - y += 16 + ((dir & 1) == 1 ? ((dir & 2) ? -32 : 32) : 0); - } - else - { - // User must pick a location - newPeep->state = PEEP_STATE_PICKED; - x = newPeep->x; - y = newPeep->y; - z = newPeep->z; - } - } - - sprite_move(x, y, z + 16, (rct_sprite*)newPeep); - invalidate_sprite_2((rct_sprite*)newPeep); -} - -static money32 staff_hire_new_staff_member( - uint8_t staff_type, uint8_t flags, int16_t command_x, int16_t command_y, int16_t command_z, int32_t autoposition, - int32_t* newPeep_sprite_index) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_WAGES; - gCommandPosition.x = command_x; - gCommandPosition.y = command_y; - gCommandPosition.z = command_z; - - if (gSpriteListCount[SPRITE_LIST_NULL] < 400) - { - gGameCommandErrorText = STR_TOO_MANY_PEOPLE_IN_GAME; - return MONEY32_UNDEFINED; - } - - // Staff type matches STAFF_TYPE enum, but ENTERTAINER onwards will match - // the ENTERTAINER_COSTUME enum - uint8_t entertainerType = ENTERTAINER_COSTUME_PANDA; - if (staff_type >= STAFF_TYPE_ENTERTAINER) - { - entertainerType = staff_type - STAFF_TYPE_ENTERTAINER; - if (entertainerType >= ENTERTAINER_COSTUME_COUNT) - { - // Invalid entertainer costume - return MONEY32_UNDEFINED; - } - - uint32_t availableCostumes = staff_get_available_entertainer_costumes(); - if (!(availableCostumes & (1 << entertainerType))) - { - // Entertainer costume unavailable - return MONEY32_UNDEFINED; - } - - staff_type = STAFF_TYPE_ENTERTAINER; - } - - int32_t i; - for (i = 0; i < STAFF_MAX_COUNT; ++i) - { - if (!(gStaffModes[i] & 1)) - break; - } - - if (i == STAFF_MAX_COUNT) - { - gGameCommandErrorText = STR_TOO_MANY_STAFF_IN_GAME; - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - int32_t newStaffId = i; - const rct_sprite_bounds* spriteBounds; - Peep* newPeep = &(create_sprite(flags)->peep); - - if (newPeep == nullptr) - { - gGameCommandErrorText = STR_TOO_MANY_PEOPLE_IN_GAME; - return MONEY32_UNDEFINED; - } - - if (flags == 0) - { - sprite_remove((rct_sprite*)newPeep); - } - else - { - move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP * 2); - - newPeep->sprite_identifier = 1; - newPeep->window_invalidate_flags = 0; - newPeep->action = PEEP_ACTION_NONE_2; - newPeep->special_sprite = 0; - newPeep->action_sprite_image_offset = 0; - newPeep->no_action_frame_num = 0; - newPeep->action_sprite_type = PEEP_ACTION_SPRITE_TYPE_NONE; - newPeep->path_check_optimisation = 0; - newPeep->type = PEEP_TYPE_STAFF; - newPeep->outside_of_park = 0; - newPeep->peep_flags = 0; - newPeep->paid_to_enter = 0; - newPeep->paid_on_rides = 0; - newPeep->paid_on_food = 0; - newPeep->paid_on_souvenirs = 0; - - if (staff_type == STAFF_TYPE_HANDYMAN) - newPeep->staff_orders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS; - else if (staff_type == STAFF_TYPE_MECHANIC) - newPeep->staff_orders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES; - else - newPeep->staff_orders = 0; - - uint16_t idSearchSpriteIndex; - Peep* idSearchPeep; - - // We search for the first available id for a given staff type - uint32_t newStaffIndex = 0; - for (;;) - { - bool found = false; - ++newStaffIndex; - - FOR_ALL_STAFF (idSearchSpriteIndex, idSearchPeep) - { - if (idSearchPeep->staff_type != staff_type) - continue; - - if (idSearchPeep->id == newStaffIndex) - { - found = true; - break; - } - } - - if (!found) - break; - } - - newPeep->id = newStaffIndex; - newPeep->staff_type = staff_type; - - static constexpr const rct_string_id staffNames[] = { - STR_HANDYMAN_X, - STR_MECHANIC_X, - STR_SECURITY_GUARD_X, - STR_ENTERTAINER_X, - }; - - /* rct2: 0x009929FC */ - static constexpr const PeepSpriteType spriteTypes[] = { - PEEP_SPRITE_TYPE_HANDYMAN, - PEEP_SPRITE_TYPE_MECHANIC, - PEEP_SPRITE_TYPE_SECURITY, - PEEP_SPRITE_TYPE_ENTERTAINER_PANDA, - }; - - PeepSpriteType sprite_type = spriteTypes[staff_type]; - if (staff_type == STAFF_TYPE_ENTERTAINER) - { - sprite_type = static_cast(PEEP_SPRITE_TYPE_ENTERTAINER_PANDA + entertainerType); - } - newPeep->name_string_idx = staffNames[staff_type]; - newPeep->sprite_type = sprite_type; - - spriteBounds = g_peep_animation_entries[sprite_type].sprite_bounds; - newPeep->sprite_width = spriteBounds->sprite_width; - newPeep->sprite_height_negative = spriteBounds->sprite_height_negative; - newPeep->sprite_height_positive = spriteBounds->sprite_height_positive; - - if (autoposition) - { - staff_autoposition_new_staff_member(newPeep); - } - else - { - newPeep->state = PEEP_STATE_PICKED; - - sprite_move(newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep); - invalidate_sprite_2((rct_sprite*)newPeep); - } - - newPeep->time_in_park = gDateMonthsElapsed; - newPeep->pathfind_goal.x = 0xFF; - newPeep->pathfind_goal.y = 0xFF; - newPeep->pathfind_goal.z = 0xFF; - newPeep->pathfind_goal.direction = 0xFF; - - uint8_t colour = staff_get_colour(staff_type); - newPeep->tshirt_colour = colour; - newPeep->trousers_colour = colour; - - // Staff energy determines their walking speed - newPeep->energy = 0x60; - newPeep->energy_target = 0x60; - newPeep->staff_mowing_timeout = 0; - - peep_update_name_sort(newPeep); - - newPeep->staff_id = newStaffId; - - gStaffModes[newStaffId] = STAFF_MODE_WALK; - - for (i = 0; i < STAFF_PATROL_AREA_SIZE; i++) - { - gStaffPatrolAreas[newStaffId * STAFF_PATROL_AREA_SIZE + i] = 0; - } - } - - *newPeep_sprite_index = newPeep->sprite_index; - } - return 0; -} - -/** - * - * rct2: 0x006BEFA1 - */ -void game_command_hire_new_staff_member( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - *ebx = staff_hire_new_staff_member( - (*ebx & 0xFF00) >> 8, *ebx & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFFFF, (*ebx & 0xFF0000) >> 16, edi); -} - /** * * rct2: 0x006C09D1 @@ -449,42 +170,39 @@ void game_command_fire_staff_member( } /** - * Hires a new staff member of the given type. If the hire cannot be completed (eg. the maximum number of staff is reached or - * there are too many peeps) it returns SPRITE_INDEX_NULL. + * Hires a new staff member of the given type. */ -uint16_t hire_new_staff_member(uint8_t staffType) +bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType) { - gGameCommandErrorTitle = STR_CANT_HIRE_NEW_STAFF; - - int32_t command_x, ebx, command_y, command_z, esi, new_sprite_index, ebp; - command_y = command_z = esi = new_sprite_index = ebp = 0; - command_x = 0x8000; - - int32_t autoposition = gConfigGeneral.auto_staff_placement; + bool autoPosition = gConfigGeneral.auto_staff_placement; if (gInputPlaceObjectModifier & PLACE_OBJECT_MODIFIER_SHIFT_Z) { - autoposition = autoposition ^ 1; + autoPosition = autoPosition ^ 1; } - ebx = autoposition << 16 | staffType << 8 | GAME_COMMAND_FLAG_APPLY; + auto hireStaffAction = StaffHireNewAction(autoPosition, staffType, entertainerType); + hireStaffAction.SetCallback([=](const GameAction*, const StaffHireNewActionResult* res) -> void { + if (res->Error != GA_ERROR::OK) + return; - game_command_callback = game_command_callback_hire_new_staff_member; - int32_t result = game_do_command_p( - GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &command_x, &ebx, &command_y, &command_z, &esi, &new_sprite_index, &ebp); + if ((staffType == STAFF_TYPE_HANDYMAN) && gConfigGeneral.handymen_mow_default) + { + Peep* newPeep = GET_PEEP(res->peepSriteIndex); + uint8_t newOrders = newPeep->staff_orders | STAFF_ORDERS_MOWING; - if (result == MONEY32_UNDEFINED) - return SPRITE_INDEX_NULL; + auto staffSetOrdersAction = StaffSetOrdersAction(res->peepSriteIndex, newOrders); + GameActions::Execute(&staffSetOrdersAction); + } - if ((staffType == STAFF_TYPE_HANDYMAN) && gConfigGeneral.handymen_mow_default) - { - Peep* newPeep = GET_PEEP(new_sprite_index); - uint8_t newOrders = newPeep->staff_orders | STAFF_ORDERS_MOWING; + // Open window for new staff. + Peep* peep = &get_sprite(res->peepSriteIndex)->peep; + auto intent = Intent(WC_PEEP); + intent.putExtra(INTENT_EXTRA_PEEP, peep); + context_open_intent(&intent); + }); - auto staffSetOrdersAction = StaffSetOrdersAction(new_sprite_index, newOrders); - GameActions::Execute(&staffSetOrdersAction); - } - - return new_sprite_index; + auto res = GameActions::Execute(&hireStaffAction); + return res->Error == GA_ERROR::OK; } /** diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 61c15896a3..30ef68ef5f 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -25,7 +25,7 @@ enum STAFF_MODE STAFF_MODE_PATROL = 3 }; -enum STAFF_TYPE +enum STAFF_TYPE : uint8_t { STAFF_TYPE_HANDYMAN, STAFF_TYPE_MECHANIC, @@ -45,7 +45,7 @@ enum STAFF_ORDERS STAFF_ORDERS_FIX_RIDES = (1 << 1) }; -enum ENTERTAINER_COSTUME +enum ENTERTAINER_COSTUME : uint8_t { ENTERTAINER_COSTUME_PANDA, ENTERTAINER_COSTUME_TIGER, @@ -86,7 +86,7 @@ void game_command_pickup_staff( void staff_reset_modes(); void staff_set_name(uint16_t spriteIndex, const char* name); -uint16_t hire_new_staff_member(uint8_t staffType); +bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType); void staff_update_greyed_patrol_areas(); bool staff_is_location_in_patrol(Peep* mechanic, int32_t x, int32_t y); bool staff_is_location_on_patrol_edge(Peep* mechanic, int32_t x, int32_t y); diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index 207255dd2b..f051444ab0 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -55,25 +55,6 @@ void game_command_callback_pickup_guest( } } -void game_command_callback_hire_new_staff_member( - [[maybe_unused]] int32_t eax, [[maybe_unused]] int32_t ebx, [[maybe_unused]] int32_t ecx, [[maybe_unused]] int32_t edx, - [[maybe_unused]] int32_t esi, int32_t edi, [[maybe_unused]] int32_t ebp) -{ - int32_t sprite_index = edi; - if (sprite_index == SPRITE_INDEX_NULL) - { - rct_window* window = window_find_by_class(WC_STAFF_LIST); - window_invalidate(window); - } - else - { - Peep* peep = &get_sprite(sprite_index)->peep; - auto intent = Intent(WC_PEEP); - intent.putExtra(INTENT_EXTRA_PEEP, peep); - context_open_intent(&intent); - } -} - void game_command_callback_pickup_staff( int32_t eax, int32_t ebx, int32_t ecx, [[maybe_unused]] int32_t edx, [[maybe_unused]] int32_t esi, [[maybe_unused]] int32_t edi, [[maybe_unused]] int32_t ebp) From a3e0fdaf8135dc4a7a86e3685efc3d904985dc29 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 11 Mar 2019 16:53:03 +0100 Subject: [PATCH 010/506] Simplify code --- src/openrct2-ui/windows/StaffList.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index f6d945f719..34379e3f24 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -207,16 +207,12 @@ static void window_staff_list_mouseup(rct_window* w, rct_widgetindex widgetIndex case WIDX_STAFF_LIST_HIRE_BUTTON: { STAFF_TYPE staffType = static_cast(_windowStaffListSelectedTab); + ENTERTAINER_COSTUME costume = ENTERTAINER_COSTUME_COUNT; if (staffType == STAFF_TYPE_ENTERTAINER) { - ENTERTAINER_COSTUME costume = static_cast( - window_staff_list_get_random_entertainer_costume()); - staff_hire_new_member(staffType, costume); - } - else - { - staff_hire_new_member(staffType, ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT); + costume = static_cast(window_staff_list_get_random_entertainer_costume()); } + staff_hire_new_member(staffType, costume); break; } case WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON: From f8e98b4e3e61ec0318720e4dac6396b46fab2613 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 11 Mar 2019 16:54:46 +0100 Subject: [PATCH 011/506] Pass staff orders by parameter. --- src/openrct2/actions/StaffHireNewAction.hpp | 16 +++++-------- src/openrct2/peep/Staff.cpp | 26 +++++++++++++-------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index 7941f86285..370a253d1a 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -45,7 +45,7 @@ class StaffHireNewActionResult final : public GameActionResult { public: StaffHireNewActionResult() - : GameActionResult(GA_ERROR::OK, 0) + : GameActionResult(GA_ERROR::OK, STR_CANT_HIRE_NEW_STAFF) { } StaffHireNewActionResult(GA_ERROR error, rct_string_id message) @@ -62,13 +62,15 @@ private: bool _autoPosition = false; uint8_t _staffType = STAFF_TYPE::STAFF_TYPE_COUNT; uint8_t _entertainerType = ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT; + uint32_t _staffOrders = 0; public: StaffHireNewAction() = default; - StaffHireNewAction(bool autoPosition, STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType) + StaffHireNewAction(bool autoPosition, STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType, uint32_t staffOrders) : _autoPosition(autoPosition) , _staffType(staffType) , _entertainerType(entertainerType) + , _staffOrders(staffOrders) { } @@ -81,7 +83,7 @@ public: { GameAction::Serialise(stream); - stream << DS_TAG(_autoPosition) << DS_TAG(_staffType) << DS_TAG(_entertainerType); + stream << DS_TAG(_autoPosition) << DS_TAG(_staffType) << DS_TAG(_entertainerType) << DS_TAG(_staffOrders); } GameActionResult::Ptr Query() const override @@ -173,13 +175,7 @@ private: newPeep->paid_on_rides = 0; newPeep->paid_on_food = 0; newPeep->paid_on_souvenirs = 0; - - if (_staffType == STAFF_TYPE_HANDYMAN) - newPeep->staff_orders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS; - else if (_staffType == STAFF_TYPE_MECHANIC) - newPeep->staff_orders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES; - else - newPeep->staff_orders = 0; + newPeep->staff_orders = _staffOrders; uint16_t idSearchSpriteIndex; Peep* idSearchPeep; diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 1cf3704928..3497ef275c 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -180,20 +180,26 @@ bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainer autoPosition = autoPosition ^ 1; } - auto hireStaffAction = StaffHireNewAction(autoPosition, staffType, entertainerType); + uint32_t staffOrders = 0; + + if (staffType == STAFF_TYPE_HANDYMAN) + { + staffOrders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS; + if (gConfigGeneral.handymen_mow_default) + { + staffOrders |= STAFF_ORDERS_MOWING; + } + } + else if (staffType == STAFF_TYPE_MECHANIC) + { + staffOrders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES; + } + + auto hireStaffAction = StaffHireNewAction(autoPosition, staffType, entertainerType, staffOrders); hireStaffAction.SetCallback([=](const GameAction*, const StaffHireNewActionResult* res) -> void { if (res->Error != GA_ERROR::OK) return; - if ((staffType == STAFF_TYPE_HANDYMAN) && gConfigGeneral.handymen_mow_default) - { - Peep* newPeep = GET_PEEP(res->peepSriteIndex); - uint8_t newOrders = newPeep->staff_orders | STAFF_ORDERS_MOWING; - - auto staffSetOrdersAction = StaffSetOrdersAction(res->peepSriteIndex, newOrders); - GameActions::Execute(&staffSetOrdersAction); - } - // Open window for new staff. Peep* peep = &get_sprite(res->peepSriteIndex)->peep; auto intent = Intent(WC_PEEP); From 84d28f2967a65e3093b9e87ef7b06ef7b217b303 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 11 Mar 2019 17:02:29 +0100 Subject: [PATCH 012/506] Update error messages. --- src/openrct2/actions/StaffHireNewAction.hpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index 370a253d1a..e74d7d2b2a 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -106,7 +106,9 @@ private: if (_staffType >= STAFF_TYPE_COUNT) { // Invalid staff type. - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + log_error("Tried to use invalid staff type: %u", (uint32_t)_staffType); + + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } if (gSpriteListCount[SPRITE_LIST_NULL] < 400) @@ -119,14 +121,18 @@ private: if (_entertainerType >= ENTERTAINER_COSTUME_COUNT) { // Invalid entertainer costume - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + log_error("Tried to use invalid entertainer type: %u", (uint32_t)_entertainerType); + + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } uint32_t availableCostumes = staff_get_available_entertainer_costumes(); if (!(availableCostumes & (1 << _entertainerType))) { // Entertainer costume unavailable - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + log_error("Tried to use unavailable entertainer type: %u", (uint32_t)_entertainerType); + + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } } @@ -147,7 +153,7 @@ private: Peep* newPeep = &(create_sprite(GetFlags())->peep); if (newPeep == nullptr) { - // Too many staff members exist already. + // Too many peeps exist already. return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME); } From da377e5b647f73c42e712d3e5b667ccb1aa4b38b Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 11 Mar 2019 17:43:07 +0000 Subject: [PATCH 013/506] Add constants for min and max footpath height --- src/openrct2/actions/FootpathPlaceAction.hpp | 4 ++-- src/openrct2/actions/FootpathPlaceFromTrackAction.hpp | 4 ++-- src/openrct2/world/Footpath.h | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/openrct2/actions/FootpathPlaceAction.hpp b/src/openrct2/actions/FootpathPlaceAction.hpp index e3c3a4b122..c52f73b337 100644 --- a/src/openrct2/actions/FootpathPlaceAction.hpp +++ b/src/openrct2/actions/FootpathPlaceAction.hpp @@ -79,12 +79,12 @@ public: return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_FOOTPATH_HERE, STR_LAND_SLOPE_UNSUITABLE); } - if (_loc.z / 8 < 2) + if (_loc.z / 8 < FootpathMinHeight) { return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_FOOTPATH_HERE, STR_TOO_LOW); } - if (_loc.z / 8 > 248) + if (_loc.z / 8 > FootpathMaxHeight) { return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_FOOTPATH_HERE, STR_TOO_HIGH); } diff --git a/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp b/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp index 41f4e50c19..0a1f675a3b 100644 --- a/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp +++ b/src/openrct2/actions/FootpathPlaceFromTrackAction.hpp @@ -75,12 +75,12 @@ public: return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); } - if (_loc.z / 8 < 2) + if (_loc.z / 8 < FootpathMinHeight) { return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_LOW); } - if (_loc.z / 8 > 248) + if (_loc.z / 8 > FootpathMaxHeight) { return MakeResult(GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_HIGH); } diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index e3e6f1bb68..79ba0f6dbb 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -21,6 +21,9 @@ enum PROVISIONAL_PATH_FLAG_2 = (1 << 2), }; +constexpr auto FootpathMaxHeight = 248; +constexpr auto FootpathMinHeight = 2; + #define FOOTPATH_ELEMENT_INSERT_QUEUE 0x80 #pragma pack(push, 1) From 7fbf11ac792beed3f9c2626d0a5a1e20fc8740a5 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 11 Mar 2019 19:07:28 +0000 Subject: [PATCH 014/506] Implement TrackSetBrakeSpeedAction --- src/openrct2-ui/windows/RideConstruction.cpp | 11 ++- .../actions/GameActionRegistration.cpp | 1 + .../actions/TrackSetBrakeSpeedAction.hpp | 74 +++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/openrct2/actions/TrackSetBrakeSpeedAction.hpp diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 9e11e4bee9..388c903d83 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -3458,9 +3459,13 @@ static void ride_construction_set_brakes_speed(int32_t brakesSpeed) z = _currentTrackBegin.z; if (!sub_6C683D(&x, &y, &z, _currentTrackPieceDirection & 3, _currentTrackPieceType, 0, &tileElement, 0)) { - game_do_command( - _currentTrackBegin.x, GAME_COMMAND_FLAG_APPLY | ((brakesSpeed) << 8), _currentTrackBegin.y, - tileElement->AsTrack()->GetTrackType(), GAME_COMMAND_SET_BRAKES_SPEED, _currentTrackBegin.z, 0); + auto trackSetBrakeSpeed = TrackSetBrakeSpeedAction( + { _currentTrackBegin.x, _currentTrackBegin.y, _currentTrackBegin.z }, tileElement->AsTrack()->GetTrackType(), + brakesSpeed); + trackSetBrakeSpeed.SetCallback( + [](const GameAction* ga, const GameActionResult* result) { window_ride_construction_update_active_elements(); }); + GameActions::Execute(&trackSetBrakeSpeed); + return; } window_ride_construction_update_active_elements(); } diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index c24a8e0a7f..3011a88f3e 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -51,6 +51,7 @@ #include "TrackRemoveAction.hpp" #include "WallRemoveAction.hpp" #include "WaterSetHeightAction.hpp" +#include "TrackSetBrakeSpeedAction.hpp" namespace GameActions { diff --git a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp new file mode 100644 index 0000000000..7ac8d7c702 --- /dev/null +++ b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp @@ -0,0 +1,74 @@ +/***************************************************************************** + * 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 "GameAction.h" + +DEFINE_GAME_ACTION(TrackSetBrakeSpeedAction, GAME_COMMAND_SET_BRAKES_SPEED, GameActionResult) +{ +private: + CoordsXYZ _loc; + uint8_t _trackType; + uint8_t _brakeSpeed; + +public: + TrackSetBrakeSpeedAction() = default; + TrackSetBrakeSpeedAction(CoordsXYZ loc, uint8_t trackType, uint8_t brakeSpeed) + : _loc(loc) + , _trackType(trackType) + , _brakeSpeed(brakeSpeed) + { + } + + 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(_trackType) << DS_TAG(_brakeSpeed); + } + + 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(); + + res->Position = _loc; + res->Position.x += 16; + res->Position.y += 16; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; + + TileElement* tileElement = map_get_track_element_at_of_type(_loc.x / 32, _loc.y / 32, _loc.z / 8, _trackType); + if (tileElement == nullptr) + { + log_warning("Invalid game command for setting brakes speed. x = %d, y = %d", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + if (isExecuting == true) + { + tileElement->AsTrack()->SetBrakeBoosterSpeed(_brakeSpeed); + } + return res; + } +}; From 539c12b41a9859813d1f60fdb721035baefc269e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 11 Mar 2019 19:11:54 +0000 Subject: [PATCH 015/506] Remove old game command --- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- src/openrct2/ride/Track.cpp | 49 ------------------------------------- src/openrct2/ride/Track.h | 2 -- 4 files changed, 2 insertions(+), 53 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 7a46e8b733..0be90cfb7f 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1289,7 +1289,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_smooth_land, game_command_raise_water, game_command_lower_water, - game_command_set_brakes_speed, + nullptr, game_command_hire_new_staff_member, game_command_set_staff_patrol, game_command_fire_staff_member, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 99961ed78e..ae7cf1f827 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -47,7 +47,7 @@ enum GAME_COMMAND GAME_COMMAND_EDIT_LAND_SMOOTH, GAME_COMMAND_RAISE_WATER, GAME_COMMAND_LOWER_WATER, - GAME_COMMAND_SET_BRAKES_SPEED, + GAME_COMMAND_SET_BRAKES_SPEED, // GA GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_PATROL, GAME_COMMAND_FIRE_STAFF_MEMBER, diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index b5421f73e5..1c7b64f6ee 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -1264,55 +1264,6 @@ void game_command_remove_track( *edx & 0xFF, (*edx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edi & 0xFFFF, (*ebx >> 8) & 0xFF, *ebx & 0xFF); } -/** - * - * rct2: 0x006C5AE9 - */ -void game_command_set_brakes_speed( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - int32_t x = (*eax & 0xFFFF); - int32_t y = (*ecx & 0xFFFF); - int32_t z = (*edi & 0xFFFF); - int32_t trackType = (*edx & 0xFF); - int32_t brakesSpeed = ((*ebx >> 8) & 0xFF); - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (*ebx & GAME_COMMAND_FLAG_APPLY) - { - *ebx = 0; - return; - } - - TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); - if (tileElement == nullptr) - { - log_warning("Invalid game command for setting brakes speed. x = %d, y = %d", x, y); - *ebx = MONEY32_UNDEFINED; - return; - } - do - { - if (tileElement->base_height * 8 != z) - continue; - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - if (tileElement->AsTrack()->GetTrackType() != trackType) - continue; - - tileElement->AsTrack()->SetBrakeBoosterSpeed(brakesSpeed); - - break; - } while (!(tileElement++)->IsLastForTile()); - - *ebx = 0; -} - void track_circuit_iterator_begin(track_circuit_iterator* it, CoordsXYE first) { it->last = first; diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index ef6bb84501..8f194f6955 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -557,7 +557,5 @@ money32 maze_set_track( uint16_t x, uint16_t y, uint16_t z, uint8_t flags, bool initialPlacement, uint8_t direction, ride_id_t rideIndex, uint8_t mode); -void game_command_set_brakes_speed( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); bool track_element_is_booster(uint8_t rideType, uint8_t trackType); bool track_element_has_speed_setting(uint8_t trackType); From 6daa4061387203ea38163af76105cc92a846d5a2 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 12 Mar 2019 17:29:38 +0000 Subject: [PATCH 016/506] Actually register it. Include correct header. Fix formatting --- src/openrct2/actions/GameActionRegistration.cpp | 3 ++- src/openrct2/actions/TrackSetBrakeSpeedAction.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 3011a88f3e..c29bdb17a9 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -49,9 +49,9 @@ #include "StaffSetOrdersAction.hpp" #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" +#include "TrackSetBrakeSpeedAction.hpp" #include "WallRemoveAction.hpp" #include "WaterSetHeightAction.hpp" -#include "TrackSetBrakeSpeedAction.hpp" namespace GameActions { @@ -96,6 +96,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp index 7ac8d7c702..c3b60556f8 100644 --- a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp +++ b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp @@ -9,6 +9,7 @@ #pragma once +#include "../management/Finance.h" #include "GameAction.h" DEFINE_GAME_ACTION(TrackSetBrakeSpeedAction, GAME_COMMAND_SET_BRAKES_SPEED, GameActionResult) From 57b8fba3228d583288e34939f20b49f7283eb273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 13 Mar 2019 23:23:38 +0100 Subject: [PATCH 017/506] Start v0.2.2+ --- distribution/changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 71b0695a56..b1e7bdb4cc 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,3 +1,6 @@ +0.2.2+ (in development) +------------------------------------------------------------------------ + 0.2.2 (2019-03-13) ------------------------------------------------------------------------ - Feature: [#4418] Allow steep slopes on the side-friction roller coaster. From 7410c4b56c5cc6c44ba340bdb5a3e636a95c94b5 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 12 Mar 2019 14:22:31 +0100 Subject: [PATCH 018/506] Use real server tick to check desyncs. --- src/openrct2/network/Network.cpp | 58 ++++++-------------------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 95cd5e38b4..d2e09eedaf 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -293,11 +293,9 @@ private: std::unique_ptr _advertiser; uint16_t listening_port = 0; SOCKET_STATUS _lastConnectStatus = SOCKET_STATUS_CLOSED; - uint32_t last_tick_sent_time = 0; uint32_t last_ping_sent_time = 0; uint32_t server_tick = 0; uint32_t server_srand0 = 0; - uint32_t server_srand0_tick = 0; std::string server_sprite_hash; uint8_t player_id = 0; std::list> client_connection_list; @@ -307,7 +305,6 @@ private: bool _desynchronised = false; uint32_t server_connect_time = 0; uint8_t default_group = 0; - uint32_t game_commands_processed_this_tick = 0; uint32_t _commandId; uint32_t _actionId; std::string _chatLogPath; @@ -361,7 +358,6 @@ Network::Network() wsa_initialized = false; mode = NETWORK_MODE_NONE; status = NETWORK_STATUS_NONE; - last_tick_sent_time = 0; last_ping_sent_time = 0; _commandId = 0; _actionId = 0; @@ -926,24 +922,8 @@ void Network::SendPacketToClients(NetworkPacket& packet, bool front, bool gameCm bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) { - if (server_srand0_tick == 0) - return true; - - if (tick > server_srand0_tick) + if (tick == server_tick) { - server_srand0_tick = 0; - return true; - } - - if (game_commands_processed_this_tick != 0) - { - // SRAND/sprite hash is only updated once at beginning of tick so it is invalid otherwise - return true; - } - - if (tick == server_srand0_tick) - { - server_srand0_tick = 0; // Check that the server and client sprite hashes match rct_sprite_checksum checksum = sprite_checksum(); std::string client_sprite_hash = checksum.ToString(); @@ -1618,14 +1598,6 @@ void Network::Server_Send_GAME_ACTION(const GameAction* action) void Network::Server_Send_TICK() { - uint32_t ticks = platform_get_ticks(); - if (ticks < last_tick_sent_time + 25) - { - return; - } - - last_tick_sent_time = ticks; - std::unique_ptr packet(NetworkPacket::Allocate()); *packet << (uint32_t)NETWORK_COMMAND_TICK << gCurrentTicks << scenario_rand_state().s0; uint32_t flags = 0; @@ -1924,7 +1896,6 @@ void Network::ProcessGameCommands() GameActionResult::Ptr result = GameActions::Execute(action); if (result->Error == GA_ERROR::OK) { - game_commands_processed_this_tick++; Server_Send_GAME_ACTION(action); } } @@ -1946,7 +1917,6 @@ void Network::ProcessGameCommands() if (cost != MONEY32_UNDEFINED) { - game_commands_processed_this_tick++; NetworkPlayer* player = GetPlayerByID(gc.playerid); if (!player) return; @@ -2546,7 +2516,6 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection, game_load_init(); game_command_queue.clear(); server_tick = gCurrentTicks; - server_srand0_tick = 0; // window_network_status_open("Loaded new map from network"); _desynchronised = false; gFirstTimeSaving = true; @@ -2887,27 +2856,20 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, { uint32_t srand0; uint32_t flags; - // Note: older server version may not advertise flags at all. - // NetworkPacket will return 0, if trying to read past end of buffer, - // so flags == 0 is expected in such cases. packet >> server_tick >> srand0 >> flags; - if (server_srand0_tick == 0) + + server_srand0 = srand0; + server_sprite_hash.resize(0); + if (flags & NETWORK_TICK_FLAG_CHECKSUMS) { - server_srand0 = srand0; - server_srand0_tick = server_tick; - server_sprite_hash.resize(0); - if (flags & NETWORK_TICK_FLAG_CHECKSUMS) + const char* text = packet.ReadString(); + if (text != nullptr) { - const char* text = packet.ReadString(); - if (text != nullptr) - { - auto textLen = std::strlen(text); - server_sprite_hash.resize(textLen); - std::memcpy(server_sprite_hash.data(), text, textLen); - } + auto textLen = std::strlen(text); + server_sprite_hash.resize(textLen); + std::memcpy(server_sprite_hash.data(), text, textLen); } } - game_commands_processed_this_tick = 0; } void Network::Client_Handle_PLAYERLIST([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) From 8f7cf5fcc92533ada56bcfe943541ada04bba035 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 12 Mar 2019 14:24:48 +0100 Subject: [PATCH 019/506] Check desyncs only when the map is fully loaded. --- src/openrct2/network/Network.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index d2e09eedaf..9697b2b3b6 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -288,6 +288,7 @@ private: bool _closeLock = false; bool _requireClose = false; bool wsa_initialized = false; + bool _clientMapLoaded = false; std::unique_ptr _listenSocket; std::unique_ptr _serverConnection; std::unique_ptr _advertiser; @@ -483,6 +484,7 @@ bool Network::BeginClient(const std::string& host, uint16_t port) _serverConnection->Socket->ConnectAsync(host, port); status = NETWORK_STATUS_CONNECTING; _lastConnectStatus = SOCKET_STATUS_CLOSED; + _clientMapLoaded = false; BeginChatLog(); BeginServerLog(); @@ -922,6 +924,10 @@ void Network::SendPacketToClients(NetworkPacket& packet, bool front, bool gameCm bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) { + // We have to wait for the map to be loaded first, ticks may match current loaded map. + if (_clientMapLoaded == false) + return true; + if (tick == server_tick) { // Check that the server and client sprite hashes match @@ -2518,6 +2524,7 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection, server_tick = gCurrentTicks; // window_network_status_open("Loaded new map from network"); _desynchronised = false; + _clientMapLoaded = true; gFirstTimeSaving = true; // Notify user he is now online and which shortcut key enables chat From 258f2722d7f3c5fc65355a227379f6b562aa607d Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 12 Mar 2019 14:25:05 +0100 Subject: [PATCH 020/506] Bump up 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 9697b2b3b6..33df716012 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 "0" +#define NETWORK_STREAM_VERSION "1" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From b249928222d8d1239a4bcfa54da8d545c643f65b Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 12 Mar 2019 21:07:48 +0100 Subject: [PATCH 021/506] Buffer tick data so client can catch up. --- src/openrct2/network/Network.cpp | 49 +++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 33df716012..7035065717 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -195,7 +195,6 @@ public: std::vector _challenge; std::map _gameActionCallbacks; NetworkUserManager _userManager; - std::string ServerName; std::string ServerDescription; std::string ServerGreeting; @@ -283,6 +282,15 @@ private: PlayerListUpdate _pendingPlayerList; + struct ServerTickData_t + { + uint32_t srand0; + uint32_t tick; + std::string spriteHash; + }; + + std::map _serverTickData; + int32_t mode = NETWORK_MODE_NONE; int32_t status = NETWORK_STATUS_NONE; bool _closeLock = false; @@ -485,6 +493,7 @@ bool Network::BeginClient(const std::string& host, uint16_t port) status = NETWORK_STATUS_CONNECTING; _lastConnectStatus = SOCKET_STATUS_CLOSED; _clientMapLoaded = false; + _serverTickData.clear(); BeginChatLog(); BeginServerLog(); @@ -928,18 +937,22 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) if (_clientMapLoaded == false) return true; - if (tick == server_tick) + auto itTickData = _serverTickData.find(tick); + if (itTickData == std::end(_serverTickData)) + return true; + + const ServerTickData_t storedTick = itTickData->second; + _serverTickData.erase(itTickData); + + if (storedTick.srand0 != srand0) + return false; + + if (storedTick.spriteHash.empty() == false) { - // Check that the server and client sprite hashes match rct_sprite_checksum checksum = sprite_checksum(); - std::string client_sprite_hash = checksum.ToString(); - const bool sprites_mismatch = server_sprite_hash[0] != '\0' && client_sprite_hash != server_sprite_hash; - // Check PRNG values and sprite hashes, if exist - if ((srand0 != server_srand0) || sprites_mismatch) + std::string clientSpriteHash = checksum.ToString(); + if (clientSpriteHash != storedTick.spriteHash) { -# ifdef DEBUG_DESYNC - dbg_report_desync(tick, srand0, server_srand0, client_sprite_hash.c_str(), server_sprite_hash.c_str()); -# endif return false; } } @@ -2865,6 +2878,10 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, uint32_t flags; packet >> server_tick >> srand0 >> flags; + ServerTickData_t tickData; + tickData.srand0 = srand0; + tickData.tick = server_tick; + server_srand0 = srand0; server_sprite_hash.resize(0); if (flags & NETWORK_TICK_FLAG_CHECKSUMS) @@ -2872,11 +2889,17 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, const char* text = packet.ReadString(); if (text != nullptr) { - auto textLen = std::strlen(text); - server_sprite_hash.resize(textLen); - std::memcpy(server_sprite_hash.data(), text, textLen); + tickData.spriteHash = text; } } + + // Don't let the history grow too much. + while (_serverTickData.size() >= 100) + { + _serverTickData.erase(_serverTickData.begin()); + } + + _serverTickData.emplace(server_tick, tickData); } void Network::Client_Handle_PLAYERLIST([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) From 3c8480ee2623f6dca419a3ee5a04dbe5655440f3 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 12 Mar 2019 21:10:32 +0100 Subject: [PATCH 022/506] Remove unused variables and strip unused DEBUG_DESYNC paths. --- src/openrct2/network/Network.cpp | 4 -- src/openrct2/scenario/Scenario.cpp | 67 ------------------------------ 2 files changed, 71 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 7035065717..d9775e7c89 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -304,8 +304,6 @@ private: SOCKET_STATUS _lastConnectStatus = SOCKET_STATUS_CLOSED; uint32_t last_ping_sent_time = 0; uint32_t server_tick = 0; - uint32_t server_srand0 = 0; - std::string server_sprite_hash; uint8_t player_id = 0; std::list> client_connection_list; std::multiset game_command_queue; @@ -2882,8 +2880,6 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, tickData.srand0 = srand0; tickData.tick = server_tick; - server_srand0 = srand0; - server_sprite_hash.resize(0); if (flags & NETWORK_TICK_FLAG_CHECKSUMS) { const char* text = packet.ReadString(); diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 76761bc8c6..1e1be5e04f 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -493,78 +493,11 @@ void scenario_rand_seed(random_engine_t::result_type s0, random_engine_t::result * * @return eax */ -#ifndef DEBUG_DESYNC random_engine_t::result_type scenario_rand() -#else -static FILE* fp = nullptr; -static const char* realm = "LC"; - -uint32_t dbg_scenario_rand(const char* file, const char* function, const uint32_t line, const void* data) -#endif { -#ifdef DEBUG_DESYNC - if (fp == nullptr) - { - if (network_get_mode() == NETWORK_MODE_SERVER) - { - fp = fopen("server_rand.txt", "wt"); - realm = "SV"; - } - else if (network_get_mode() == NETWORK_MODE_CLIENT) - { - fp = fopen("client_rand.txt", "wt"); - realm = "CL"; - } - else - { - if (fp) - fclose(fp); - fp = nullptr; - realm = "LC"; - } - } - if (fp) - { - fprintf(fp, "Tick: %d, Rand: %08X - REF: %s:%u %s (%p)\n", gCurrentTicks, gScenarioSrand1, file, line, function, data); - } - if (!gInUpdateCode && !gInMapInitCode) - { - log_warning("scenario_rand called from outside game update"); - assert(false); - } -#endif - return gScenarioRand(); } -#ifdef DEBUG_DESYNC -void dbg_report_desync(uint32_t tick, uint32_t srand0, uint32_t server_srand0, const char* clientHash, const char* serverHash) -{ - if (fp == nullptr) - { - if (network_get_mode() == NETWORK_MODE_SERVER) - { - fp = fopen("server_rand.txt", "wt"); - realm = "SV"; - } - else if (network_get_mode() == NETWORK_MODE_CLIENT) - { - fp = fopen("client_rand.txt", "wt"); - realm = "CL"; - } - } - if (fp) - { - const bool sprites_mismatch = serverHash[0] != '\0' && strcmp(clientHash, serverHash); - - fprintf( - fp, "[%s] !! DESYNC !! Tick: %d, Client Hash: %s, Server Hash: %s, Client Rand: %08X, Server Rand: %08X - %s\n", - realm, tick, clientHash, ((serverHash[0] != '\0') ? serverHash : ""), srand0, server_srand0, - (sprites_mismatch ? "Sprite hash mismatch" : "scenario rand mismatch")); - } -} -#endif - uint32_t scenario_rand_max(uint32_t max) { if (max < 2) From 52c652098c19f7e0d6f03b4e1c7757e8ccf87eee Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 14 Mar 2019 13:44:38 +0100 Subject: [PATCH 023/506] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b1e7bdb4cc..aa498361f6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Fix: [#5579] Network desync immediately after connecting. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ From 126ffd104e974203e20233bda91b89567f5f8dc8 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 15 Mar 2019 03:12:20 +0100 Subject: [PATCH 024/506] Fix #8873: null dereference when trying to place footpath. --- distribution/changelog.txt | 1 + src/openrct2/actions/FootpathSceneryPlaceAction.hpp | 6 +++--- src/openrct2/world/Footpath.cpp | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index aa498361f6..472b25afee 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ - Fix: [#5579] Network desync immediately after connecting. +- Fix: [#8873] Potential crash when placing footpaths. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2/actions/FootpathSceneryPlaceAction.hpp b/src/openrct2/actions/FootpathSceneryPlaceAction.hpp index 7e7a3f7377..aee3269473 100644 --- a/src/openrct2/actions/FootpathSceneryPlaceAction.hpp +++ b/src/openrct2/actions/FootpathSceneryPlaceAction.hpp @@ -75,14 +75,14 @@ public: } auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); - auto pathElement = tileElement->AsPath(); - - if (pathElement == nullptr) + if (tileElement == nullptr) { log_error("Could not find path element."); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); } + auto pathElement = tileElement->AsPath(); + // No change if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAddition() == _pathItemType && !(pathElement->IsBroken())) diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 3795e43c5a..2dad1d9c03 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -112,11 +112,11 @@ static bool entrance_has_direction(TileElement* tileElement, int32_t direction) TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z) { - TileElement* tileElement; - - tileElement = map_get_first_element_at(x, y); + TileElement* tileElement = map_get_first_element_at(x, y); do { + if (tileElement == nullptr) + break; if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH && tileElement->base_height == z) return tileElement; } while (!(tileElement++)->IsLastForTile()); From 9249b0c887256c4e00526382fbb15ccc2754e29b Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 15 Mar 2019 01:40:43 +0100 Subject: [PATCH 025/506] Fix #8870: Use player index instead of id. --- src/openrct2-ui/windows/Player.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index 88316cbdff..7c6b99e3e9 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -400,6 +400,12 @@ void window_player_overview_paint(rct_window* w, rct_drawpixelinfo* dpi) void window_player_overview_invalidate(rct_window* w) { + int32_t playerIndex = network_get_player_index((uint8_t)w->number); + if (playerIndex == -1) + { + return; + } + if (window_player_page_widgets[w->page] != w->widgets) { w->widgets = window_player_page_widgets[w->page]; @@ -449,7 +455,7 @@ void window_player_overview_invalidate(rct_window* w) // Only enable kick button for other players const bool canKick = network_can_perform_action(network_get_current_player_group_index(), NETWORK_PERMISSION_KICK_PLAYER); - const bool isServer = network_get_player_flags(w->number) & NETWORK_PLAYER_FLAG_ISSERVER; + const bool isServer = network_get_player_flags(playerIndex) & NETWORK_PLAYER_FLAG_ISSERVER; const bool isOwnWindow = (network_get_current_player_id() == w->number); widget_set_enabled(w, WIDX_KICK, canKick && !isOwnWindow && !isServer); } From c84927306e962adf602dadecad51cd674870fd88 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 4 Mar 2019 16:57:01 +0000 Subject: [PATCH 026/506] Implement land/water lower raise --- src/openrct2-ui/windows/TopToolbar.cpp | 73 ++++++--- .../actions/GameActionRegistration.cpp | 8 + src/openrct2/actions/LandLowerAction.hpp | 145 +++++++++++++++++ src/openrct2/actions/LandRaiseAction.hpp | 140 ++++++++++++++++ src/openrct2/actions/WaterLowerAction.hpp | 146 +++++++++++++++++ src/openrct2/actions/WaterRaiseAction.hpp | 152 ++++++++++++++++++ src/openrct2/world/Map.cpp | 34 ++-- src/openrct2/world/Map.h | 7 + 8 files changed, 669 insertions(+), 36 deletions(-) create mode 100644 src/openrct2/actions/LandLowerAction.hpp create mode 100644 src/openrct2/actions/LandRaiseAction.hpp create mode 100644 src/openrct2/actions/WaterLowerAction.hpp create mode 100644 src/openrct2/actions/WaterRaiseAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index d28c609c2c..d1681b5efb 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -27,9 +27,13 @@ #include #include #include +#include +#include #include #include #include +#include +#include #include #include #include @@ -2331,16 +2335,21 @@ static void top_toolbar_tool_update_water(int16_t x, int16_t y) if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)) return; - money32 lower_cost = lower_water( - gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y, 0); + auto waterLowerAction = WaterLowerAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); + auto waterRaiseAction = WaterRaiseAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); - money32 raise_cost = raise_water( - gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y, 0); + auto res = GameActions::Query(&waterLowerAction); + money32 lowerCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; - if (gWaterToolRaiseCost != raise_cost || gWaterToolLowerCost != lower_cost) + res = GameActions::Query(&waterRaiseAction); + money32 raiseCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; + + if (gWaterToolRaiseCost != raiseCost || gWaterToolLowerCost != lowerCost) { - gWaterToolRaiseCost = raise_cost; - gWaterToolLowerCost = lower_cost; + gWaterToolRaiseCost = raiseCost; + gWaterToolLowerCost = lowerCost; window_invalidate_by_class(WC_WATER); } return; @@ -2422,16 +2431,21 @@ static void top_toolbar_tool_update_water(int16_t x, int16_t y) if (!state_changed) return; - money32 lower_cost = lower_water( - gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y, 0); + auto waterLowerAction = WaterLowerAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); + auto waterRaiseAction = WaterRaiseAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); - money32 raise_cost = raise_water( - gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y, 0); + auto res = GameActions::Query(&waterLowerAction); + money32 lowerCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; - if (gWaterToolRaiseCost != raise_cost || gWaterToolLowerCost != lower_cost) + res = GameActions::Query(&waterRaiseAction); + money32 raiseCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; + + if (gWaterToolRaiseCost != raiseCost || gWaterToolLowerCost != lowerCost) { - gWaterToolRaiseCost = raise_cost; - gWaterToolLowerCost = lower_cost; + gWaterToolRaiseCost = raiseCost; + gWaterToolLowerCost = lowerCost; window_invalidate_by_class(WC_WATER); } } @@ -2927,7 +2941,13 @@ static money32 selection_raise_land(uint8_t flags) } else { - return game_do_command(centreX, flags, centreY, xBounds, GAME_COMMAND_RAISE_LAND, gMapSelectType, yBounds); + auto landRaiseAction = LandRaiseAction( + { centreX, centreY }, + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, gMapSelectType); + auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::Execute(&landRaiseAction) + : GameActions::Query(&landRaiseAction); + + return res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } } @@ -2953,7 +2973,13 @@ static money32 selection_lower_land(uint8_t flags) } else { - return game_do_command(centreX, flags, centreY, xBounds, GAME_COMMAND_LOWER_LAND, gMapSelectType, yBounds); + auto landLowerAction = LandLowerAction( + { centreX, centreY }, + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, gMapSelectType); + auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::Execute(&landLowerAction) + : GameActions::Query(&landLowerAction); + + return res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } } @@ -3028,11 +3054,10 @@ static void window_top_toolbar_water_tool_drag(int16_t x, int16_t y) { gInputDragLastY += dx; - gGameCommandErrorTitle = STR_CANT_RAISE_WATER_LEVEL_HERE; + auto waterRaiseAction = WaterRaiseAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); + GameActions::Execute(&waterRaiseAction); - game_do_command( - gMapSelectPositionA.x, 1, gMapSelectPositionA.y, dx, GAME_COMMAND_RAISE_WATER, gMapSelectPositionB.x, - gMapSelectPositionB.y); gWaterToolRaiseCost = MONEY32_UNDEFINED; gWaterToolLowerCost = MONEY32_UNDEFINED; @@ -3045,11 +3070,9 @@ static void window_top_toolbar_water_tool_drag(int16_t x, int16_t y) { gInputDragLastY += dx; - gGameCommandErrorTitle = STR_CANT_LOWER_WATER_LEVEL_HERE; - - game_do_command( - gMapSelectPositionA.x, 1, gMapSelectPositionA.y, dx, GAME_COMMAND_LOWER_WATER, gMapSelectPositionB.x, - gMapSelectPositionB.y); + auto waterLowerAction = WaterLowerAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }); + GameActions::Execute(&waterLowerAction); gWaterToolRaiseCost = MONEY32_UNDEFINED; gWaterToolLowerCost = MONEY32_UNDEFINED; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index fa705b1681..d87adb6b4d 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -17,6 +17,8 @@ #include "FootpathSceneryRemoveAction.hpp" #include "GameAction.h" #include "GuestSetNameAction.hpp" +#include "LandLowerAction.hpp" +#include "LandRaiseAction.hpp" #include "LandSetHeightAction.hpp" #include "LargeSceneryRemoveAction.hpp" #include "LoadOrQuitAction.hpp" @@ -51,6 +53,8 @@ #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "WallRemoveAction.hpp" +#include "WaterLowerAction.hpp" +#include "WaterRaiseAction.hpp" #include "WaterSetHeightAction.hpp" namespace GameActions @@ -94,6 +98,8 @@ namespace GameActions Register(); Register(); Register(); + Register(); + Register(); Register(); Register(); Register(); @@ -101,5 +107,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/LandLowerAction.hpp b/src/openrct2/actions/LandLowerAction.hpp new file mode 100644 index 0000000000..e692446bac --- /dev/null +++ b/src/openrct2/actions/LandLowerAction.hpp @@ -0,0 +1,145 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../actions/LandSetHeightAction.hpp" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/RideData.h" +#include "../windows/Intent.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "../audio/audio.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(LandLowerAction, GAME_COMMAND_LOWER_LAND, GameActionResult) +{ +private: + CoordsXY _coords; + MapRange _range; + uint8_t _selectionType; + +public: + LandLowerAction() + { + } + LandLowerAction(CoordsXY coords, MapRange range, uint8_t selectionType) + : _coords(coords) + , _range(range) + , _selectionType(selectionType) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_coords) << DS_TAG(_range) << DS_TAG(_selectionType); + } + + 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(); + size_t tableRow = _selectionType; + + // The selections between MAP_SELECT_TYPE_FULL and MAP_SELECT_TYPE_EDGE_0 are not included in the tables + if (_selectionType >= MAP_SELECT_TYPE_EDGE_0 && _selectionType <= MAP_SELECT_TYPE_EDGE_3) + tableRow -= MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1; + + // Keep big coordinates within map boundaries + auto aX = std::max(32, _range.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, _range.GetRight()); + auto aY = std::max(32, _range.GetTop()); + auto bY = std::min(gMapSizeMaxXY, _range.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF }; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + if (isExecuting) + { + audio_play_sound_at_location( + SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF); + } + + uint8_t maxHeight = map_get_highest_land_height( + validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom()); + + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); + if (tileElement != nullptr) + { + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->base_height; + if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) + height += 2; + if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG) + height += 2; + + if (height >= maxHeight) + { + height = surfaceElement->base_height; + uint8_t currentSlope = surfaceElement->GetSlope(); + uint8_t newSlope = tile_element_lower_styles[tableRow][currentSlope]; + if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + height -= 2; + + newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; + + auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); + landSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + } + else + { + result->ErrorTitle = STR_CANT_LOWER_LAND_HERE; + return result; + } + } + } + } + } + + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + return res; + } +}; diff --git a/src/openrct2/actions/LandRaiseAction.hpp b/src/openrct2/actions/LandRaiseAction.hpp new file mode 100644 index 0000000000..3a863e77a5 --- /dev/null +++ b/src/openrct2/actions/LandRaiseAction.hpp @@ -0,0 +1,140 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../actions/LandSetHeightAction.hpp" +#include "../audio/audio.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/RideData.h" +#include "../windows/Intent.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(LandRaiseAction, GAME_COMMAND_RAISE_LAND, GameActionResult) +{ +private: + CoordsXY _coords; + MapRange _range; + uint8_t _selectionType; + +public: + LandRaiseAction() + { + } + LandRaiseAction(CoordsXY coords, MapRange range, uint8_t selectionType) + : _coords(coords) + , _range(range) + , _selectionType(selectionType) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_coords) << DS_TAG(_range) << DS_TAG(_selectionType); + } + + 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(); + size_t tableRow = _selectionType; + + // The selections between MAP_SELECT_TYPE_FULL and MAP_SELECT_TYPE_EDGE_0 are not included in the tables + if (_selectionType >= MAP_SELECT_TYPE_EDGE_0 && _selectionType <= MAP_SELECT_TYPE_EDGE_3) + tableRow -= MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1; + + // Keep big coordinates within map boundaries + auto aX = std::max(32, _range.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, _range.GetRight()); + auto aY = std::max(32, _range.GetTop()); + auto bY = std::min(gMapSizeMaxXY, _range.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF }; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + if (isExecuting) + { + audio_play_sound_at_location( + SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF); + } + + uint8_t minHeight = map_get_lowest_land_height( + validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom()); + + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); + if (tileElement != nullptr) + { + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->base_height; + + if (height <= minHeight) + { + uint8_t currentSlope = surfaceElement->GetSlope(); + uint8_t newSlope = tile_element_raise_styles[tableRow][currentSlope]; + if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + height += 2; + + newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; + + auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); + landSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + } + else + { + result->ErrorTitle = STR_CANT_RAISE_LAND_HERE; + return result; + } + } + } + } + } + + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + return res; + } +}; diff --git a/src/openrct2/actions/WaterLowerAction.hpp b/src/openrct2/actions/WaterLowerAction.hpp new file mode 100644 index 0000000000..6305cea67e --- /dev/null +++ b/src/openrct2/actions/WaterLowerAction.hpp @@ -0,0 +1,146 @@ +/***************************************************************************** + * 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 "WaterSetHeightAction.hpp" +#include "GameAction.h" + +DEFINE_GAME_ACTION(WaterLowerAction, GAME_COMMAND_LOWER_WATER, GameActionResult) +{ +private: + MapRange _range; + +public: + WaterLowerAction() + { + } + WaterLowerAction(MapRange range) + : _range(range) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_range); + } + + 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(); + + // Keep big coordinates within map boundaries + auto aX = std::max(32, _range.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, _range.GetRight()); + auto aY = std::max(32, _range.GetTop()); + auto bY = std::min(gMapSizeMaxXY, _range.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + res->Position.x = ((validRange.GetLeft() + validRange.GetRight()) / 2) + 16; + res->Position.y = ((validRange.GetTop() + validRange.GetBottom()) / 2) + 16; + int32_t z = tile_element_height(res->Position.x, res->Position.y); + int16_t waterHeight = z >> 16; + z &= 0xFFFF; + if (waterHeight != 0) + { + z = waterHeight; + } + res->Position.z = z; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + uint8_t minHeight = GetLowestHeight(); + bool hasChanged = false; + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); + if (tileElement != nullptr) + { + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->GetWaterHeight(); + if (height != 0) + { + height *= 2; + if (height < minHeight) + continue; + height -= 2; + auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); + waterSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) + : GameActions::QueryNested(&waterSetHeightAction); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + hasChanged = true; + } + else + { + result->ErrorTitle = STR_CANT_LOWER_WATER_LEVEL_HERE; + return result; + } + } + } + } + } + + if (isExecuting && hasChanged) + { + audio_play_sound_at_location(SOUND_LAYING_OUT_WATER, res->Position.x, res->Position.y, res->Position.z); + } + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + return res; + } + +private: + uint8_t GetLowestHeight() const + { + uint8_t minHeight{ 0 }; + for (int32_t y = _range.GetTop(); y <= _range.GetBottom(); y += 32) + { + for (int32_t x = _range.GetLeft(); x <= _range.GetRight(); x += 32) + { + TileElement* tile_element = map_get_surface_element_at({ x, y }); + if (tile_element != nullptr) + { + uint8_t height = tile_element->AsSurface()->GetWaterHeight(); + if (height != 0) + { + height *= 2; + if (height > minHeight) + minHeight = height; + } + } + } + } + + return minHeight; + } +}; diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp new file mode 100644 index 0000000000..7ff9989b62 --- /dev/null +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -0,0 +1,152 @@ +/***************************************************************************** + * 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 "GameAction.h" +#include "WaterSetHeightAction.hpp" + +DEFINE_GAME_ACTION(WaterRaiseAction, GAME_COMMAND_RAISE_WATER, GameActionResult) +{ +private: + MapRange _range; + +public: + WaterRaiseAction() + { + } + WaterRaiseAction(MapRange range) + : _range(range) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_range); + } + + 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(); + + // Keep big coordinates within map boundaries + auto aX = std::max(32, _range.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, _range.GetRight()); + auto aY = std::max(32, _range.GetTop()); + auto bY = std::min(gMapSizeMaxXY, _range.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + res->Position.x = ((validRange.GetLeft() + validRange.GetRight()) / 2) + 16; + res->Position.y = ((validRange.GetTop() + validRange.GetBottom()) / 2) + 16; + int32_t z = tile_element_height(res->Position.x, res->Position.y); + int16_t waterHeight = z >> 16; + z &= 0xFFFF; + if (waterHeight != 0) + { + z = waterHeight; + } + res->Position.z = z; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + uint8_t maxHeight = GetHighestHeight(); + bool hasChanged = false; + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); + if (tileElement != nullptr) + { + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->GetWaterHeight(); + if (height != 0) + { + height *= 2; + if (height > maxHeight) + continue; + height += 2; + } + else + { + height = surfaceElement->base_height + 2; + } + auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); + waterSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) + : GameActions::QueryNested(&waterSetHeightAction); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + hasChanged = true; + } + else + { + result->ErrorTitle = STR_CANT_RAISE_WATER_LEVEL_HERE; + return result; + } + } + } + } + + if (isExecuting && hasChanged) + { + audio_play_sound_at_location(SOUND_LAYING_OUT_WATER, res->Position.x, res->Position.y, res->Position.z); + } + // Force ride construction to recheck area + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; + + return res; + } + +private: + uint8_t GetHighestHeight() const + { + uint8_t maxHeight{ 255 }; + for (int32_t y = _range.GetTop(); y <= _range.GetBottom(); y += 32) + { + for (int32_t x = _range.GetLeft(); x <= _range.GetRight(); x += 32) + { + TileElement* tile_element = map_get_surface_element_at({ x, y }); + if (tile_element != nullptr) + { + uint8_t height = tile_element->AsSurface()->GetWaterHeight(); + if (height != 0) + { + height *= 2; + if (maxHeight > height) + { + maxHeight = height; + } + } + } + } + } + + return maxHeight; + } +}; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 2fd1c22770..60bf4c4952 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -15,6 +15,8 @@ #include "../Input.h" #include "../OpenRCT2.h" #include "../actions/FootpathRemoveAction.hpp" +#include "../actions/LandLowerAction.hpp" +#include "../actions/LandRaiseAction.hpp" #include "../actions/LandSetHeightAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" @@ -1015,11 +1017,10 @@ void game_command_change_surface_style( } // 0x00981A1E -#define SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT 0x20 // Table of pre-calculated surface slopes (32) when raising the land tile for a given selection (5) // 0x1F = new slope // 0x20 = base height increases -static constexpr const uint8_t tile_element_raise_styles[9][32] = { +const uint8_t tile_element_raise_styles[9][32] = { { 0x01, 0x1B, 0x03, 0x1B, 0x05, 0x21, 0x07, 0x21, 0x09, 0x1B, 0x0B, 0x1B, 0x0D, 0x21, 0x20, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x23, 0x18, 0x19, 0x1A, 0x3B, 0x1C, 0x29, 0x24, 0x1F }, // MAP_SELECT_TYPE_CORNER_0 // (absolute rotation) @@ -1045,7 +1046,7 @@ static constexpr const uint8_t tile_element_raise_styles[9][32] = { // Basically the inverse of the table above. // 0x1F = new slope // 0x20 = base height increases -static constexpr const uint8_t tile_element_lower_styles[9][32] = { +const uint8_t tile_element_lower_styles[9][32] = { { 0x2E, 0x00, 0x2E, 0x02, 0x3E, 0x04, 0x3E, 0x06, 0x2E, 0x08, 0x2E, 0x0A, 0x3E, 0x0C, 0x3E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x06, 0x18, 0x19, 0x1A, 0x0B, 0x1C, 0x0C, 0x3E, 0x1F }, // MAP_SELECT_TYPE_CORNER_0 { 0x2D, 0x2D, 0x00, 0x01, 0x2D, 0x2D, 0x04, 0x05, 0x3D, 0x3D, 0x08, 0x09, 0x3D, 0x3D, 0x0C, 0x0F, @@ -1167,7 +1168,7 @@ void game_command_set_land_ownership( } } -static uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax) +uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax) { xMin = std::max(xMin, 32); yMin = std::max(yMin, 32); @@ -1189,7 +1190,7 @@ static uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yM return min_height; } -static uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax) +uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax) { xMin = std::max(xMin, 32); yMin = std::max(yMin, 32); @@ -2089,16 +2090,27 @@ static money32 smooth_land( } // switch selectionType // Raise / lower the land tool selection area - int32_t commandType = raiseLand ? GAME_COMMAND_RAISE_LAND : GAME_COMMAND_LOWER_LAND; - int32_t mapLeftRight = mapLeft | (mapRight << 16); - int32_t mapTopBottom = mapTop | (mapBottom << 16); - money32 cost = game_do_command(centreX, flags, centreY, mapLeftRight, commandType, command & 0x7FFF, mapTopBottom); - if (cost == MONEY32_UNDEFINED) + GameActionResult::Ptr res; + if (raiseLand) + { + auto raiseLandAction = LandRaiseAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); + raiseLandAction.SetFlags(flags); + res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&raiseLandAction) + : GameActions::QueryNested(&raiseLandAction); + } + else + { + auto lowerLandAction = LandLowerAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); + lowerLandAction.SetFlags(flags); + res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&lowerLandAction) + : GameActions::QueryNested(&lowerLandAction); + } + if (res->Error != GA_ERROR::OK) { return MONEY32_UNDEFINED; } - totalCost += cost; + totalCost += res->Cost; gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; gCommandPosition.x = centreX; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 5bf2570356..302a1c6bc0 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -129,7 +129,12 @@ extern LocationXYZ16 gCommandPosition; extern bool gMapLandRightsUpdateSuccess; +constexpr auto SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT = 0x20; +extern const uint8_t tile_element_lower_styles[9][32]; +extern const uint8_t tile_element_raise_styles[9][32]; + void map_init(int32_t size); + void map_count_remaining_land_rights(); void map_strip_ghost_flag_from_elements(); void map_update_tile_pointers(); @@ -147,6 +152,8 @@ EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, bool ghost); int32_t tile_element_height(int32_t x, int32_t y); +uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax); +uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax); bool map_coord_is_connected(int32_t x, int32_t y, int32_t z, uint8_t faceDirection); void map_remove_provisional_elements(); void map_restore_provisional_elements(); From d8f764723f7c787f61b999f0925a8f99e0b0b07e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 4 Mar 2019 17:50:03 +0000 Subject: [PATCH 027/506] Remove old game command --- src/openrct2/Game.cpp | 8 +- src/openrct2/Game.h | 8 +- src/openrct2/world/Map.cpp | 378 ------------------------------------- src/openrct2/world/Map.h | 6 - 4 files changed, 8 insertions(+), 392 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index fc38e1bb4b..9ed6cf73e2 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1284,11 +1284,11 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, game_command_set_guest_name, game_command_set_staff_name, - game_command_raise_land, - game_command_lower_land, + nullptr, + nullptr, game_command_smooth_land, - game_command_raise_water, - game_command_lower_water, + nullptr, + nullptr, game_command_set_brakes_speed, game_command_hire_new_staff_member, game_command_set_staff_patrol, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 35bdde7acc..99a8cb3d83 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -42,11 +42,11 @@ enum GAME_COMMAND GAME_COMMAND_SET_RIDE_PRICE, // GA GAME_COMMAND_SET_GUEST_NAME, // GA GAME_COMMAND_SET_STAFF_NAME, // GA - GAME_COMMAND_RAISE_LAND, - GAME_COMMAND_LOWER_LAND, + GAME_COMMAND_RAISE_LAND, // GA + GAME_COMMAND_LOWER_LAND, // GA GAME_COMMAND_EDIT_LAND_SMOOTH, - GAME_COMMAND_RAISE_WATER, - GAME_COMMAND_LOWER_WATER, + GAME_COMMAND_RAISE_WATER, // GA + GAME_COMMAND_LOWER_WATER, // GA GAME_COMMAND_SET_BRAKES_SPEED, GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_PATROL, diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 60bf4c4952..4170987951 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1218,360 +1218,6 @@ uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, in return max_height; } -static money32 raise_land( - int32_t flags, int32_t x, int32_t y, int32_t z, int32_t point_a_x, int32_t point_a_y, int32_t point_b_x, int32_t point_b_y, - int32_t selectionType) -{ - money32 cost = 0; - size_t tableRow = selectionType; - - // The selections between MAP_SELECT_TYPE_FULL and MAP_SELECT_TYPE_EDGE_0 are not included in the tables - if (selectionType >= MAP_SELECT_TYPE_EDGE_0 && selectionType <= MAP_SELECT_TYPE_EDGE_3) - tableRow -= MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1; - - if ((flags & GAME_COMMAND_FLAG_APPLY) && gGameCommandNestLevel == 1) - { - audio_play_sound_at_location(SOUND_PLACE_ITEM, x, y, z); - } - - // Keep big coordinates within map boundaries - point_a_x = std::max(32, point_a_x); - point_b_x = std::min(gMapSizeMaxXY, point_b_x); - point_a_y = std::max(32, point_a_y); - point_b_y = std::min(gMapSizeMaxXY, point_b_y); - - uint8_t min_height = map_get_lowest_land_height(point_a_x, point_b_x, point_a_y, point_b_y); - - for (int32_t y_coord = point_a_y; y_coord <= point_b_y; y_coord += 32) - { - for (int32_t x_coord = point_a_x; x_coord <= point_b_x; x_coord += 32) - { - TileElement* tile_element = map_get_surface_element_at(x_coord / 32, y_coord / 32); - if (tile_element != nullptr) - { - uint8_t height = tile_element->base_height; - if (height <= min_height) - { - uint8_t raisedCorners = tile_element->AsSurface()->GetSlope(); - uint8_t slope = tile_element_raise_styles[tableRow][raisedCorners]; - - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - height += 2; - - slope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; - auto landSetHeightAction = LandSetHeightAction({ x_coord, y_coord }, height, slope); - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? landSetHeightAction.Execute() : landSetHeightAction.Query(); - - if (res->Error != GA_ERROR::OK) - { - return MONEY32_UNDEFINED; - } - cost += res->Cost; - } - } - } - } - - // Force ride construction to recheck area - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z; - return cost; -} - -static money32 lower_land( - int32_t flags, int32_t x, int32_t y, int32_t z, int32_t point_a_x, int32_t point_a_y, int32_t point_b_x, int32_t point_b_y, - int32_t selectionType) -{ - money32 cost = 0; - size_t tableRow = selectionType; - - // The selections between MAP_SELECT_TYPE_FULL and MAP_SELECT_TYPE_EDGE_0 are not included in the tables - if (selectionType >= MAP_SELECT_TYPE_EDGE_0 && selectionType <= MAP_SELECT_TYPE_EDGE_3) - tableRow -= MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1; - - // Keep big coordinates within map boundaries - point_a_x = std::max(32, point_a_x); - point_b_x = std::min(gMapSizeMaxXY, point_b_x); - point_a_y = std::max(32, point_a_y); - point_b_y = std::min(gMapSizeMaxXY, point_b_y); - - if ((flags & GAME_COMMAND_FLAG_APPLY) && gGameCommandNestLevel == 1) - { - audio_play_sound_at_location(SOUND_PLACE_ITEM, x, y, z); - } - - uint8_t max_height = map_get_highest_land_height(point_a_x, point_b_x, point_a_y, point_b_y); - - for (int32_t y_coord = point_a_y; y_coord <= point_b_y; y_coord += 32) - { - for (int32_t x_coord = point_a_x; x_coord <= point_b_x; x_coord += 32) - { - TileElement* tile_element = map_get_surface_element_at(x_coord / 32, y_coord / 32); - if (tile_element != nullptr) - { - uint8_t height = tile_element->base_height; - if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) - height += 2; - if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG) - height += 2; - - if (height >= max_height) - { - height = tile_element->base_height; - uint8_t currentSlope = tile_element->AsSurface()->GetSlope(); - uint8_t newSlope = tile_element_lower_styles[tableRow][currentSlope]; - if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - height -= 2; - - newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; - - auto landSetHeightAction = LandSetHeightAction({ x_coord, y_coord }, height, newSlope); - landSetHeightAction.SetFlags(flags); - - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - if (res->Error != GA_ERROR::OK) - { - return MONEY32_UNDEFINED; - } - cost += res->Cost; - } - } - } - } - - // Force ride construction to recheck area - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z; - return cost; -} - -money32 raise_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flags) -{ - money32 cost = 0; - bool waterHeightChanged = false; - - uint8_t max_height = 0xFF; - - x0 = std::max(x0, (int16_t)32); - y0 = std::max(y0, (int16_t)32); - x1 = std::min(x1, gMapSizeMaxXY); - y1 = std::min(y1, gMapSizeMaxXY); - - for (int32_t yi = y0; yi <= y1; yi += 32) - { - for (int32_t xi = x0; xi <= x1; xi += 32) - { - TileElement* tile_element = map_get_surface_element_at({ xi, yi }); - if (tile_element != nullptr) - { - uint8_t height = tile_element->base_height; - if (tile_element->AsSurface()->GetWaterHeight() > 0) - height = tile_element->AsSurface()->GetWaterHeight() * 2; - if (max_height > height) - max_height = height; - } - } - } - - for (int32_t yi = y0; yi <= y1; yi += 32) - { - for (int32_t xi = x0; xi <= x1; xi += 32) - { - TileElement* tile_element = map_get_surface_element_at({ xi, yi }); - if (tile_element != nullptr) - { - if (tile_element->base_height <= max_height) - { - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height > max_height) - continue; - height += 2; - } - else - { - height = tile_element->base_height + 2; - } - - auto waterSetHeightAction = WaterSetHeightAction({ xi, yi }, height); - waterSetHeightAction.SetFlags(flags); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&waterSetHeightAction) - : GameActions::QueryNested(&waterSetHeightAction); - if (res->Error != GA_ERROR::OK) - { - gGameCommandErrorText = res->ErrorMessage; - // set gCommonFormatArguments to res->ErrorArgs - return MONEY32_UNDEFINED; - } - - cost += res->Cost; - waterHeightChanged = true; - } - } - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - int32_t x = ((x0 + x1) / 2) + 16; - int32_t y = ((y0 + y1) / 2) + 16; - int32_t z = tile_element_height(x, y); - int16_t water_height_z = z >> 16; - int16_t base_height_z = z; - z = water_height_z; - if (z == 0) - z = base_height_z; - - LocationXYZ16 coord; - coord.x = x; - coord.y = y; - coord.z = z; - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z; - if (waterHeightChanged) - { - audio_play_sound_at_location(SOUND_LAYING_OUT_WATER, x, y, z); - } - } - - // Force ride construction to recheck area - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; - - return cost; -} - -money32 lower_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flags) -{ - money32 cost = 0; - bool waterHeightChanged = false; - - uint8_t min_height = 0; - - x0 = std::max(x0, (int16_t)32); - y0 = std::max(y0, (int16_t)32); - x1 = std::min(x1, gMapSizeMaxXY); - y1 = std::min(y1, gMapSizeMaxXY); - - for (int32_t yi = y0; yi <= y1; yi += 32) - { - for (int32_t xi = x0; xi <= x1; xi += 32) - { - TileElement* tile_element = map_get_surface_element_at({ xi, yi }); - if (tile_element != nullptr) - { - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height > min_height) - min_height = height; - } - } - } - } - - for (int32_t yi = y0; yi <= y1; yi += 32) - { - for (int32_t xi = x0; xi <= x1; xi += 32) - { - TileElement* tile_element = map_get_surface_element_at({ xi, yi }); - if (tile_element != nullptr) - { - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height < min_height) - continue; - height -= 2; - auto waterSetHeightAction = WaterSetHeightAction({ xi, yi }, height); - waterSetHeightAction.SetFlags(flags); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&waterSetHeightAction) - : GameActions::QueryNested(&waterSetHeightAction); - if (res->Error != GA_ERROR::OK) - { - gGameCommandErrorText = res->ErrorMessage; - // set gCommonFormatArguments to res->ErrorArgs - return MONEY32_UNDEFINED; - } - - cost += res->Cost; - waterHeightChanged = true; - } - } - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - int32_t x = ((x0 + x1) / 2) + 16; - int32_t y = ((y0 + y1) / 2) + 16; - int32_t z = tile_element_height(x, y); - int16_t water_height_z = z >> 16; - int16_t base_height_z = z; - z = water_height_z; - if (z == 0) - z = base_height_z; - - LocationXYZ16 coord; - coord.x = x; - coord.y = y; - coord.z = z; - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z; - if (waterHeightChanged) - { - audio_play_sound_at_location(SOUND_LAYING_OUT_WATER, x, y, z); - } - } - - // Force ride construction to recheck area - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; - - return cost; -} - -/** - * - * rct2: 0x0068C542 - */ -void game_command_raise_land( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - *ebx = raise_land( - *ebx, *eax, *ecx, tile_element_height(*eax, *ecx), (int16_t)(*edx & 0xFFFF), (int16_t)(*ebp & 0xFFFF), *edx >> 16, - *ebp >> 16, *edi & 0xFFFF); -} - -/** - * - * rct2: 0x0068C6D1 - */ -void game_command_lower_land( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - *ebx = lower_land( - *ebx, *eax, *ecx, tile_element_height(*eax, *ecx), (int16_t)(*edx & 0xFFFF), (int16_t)(*ebp & 0xFFFF), *edx >> 16, - *ebp >> 16, *edi & 0xFFFF); -} - static money32 smooth_land_tile( int32_t direction, uint8_t flags, int32_t x, int32_t y, TileElement* tileElement, bool raiseLand) { @@ -2137,30 +1783,6 @@ void game_command_smooth_land( *ebx = smooth_land(flags, centreX, centreY, mapLeft, mapTop, mapRight, mapBottom, command); } -/** - * - * rct2: 0x006E66A0 - */ -void game_command_raise_water( - int32_t* eax, int32_t* ebx, int32_t* ecx, [[maybe_unused]] int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - int32_t* ebp) -{ - *ebx = raise_water( - (int16_t)(*eax & 0xFFFF), (int16_t)(*ecx & 0xFFFF), (int16_t)(*edi & 0xFFFF), (int16_t)(*ebp & 0xFFFF), (uint8_t)*ebx); -} - -/** - * - * rct2: 0x006E6878 - */ -void game_command_lower_water( - int32_t* eax, int32_t* ebx, int32_t* ecx, [[maybe_unused]] int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - int32_t* ebp) -{ - *ebx = lower_water( - (int16_t)(*eax & 0xFFFF), (int16_t)(*ecx & 0xFFFF), (int16_t)(*edi & 0xFFFF), (int16_t)(*ebp & 0xFFFF), (uint8_t)*ebx); -} - bool map_is_location_at_edge(int32_t x, int32_t y) { return x < 32 || y < 32 || x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32) || y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 302a1c6bc0..b165ca3ebe 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -186,8 +186,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); money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t clear, int32_t flags); -money32 lower_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flags); -money32 raise_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flags); money32 wall_place( int32_t type, int32_t x, int32_t y, int32_t z, int32_t edge, int32_t primaryColour, int32_t secondaryColour, int32_t tertiaryColour, int32_t flags); @@ -206,11 +204,7 @@ void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_change_surface_style( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_raise_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_lower_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_smooth_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_raise_water(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_lower_water(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_wall(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); From 3ed08f897793e54c4611eaae3ecd7ceb84af1f4d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 5 Mar 2019 20:00:40 +0000 Subject: [PATCH 028/506] Fix formatting. Add missing header --- src/openrct2/actions/LandLowerAction.hpp | 2 +- src/openrct2/actions/WaterLowerAction.hpp | 3 ++- src/openrct2/actions/WaterRaiseAction.hpp | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/LandLowerAction.hpp b/src/openrct2/actions/LandLowerAction.hpp index e692446bac..665a13e0ac 100644 --- a/src/openrct2/actions/LandLowerAction.hpp +++ b/src/openrct2/actions/LandLowerAction.hpp @@ -12,6 +12,7 @@ #include "../Context.h" #include "../OpenRCT2.h" #include "../actions/LandSetHeightAction.hpp" +#include "../audio/audio.h" #include "../interface/Window.h" #include "../localisation/Localisation.h" #include "../localisation/StringIds.h" @@ -22,7 +23,6 @@ #include "../world/Scenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" -#include "../audio/audio.h" #include "GameAction.h" DEFINE_GAME_ACTION(LandLowerAction, GAME_COMMAND_LOWER_LAND, GameActionResult) diff --git a/src/openrct2/actions/WaterLowerAction.hpp b/src/openrct2/actions/WaterLowerAction.hpp index 6305cea67e..aea73e8815 100644 --- a/src/openrct2/actions/WaterLowerAction.hpp +++ b/src/openrct2/actions/WaterLowerAction.hpp @@ -9,8 +9,9 @@ #pragma once -#include "WaterSetHeightAction.hpp" +#include "../audio/audio.h" #include "GameAction.h" +#include "WaterSetHeightAction.hpp" DEFINE_GAME_ACTION(WaterLowerAction, GAME_COMMAND_LOWER_WATER, GameActionResult) { diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index 7ff9989b62..35aa094540 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -9,6 +9,7 @@ #pragma once +#include "../audio/audio.h" #include "GameAction.h" #include "WaterSetHeightAction.hpp" From 6a177e696bf08a2fec495d4a958275c11e321642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 11 Mar 2019 02:46:55 -0700 Subject: [PATCH 029/506] Update xcode project (#26) --- OpenRCT2.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index ead85e34e1..71dc46d782 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -1304,6 +1304,10 @@ C6E96E341E0408A80076A04F /* zipconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zipconf.h; sourceTree = ""; }; C6E96E351E0408B40076A04F /* libzip.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libzip.dylib; sourceTree = ""; }; C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceFromTrackAction.hpp; sourceTree = ""; }; + C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandRaiseAction.hpp; sourceTree = ""; }; + C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandLowerAction.hpp; sourceTree = ""; }; + C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterLowerAction.hpp; sourceTree = ""; }; + C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterRaiseAction.hpp; sourceTree = ""; }; D41B73EE1C2101890080A7B9 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/macos/Assets.xcassets; sourceTree = SOURCE_ROOT; }; @@ -2036,6 +2040,10 @@ isa = PBXGroup; children = ( C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */, + C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */, + C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */, + C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */, + C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */, 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */, 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */, 2A61CAF42229E5720095AD67 /* FootpathPlaceAction.hpp */, From cdabb7c3883bc56345841c2da849a2549ecc1d5e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 12 Mar 2019 17:43:31 +0000 Subject: [PATCH 030/506] Use continue to prevent nested brackets --- src/openrct2/actions/LandLowerAction.hpp | 64 ++++++++++---------- src/openrct2/actions/LandRaiseAction.hpp | 54 ++++++++--------- src/openrct2/actions/WaterLowerAction.hpp | 67 +++++++++++---------- src/openrct2/actions/WaterRaiseAction.hpp | 72 +++++++++++------------ 4 files changed, 130 insertions(+), 127 deletions(-) diff --git a/src/openrct2/actions/LandLowerAction.hpp b/src/openrct2/actions/LandLowerAction.hpp index 665a13e0ac..0ef06089ca 100644 --- a/src/openrct2/actions/LandLowerAction.hpp +++ b/src/openrct2/actions/LandLowerAction.hpp @@ -100,39 +100,39 @@ private: for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) { TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); - if (tileElement != nullptr) + if (tileElement == nullptr) + continue; + + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->base_height; + if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) + height += 2; + if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG) + height += 2; + + if (height < maxHeight) + continue; + + height = surfaceElement->base_height; + uint8_t currentSlope = surfaceElement->GetSlope(); + uint8_t newSlope = tile_element_lower_styles[tableRow][currentSlope]; + if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + height -= 2; + + newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; + + auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); + landSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + if (result->Error == GA_ERROR::OK) { - SurfaceElement* surfaceElement = tileElement->AsSurface(); - uint8_t height = surfaceElement->base_height; - if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) - height += 2; - if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG) - height += 2; - - if (height >= maxHeight) - { - height = surfaceElement->base_height; - uint8_t currentSlope = surfaceElement->GetSlope(); - uint8_t newSlope = tile_element_lower_styles[tableRow][currentSlope]; - if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - height -= 2; - - newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; - - auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); - landSetHeightAction.SetFlags(GetFlags()); - auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - if (result->Error == GA_ERROR::OK) - { - res->Cost += result->Cost; - } - else - { - result->ErrorTitle = STR_CANT_LOWER_LAND_HERE; - return result; - } - } + res->Cost += result->Cost; + } + else + { + result->ErrorTitle = STR_CANT_LOWER_LAND_HERE; + return result; } } } diff --git a/src/openrct2/actions/LandRaiseAction.hpp b/src/openrct2/actions/LandRaiseAction.hpp index 3a863e77a5..fb2ddd40a2 100644 --- a/src/openrct2/actions/LandRaiseAction.hpp +++ b/src/openrct2/actions/LandRaiseAction.hpp @@ -100,34 +100,34 @@ private: for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) { TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); - if (tileElement != nullptr) + if (tileElement == nullptr) + continue; + + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->base_height; + + if (height > minHeight) + continue; + + uint8_t currentSlope = surfaceElement->GetSlope(); + uint8_t newSlope = tile_element_raise_styles[tableRow][currentSlope]; + if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + height += 2; + + newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; + + auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); + landSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + if (result->Error == GA_ERROR::OK) { - SurfaceElement* surfaceElement = tileElement->AsSurface(); - uint8_t height = surfaceElement->base_height; - - if (height <= minHeight) - { - uint8_t currentSlope = surfaceElement->GetSlope(); - uint8_t newSlope = tile_element_raise_styles[tableRow][currentSlope]; - if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - height += 2; - - newSlope &= TILE_ELEMENT_SURFACE_SLOPE_MASK; - - auto landSetHeightAction = LandSetHeightAction({ x, y }, height, newSlope); - landSetHeightAction.SetFlags(GetFlags()); - auto result = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - if (result->Error == GA_ERROR::OK) - { - res->Cost += result->Cost; - } - else - { - result->ErrorTitle = STR_CANT_RAISE_LAND_HERE; - return result; - } - } + res->Cost += result->Cost; + } + else + { + result->ErrorTitle = STR_CANT_RAISE_LAND_HERE; + return result; } } } diff --git a/src/openrct2/actions/WaterLowerAction.hpp b/src/openrct2/actions/WaterLowerAction.hpp index aea73e8815..5671f49938 100644 --- a/src/openrct2/actions/WaterLowerAction.hpp +++ b/src/openrct2/actions/WaterLowerAction.hpp @@ -81,31 +81,32 @@ private: for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) { TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); - if (tileElement != nullptr) + if (tileElement == nullptr) + continue; + + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->GetWaterHeight(); + if (height == 0) + continue; + + height *= 2; + if (height < minHeight) + continue; + + height -= 2; + auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); + waterSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) + : GameActions::QueryNested(&waterSetHeightAction); + if (result->Error == GA_ERROR::OK) { - SurfaceElement* surfaceElement = tileElement->AsSurface(); - uint8_t height = surfaceElement->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height < minHeight) - continue; - height -= 2; - auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); - waterSetHeightAction.SetFlags(GetFlags()); - auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) - : GameActions::QueryNested(&waterSetHeightAction); - if (result->Error == GA_ERROR::OK) - { - res->Cost += result->Cost; - hasChanged = true; - } - else - { - result->ErrorTitle = STR_CANT_LOWER_WATER_LEVEL_HERE; - return result; - } - } + res->Cost += result->Cost; + hasChanged = true; + } + else + { + result->ErrorTitle = STR_CANT_LOWER_WATER_LEVEL_HERE; + return result; } } } @@ -129,15 +130,17 @@ private: for (int32_t x = _range.GetLeft(); x <= _range.GetRight(); x += 32) { TileElement* tile_element = map_get_surface_element_at({ x, y }); - if (tile_element != nullptr) + if (tile_element == nullptr) + continue; + + uint8_t height = tile_element->AsSurface()->GetWaterHeight(); + if (height == 0) + continue; + + height *= 2; + if (height > minHeight) { - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height > minHeight) - minHeight = height; - } + minHeight = height; } } } diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index 35aa094540..65b4104859 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -81,35 +81,35 @@ private: for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) { TileElement* tileElement = map_get_surface_element_at(x / 32, y / 32); - if (tileElement != nullptr) + if (tileElement == nullptr) + continue; + + SurfaceElement* surfaceElement = tileElement->AsSurface(); + uint8_t height = surfaceElement->GetWaterHeight(); + if (height != 0) { - SurfaceElement* surfaceElement = tileElement->AsSurface(); - uint8_t height = surfaceElement->GetWaterHeight(); - if (height != 0) - { - height *= 2; - if (height > maxHeight) - continue; - height += 2; - } - else - { - height = surfaceElement->base_height + 2; - } - auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); - waterSetHeightAction.SetFlags(GetFlags()); - auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) - : GameActions::QueryNested(&waterSetHeightAction); - if (result->Error == GA_ERROR::OK) - { - res->Cost += result->Cost; - hasChanged = true; - } - else - { - result->ErrorTitle = STR_CANT_RAISE_WATER_LEVEL_HERE; - return result; - } + height *= 2; + if (height > maxHeight) + continue; + height += 2; + } + else + { + height = surfaceElement->base_height + 2; + } + auto waterSetHeightAction = WaterSetHeightAction({ x, y }, height); + waterSetHeightAction.SetFlags(GetFlags()); + auto result = isExecuting ? GameActions::ExecuteNested(&waterSetHeightAction) + : GameActions::QueryNested(&waterSetHeightAction); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + hasChanged = true; + } + else + { + result->ErrorTitle = STR_CANT_RAISE_WATER_LEVEL_HERE; + return result; } } } @@ -133,16 +133,16 @@ private: for (int32_t x = _range.GetLeft(); x <= _range.GetRight(); x += 32) { TileElement* tile_element = map_get_surface_element_at({ x, y }); - if (tile_element != nullptr) + if (tile_element == nullptr) + continue; + + uint8_t height = tile_element->AsSurface()->GetWaterHeight(); + if (height != 0) { - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) + height *= 2; + if (maxHeight > height) { - height *= 2; - if (maxHeight > height) - { - maxHeight = height; - } + maxHeight = height; } } } From cd6c9b7b152598cd4b90f28fe1b7e34c66165526 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 15 Mar 2019 20:11:06 +0000 Subject: [PATCH 031/506] Fix set brakes speed action --- src/openrct2/actions/TrackSetBrakeSpeedAction.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp index c3b60556f8..297f2fd565 100644 --- a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp +++ b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp @@ -59,7 +59,7 @@ private: res->Position.y += 16; res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; - TileElement* tileElement = map_get_track_element_at_of_type(_loc.x / 32, _loc.y / 32, _loc.z / 8, _trackType); + TileElement* tileElement = map_get_track_element_at_of_type(_loc.x, _loc.y, _loc.z / 8, _trackType); if (tileElement == nullptr) { log_warning("Invalid game command for setting brakes speed. x = %d, y = %d", _loc.x, _loc.y); From 0c46475d07b4bbc8b8504ad3728582a7537306e5 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 15 Mar 2019 20:12:10 +0000 Subject: [PATCH 032/506] 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 d9775e7c89..a50594001b 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 "1" +#define NETWORK_STREAM_VERSION "2" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 2090cbefae8bb613725248e9cc7d6c9c9b0efbd6 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 15 Mar 2019 21:27:06 +0100 Subject: [PATCH 033/506] Fix #8851: Show only game action errors to the issuer. --- src/openrct2/actions/GameAction.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 015e174338..c07bfe2a82 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -357,7 +357,19 @@ namespace GameActions cb(action, result.get()); } - if (result->Error != GA_ERROR::OK && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5)) + // Only show errors when its not a ghost and not a preview and also top level action. + bool shouldShowError = !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5) && topLevel == true; + + // In network mode the error should be only shown to the issuer of the action. + if (network_get_mode() != NETWORK_MODE_NONE) + { + if (action->GetPlayer() != network_get_current_player_id()) + { + shouldShowError = false; + } + } + + if (result->Error != GA_ERROR::OK && shouldShowError == true) { // Show the error box std::copy(result->ErrorMessageArgs.begin(), result->ErrorMessageArgs.end(), gCommonFormatArgs); From 9a1532ecc4ee9c1b1e6fca6d39f55d7f44791b72 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 15 Mar 2019 20:53:17 +0000 Subject: [PATCH 034/506] Add ParkSetParameterAction --- src/openrct2-ui/windows/Park.cpp | 10 +- src/openrct2-ui/windows/Ride.cpp | 13 ++- src/openrct2/Cheats.cpp | 2 +- src/openrct2/Game.cpp | 20 +--- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/ParkSetParameterAction.hpp | 99 +++++++++++++++++++ src/openrct2/world/Park.cpp | 52 +--------- src/openrct2/world/Park.h | 4 +- 9 files changed, 122 insertions(+), 82 deletions(-) create mode 100644 src/openrct2/actions/ParkSetParameterAction.hpp diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index ebd224fc6d..90952ddd85 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -658,10 +658,10 @@ static void window_park_entrance_mouseup(rct_window* w, rct_widgetindex widgetIn window_text_input_open(w, WIDX_RENAME, STR_PARK_NAME, STR_ENTER_PARK_NAME, gParkName, 0, USER_STRING_MAX_LENGTH); break; case WIDX_CLOSE_LIGHT: - park_set_open(0); + park_set_open(false); break; case WIDX_OPEN_LIGHT: - park_set_open(1); + park_set_open(true); break; } } @@ -718,13 +718,11 @@ static void window_park_entrance_dropdown(rct_window* w, rct_widgetindex widgetI if (dropdownIndex != 0) { - gGameCommandErrorTitle = STR_CANT_CLOSE_PARK; - park_set_open(1); + park_set_open(true); } else { - gGameCommandErrorTitle = STR_CANT_OPEN_PARK; - park_set_open(0); + park_set_open(false); } } } diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 01d596c6b6..8e2d671e3c 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -6157,11 +6158,13 @@ static void update_same_price_throughout_flags(uint32_t shop_item) { newFlags = gSamePriceThroughoutParkA; newFlags ^= (1 << SHOP_ITEM_PHOTO); - game_do_command(0, 1, 0, (0x2 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item); + auto parkSetParameterA = ParkSetParameterAction(ParkParameter::SamePriceInParkA, shop_item); + GameActions::Execute(&parkSetParameterA); newFlags = gSamePriceThroughoutParkB; newFlags ^= (1 << (SHOP_ITEM_PHOTO2 - 32)) | (1 << (SHOP_ITEM_PHOTO3 - 32)) | (1 << (SHOP_ITEM_PHOTO4 - 32)); - game_do_command(0, 1, 0, (0x3 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item); + auto parkSetParameterB = ParkSetParameterAction(ParkParameter::SamePriceInParkB, shop_item); + GameActions::Execute(&parkSetParameterB); } else { @@ -6169,13 +6172,15 @@ static void update_same_price_throughout_flags(uint32_t shop_item) { newFlags = gSamePriceThroughoutParkA; newFlags ^= (1u << shop_item); - game_do_command(0, 1, 0, (0x2 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item); + auto parkSetParameterA = ParkSetParameterAction(ParkParameter::SamePriceInParkA, shop_item); + GameActions::Execute(&parkSetParameterA); } else { newFlags = gSamePriceThroughoutParkB; newFlags ^= (1u << (shop_item - 32)); - game_do_command(0, 1, 0, (0x3 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item); + auto parkSetParameterB = ParkSetParameterAction(ParkParameter::SamePriceInParkB, shop_item); + GameActions::Execute(&parkSetParameterB); } } } diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index a46c25fca9..69c83e064f 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -620,7 +620,7 @@ void game_command_cheat( gCheatsNeverendingMarketing = *edx != 0; break; case CHEAT_OPENCLOSEPARK: - park_set_open(park_is_open() ? 0 : 1); + park_set_open(!park_is_open()); break; case CHEAT_HAVEFUN: gScenarioObjectiveType = OBJECTIVE_HAVE_FUN; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 791f428806..0cf28b57fd 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -611,24 +611,6 @@ 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_SET_PARK_OPEN) - { - // Log change in park open/close - char* args[1] = { - (char*)player_name, - }; - - if (*edx >> 8 == 0) - { - format_string(log_msg, 256, STR_LOG_PARK_OPEN, args); - } - else if (*edx >> 8 == 1) - { - format_string(log_msg, 256, STR_LOG_PARK_CLOSED, args); - } - - network_append_server_log(log_msg); - } else if ( command == GAME_COMMAND_PLACE_WALL || command == GAME_COMMAND_PLACE_LARGE_SCENERY || command == GAME_COMMAND_PLACE_BANNER) @@ -1295,7 +1277,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_fire_staff_member, nullptr, nullptr, - game_command_set_park_open, + nullptr, game_command_buy_land_rights, game_command_place_park_entrance, game_command_remove_park_entrance, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index e0b759675a..5c5f3d034e 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -53,7 +53,7 @@ enum GAME_COMMAND GAME_COMMAND_FIRE_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_ORDERS, // GA GAME_COMMAND_SET_PARK_NAME, // GA - GAME_COMMAND_SET_PARK_OPEN, + GAME_COMMAND_SET_PARK_OPEN, // GA GAME_COMMAND_BUY_LAND_RIGHTS, GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA GAME_COMMAND_REMOVE_PARK_ENTRANCE, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index cf6fd67727..39dc69345d 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -26,6 +26,7 @@ #include "ParkMarketingAction.hpp" #include "ParkSetLoanAction.hpp" #include "ParkSetNameAction.hpp" +#include "ParkSetParameterAction.hpp" #include "ParkSetResearchFundingAction.hpp" #include "PauseToggleAction.hpp" #include "PlaceParkEntranceAction.hpp" @@ -75,6 +76,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/ParkSetParameterAction.hpp b/src/openrct2/actions/ParkSetParameterAction.hpp new file mode 100644 index 0000000000..1d2e0913c5 --- /dev/null +++ b/src/openrct2/actions/ParkSetParameterAction.hpp @@ -0,0 +1,99 @@ +/***************************************************************************** + * 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 "../interface/Window.h" +#include "../ride/ShopItem.h" +#include "../world/Park.h" +#include "GameAction.h" + +enum class ParkParameter : uint8_t +{ + Close, + Open, + SamePriceInParkA, + SamePriceInParkB, + Count +}; + +DEFINE_GAME_ACTION(ParkSetParameterAction, GAME_COMMAND_SET_PARK_OPEN, GameActionResult) +{ +private: + uint8_t _parameter; + uint32_t _value; + + constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_CLOSE_PARK, STR_CANT_OPEN_PARK, STR_NONE, STR_NONE }; + +public: + ParkSetParameterAction() + { + } + ParkSetParameterAction(ParkParameter parameter, uint32_t value = 0) + : _parameter(static_cast(parameter)) + , _value(value) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_parameter) << DS_TAG(_value); + } + + GameActionResult::Ptr Query() const override + { + if (_parameter >= static_cast(ParkParameter::Count)) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + auto res = MakeResult(); + res->ErrorTitle = _ErrorTitles[_parameter]; + return res; + } + + GameActionResult::Ptr Execute() const override + { + switch (static_cast(_parameter)) + { + case ParkParameter::Close: + if (gParkFlags & PARK_FLAGS_PARK_OPEN) + { + gParkFlags &= ~PARK_FLAGS_PARK_OPEN; + window_invalidate_by_class(WC_PARK_INFORMATION); + } + break; + case ParkParameter::Open: + if (!(gParkFlags & PARK_FLAGS_PARK_OPEN)) + { + gParkFlags |= PARK_FLAGS_PARK_OPEN; + window_invalidate_by_class(WC_PARK_INFORMATION); + } + break; + case ParkParameter::SamePriceInParkA: + gSamePriceThroughoutParkA = _value; + window_invalidate_by_class(WC_RIDE); + break; + case ParkParameter::SamePriceInParkB: + gSamePriceThroughoutParkB = _value; + window_invalidate_by_class(WC_RIDE); + break; + } + + auto res = MakeResult(); + res->ErrorTitle = _ErrorTitles[_parameter]; + return res; + } +}; diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index ea5c163742..3b8845cb68 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -15,6 +15,7 @@ #include "../Game.h" #include "../GameState.h" #include "../OpenRCT2.h" +#include "../actions/ParkSetParameterAction.hpp" #include "../config/Config.h" #include "../core/Memory.hpp" #include "../interface/Colour.h" @@ -104,55 +105,10 @@ static PeepSpawn* get_random_peep_spawn() } } -void park_set_open(int32_t open) +void park_set_open(bool open) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, open << 8, GAME_COMMAND_SET_PARK_OPEN, 0, 0); -} - -/** - * - * rct2: 0x00669D4A - */ -void game_command_set_park_open( - [[maybe_unused]] int32_t* eax, int32_t* ebx, [[maybe_unused]] int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) - { - *ebx = 0; - return; - } - - int32_t dh = (*edx >> 8) & 0xFF; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_PARK_ENTRANCE_TICKETS; - switch (dh) - { - case 0: - if (gParkFlags & PARK_FLAGS_PARK_OPEN) - { - gParkFlags &= ~PARK_FLAGS_PARK_OPEN; - window_invalidate_by_class(WC_PARK_INFORMATION); - } - break; - case 1: - if (!(gParkFlags & PARK_FLAGS_PARK_OPEN)) - { - gParkFlags |= PARK_FLAGS_PARK_OPEN; - window_invalidate_by_class(WC_PARK_INFORMATION); - } - break; - case 2: - gSamePriceThroughoutParkA = *edi; - window_invalidate_by_class(WC_RIDE); - break; - case 3: - gSamePriceThroughoutParkB = *edi; - window_invalidate_by_class(WC_RIDE); - break; - } - - *ebx = 0; + auto parkSetParameter = ParkSetParameterAction(open ? ParkParameter::Open : ParkParameter::Close); + GameActions::Execute(&parkSetParameter); } /** diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index cd54738bc9..60163cca04 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -132,7 +132,7 @@ void update_park_fences_around_tile(CoordsXY coords); uint8_t calculate_guest_initial_happiness(uint8_t percentage); -void park_set_open(int32_t open); +void park_set_open(bool open); int32_t park_entrance_get_index(int32_t x, int32_t y, int32_t z); void park_set_name(const char* name); void park_set_entrance_fee(money32 value); @@ -141,8 +141,6 @@ int32_t map_buy_land_rights(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int3 void game_command_set_park_entrance_fee( 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_park_open( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_buy_land_rights( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); From 0e50d438d7ff3026bd2c5e4d29d27eba55e48f9a Mon Sep 17 00:00:00 2001 From: Phillip Walters Date: Fri, 15 Mar 2019 20:31:30 -0700 Subject: [PATCH 035/506] Added console logging for failed map saves --- src/openrct2/rct2/S6Importer.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 1cd13ac8f0..2bc500f693 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -8,6 +8,7 @@ *****************************************************************************/ #include "../Context.h" +#include "../Diagnostic.h" #include "../Game.h" #include "../GameState.h" #include "../OpenRCT2.h" @@ -1412,10 +1413,11 @@ void load_from_sv6(const char* path) gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA; } - catch (const IOException&) + catch (const IOException& loadError) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; + log_error("Error loading: %s\n", loadError.what()); } catch (const std::exception&) { @@ -1443,15 +1445,17 @@ void load_from_sc6(const char* path) sprite_position_tween_reset(); return; } - catch (const ObjectLoadException&) + catch (const ObjectLoadException& loadError) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; + log_error("Error loading: %s\n", loadError.what()); } - catch (const IOException&) + catch (const IOException& loadError) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; + log_error("Error loading: %s\n", loadError.what()); } catch (const std::exception&) { From 78ede8758b3cc0b44c18f97aeee12912885c1d31 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 07:15:12 +0000 Subject: [PATCH 036/506] Add a default to the switch --- src/openrct2/actions/ParkSetParameterAction.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openrct2/actions/ParkSetParameterAction.hpp b/src/openrct2/actions/ParkSetParameterAction.hpp index 1d2e0913c5..7cbc34fd29 100644 --- a/src/openrct2/actions/ParkSetParameterAction.hpp +++ b/src/openrct2/actions/ParkSetParameterAction.hpp @@ -90,6 +90,9 @@ public: gSamePriceThroughoutParkB = _value; window_invalidate_by_class(WC_RIDE); break; + default: + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + break; } auto res = MakeResult(); From 24e94287310b137e09f6e7a3a78f5e1911912b30 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 07:33:21 +0000 Subject: [PATCH 037/506] Use 64bit values to simplify code --- src/openrct2-ui/windows/Ride.cpp | 34 ++++++------------- .../actions/ParkSetParameterAction.hpp | 15 +++----- src/openrct2/rct2/S6Exporter.cpp | 4 +-- src/openrct2/rct2/S6Importer.cpp | 3 +- src/openrct2/ride/ShopItem.cpp | 12 ++----- src/openrct2/ride/ShopItem.h | 3 +- 6 files changed, 21 insertions(+), 50 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 8e2d671e3c..65459dce12 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -6152,36 +6152,22 @@ static utf8 _moneyInputText[MONEY_STRING_MAXLENGTH]; static void update_same_price_throughout_flags(uint32_t shop_item) { - uint32_t newFlags; + uint64_t newFlags; if (shop_item_is_photo(shop_item)) { - newFlags = gSamePriceThroughoutParkA; - newFlags ^= (1 << SHOP_ITEM_PHOTO); - auto parkSetParameterA = ParkSetParameterAction(ParkParameter::SamePriceInParkA, shop_item); - GameActions::Execute(&parkSetParameterA); - - newFlags = gSamePriceThroughoutParkB; - newFlags ^= (1 << (SHOP_ITEM_PHOTO2 - 32)) | (1 << (SHOP_ITEM_PHOTO3 - 32)) | (1 << (SHOP_ITEM_PHOTO4 - 32)); - auto parkSetParameterB = ParkSetParameterAction(ParkParameter::SamePriceInParkB, shop_item); - GameActions::Execute(&parkSetParameterB); + newFlags = gSamePriceThroughoutPark; + newFlags ^= (1ULL << SHOP_ITEM_PHOTO) | (1ULL << SHOP_ITEM_PHOTO2) | (1ULL << SHOP_ITEM_PHOTO3) + | (1ULL << SHOP_ITEM_PHOTO4); + auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, shop_item); + GameActions::Execute(&parkSetParameter); } else { - if (shop_item < 32) - { - newFlags = gSamePriceThroughoutParkA; - newFlags ^= (1u << shop_item); - auto parkSetParameterA = ParkSetParameterAction(ParkParameter::SamePriceInParkA, shop_item); - GameActions::Execute(&parkSetParameterA); - } - else - { - newFlags = gSamePriceThroughoutParkB; - newFlags ^= (1u << (shop_item - 32)); - auto parkSetParameterB = ParkSetParameterAction(ParkParameter::SamePriceInParkB, shop_item); - GameActions::Execute(&parkSetParameterB); - } + newFlags = gSamePriceThroughoutPark; + newFlags ^= (1ULL << shop_item); + auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, shop_item); + GameActions::Execute(&parkSetParameter); } } diff --git a/src/openrct2/actions/ParkSetParameterAction.hpp b/src/openrct2/actions/ParkSetParameterAction.hpp index 7cbc34fd29..6fc33aee35 100644 --- a/src/openrct2/actions/ParkSetParameterAction.hpp +++ b/src/openrct2/actions/ParkSetParameterAction.hpp @@ -18,8 +18,7 @@ enum class ParkParameter : uint8_t { Close, Open, - SamePriceInParkA, - SamePriceInParkB, + SamePriceInPark, Count }; @@ -27,7 +26,7 @@ DEFINE_GAME_ACTION(ParkSetParameterAction, GAME_COMMAND_SET_PARK_OPEN, GameActio { private: uint8_t _parameter; - uint32_t _value; + uint64_t _value; constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_CLOSE_PARK, STR_CANT_OPEN_PARK, STR_NONE, STR_NONE }; @@ -35,7 +34,7 @@ public: ParkSetParameterAction() { } - ParkSetParameterAction(ParkParameter parameter, uint32_t value = 0) + ParkSetParameterAction(ParkParameter parameter, uint64_t value = 0) : _parameter(static_cast(parameter)) , _value(value) { @@ -82,12 +81,8 @@ public: window_invalidate_by_class(WC_PARK_INFORMATION); } break; - case ParkParameter::SamePriceInParkA: - gSamePriceThroughoutParkA = _value; - window_invalidate_by_class(WC_RIDE); - break; - case ParkParameter::SamePriceInParkB: - gSamePriceThroughoutParkB = _value; + case ParkParameter::SamePriceInPark: + gSamePriceThroughoutPark = _value; window_invalidate_by_class(WC_RIDE); break; default: diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 21849810c3..1f0eef0b71 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -316,7 +316,7 @@ void S6Exporter::Export() _s6.map_size_minus_2 = gMapSizeMinus2; _s6.map_size = gMapSize; _s6.map_max_xy = gMapSizeMaxXY; - _s6.same_price_throughout = gSamePriceThroughoutParkA; + _s6.same_price_throughout = gSamePriceThroughoutPark & 0xFFFFFFFF; _s6.suggested_max_guests = _suggestedGuestMaximum; _s6.park_rating_warning_days = gScenarioParkRatingWarningDays; _s6.last_entrance_style = gLastEntranceStyle; @@ -328,7 +328,7 @@ void S6Exporter::Export() String::Set(_s6.scenario_description, sizeof(_s6.scenario_description), gScenarioDetails.c_str()); _s6.current_interest_rate = gBankLoanInterestRate; // pad_0135934B - _s6.same_price_throughout_extended = gSamePriceThroughoutParkB; + _s6.same_price_throughout_extended = gSamePriceThroughoutPark >> 32; // Preserve compatibility with vanilla RCT2's save format. for (uint8_t i = 0; i < RCT12_MAX_PARK_ENTRANCES; i++) { diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 1cd13ac8f0..65578f8b94 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -334,7 +334,7 @@ public: gMapSizeMinus2 = _s6.map_size_minus_2; gMapSize = _s6.map_size; gMapSizeMaxXY = _s6.map_max_xy; - gSamePriceThroughoutParkA = _s6.same_price_throughout; + gSamePriceThroughoutPark = _s6.same_price_throughout | (static_cast(_s6.same_price_throughout_extended) << 32); _suggestedGuestMaximum = _s6.suggested_max_guests; gScenarioParkRatingWarningDays = _s6.park_rating_warning_days; gLastEntranceStyle = _s6.last_entrance_style; @@ -346,7 +346,6 @@ public: gScenarioDetails = std::string_view(_s6.scenario_description, sizeof(_s6.scenario_description)); gBankLoanInterestRate = _s6.current_interest_rate; // pad_0135934B - gSamePriceThroughoutParkB = _s6.same_price_throughout_extended; // Preserve compatibility with vanilla RCT2's save format. gParkEntrances.clear(); for (uint8_t i = 0; i < RCT12_MAX_PARK_ENTRANCES; i++) diff --git a/src/openrct2/ride/ShopItem.cpp b/src/openrct2/ride/ShopItem.cpp index b317066dca..4606bf2392 100644 --- a/src/openrct2/ride/ShopItem.cpp +++ b/src/openrct2/ride/ShopItem.cpp @@ -13,8 +13,7 @@ #include "../localisation/StringIds.h" #include "../sprites.h" -uint32_t gSamePriceThroughoutParkA; -uint32_t gSamePriceThroughoutParkB; +uint64_t gSamePriceThroughoutPark; /** rct2: 0x00982164 */ static const rct_shop_item_stats ShopItemStats[SHOP_ITEM_COUNT] = { @@ -313,14 +312,7 @@ bool shop_item_is_photo(int32_t shopItem) bool shop_item_has_common_price(int32_t shopItem) { - if (shopItem < 32) - { - return (gSamePriceThroughoutParkA & (1u << shopItem)) != 0; - } - else - { - return (gSamePriceThroughoutParkB & (1u << (shopItem - 32))) != 0; - } + return (gSamePriceThroughoutPark & (1ULL << shopItem)) != 0; } bool shop_item_is_food_or_drink(int32_t shopItem) diff --git a/src/openrct2/ride/ShopItem.h b/src/openrct2/ride/ShopItem.h index 159ce77526..1f84fe4885 100644 --- a/src/openrct2/ride/ShopItem.h +++ b/src/openrct2/ride/ShopItem.h @@ -87,8 +87,7 @@ struct rct_shop_item_string_types rct_string_id display; // "Diamond Heights" Balloon }; -extern uint32_t gSamePriceThroughoutParkA; -extern uint32_t gSamePriceThroughoutParkB; +extern uint64_t gSamePriceThroughoutPark; extern const money8 DefaultShopItemPrice[SHOP_ITEM_COUNT]; extern const rct_shop_item_string_types ShopItemStringIds[SHOP_ITEM_COUNT]; From 9c4430736da019f1a913df8702d1dfa47fded73f Mon Sep 17 00:00:00 2001 From: Duncan Date: Sat, 16 Mar 2019 11:21:36 +0000 Subject: [PATCH 038/506] Use get track element (#8884) * Use get_track_element and change its return type * Make things work * Use helper functions where possible --- src/openrct2/peep/Guest.cpp | 16 +++------- src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/ride/Ride.cpp | 56 +++++++++++------------------------ src/openrct2/ride/Vehicle.cpp | 22 +++++++------- src/openrct2/world/Map.cpp | 4 +-- src/openrct2/world/Map.h | 2 +- test/tests/TileElements.cpp | 2 +- 7 files changed, 37 insertions(+), 67 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 597711ab71..80b105092e 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4714,20 +4714,12 @@ void Guest::UpdateRideMazePathfinding() int16_t stationHeight = ride->stations[0].Height; // Find the station track element - TileElement* tileElement = map_get_first_element_at(actionX / 32, actionY / 32); - do - { - if (tileElement->GetType() == TILE_ELEMENT_TYPE_TRACK && stationHeight == tileElement->base_height) - break; - - } while (!(tileElement++)->IsLastForTile()); - - auto trackMazeEntry = tileElement->AsTrack(); - if (trackMazeEntry == nullptr) + auto trackElement = map_get_track_element_at(actionX, actionY, stationHeight); + if (trackElement == nullptr) { return; } - uint16_t mazeEntry = trackMazeEntry->GetMazeEntry(); + uint16_t mazeEntry = trackElement->GetMazeEntry(); uint16_t openHedges = 0; // var_37 is 3, 7, 11 or 15 @@ -4780,7 +4772,7 @@ void Guest::UpdateRideMazePathfinding() }; maze_type mazeType = maze_type::invalid; - tileElement = map_get_first_element_at(actionX / 32, actionY / 32); + auto tileElement = map_get_first_element_at(actionX / 32, actionY / 32); do { if (stationHeight != tileElement->base_height) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 3497ef275c..80203cf89c 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -2472,7 +2472,7 @@ bool Staff::UpdateFixingMoveToStationEnd(bool firstRun, Ride* ride) uint16_t stationX = stationPosition.x * 32; uint16_t stationY = stationPosition.y * 32; - TileElement* tileElement = map_get_track_element_at(stationX, stationY, stationZ); + auto tileElement = map_get_track_element_at(stationX, stationY, stationZ); if (tileElement == nullptr) { log_error("Couldn't find tile_element"); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index cadff985bd..05b42e445e 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4904,57 +4904,51 @@ static void ride_create_vehicles_find_first_block(Ride* ride, CoordsXYE* outXYEl int32_t firstX = vehicle->track_x; int32_t firstY = vehicle->track_y; int32_t firstZ = vehicle->track_z; - TileElement* firstElement = map_get_track_element_at(firstX, firstY, firstZ / 8); + auto firstElement = map_get_track_element_at(firstX, firstY, firstZ / 8); assert(firstElement != nullptr); int32_t x = firstX; int32_t y = firstY; - TileElement* trackElement = firstElement; + auto trackElement = firstElement; track_begin_end trackBeginEnd; - while (track_block_get_previous(x, y, trackElement, &trackBeginEnd)) + while (track_block_get_previous(x, y, reinterpret_cast(trackElement), &trackBeginEnd)) { x = trackBeginEnd.end_x; y = trackBeginEnd.end_y; - trackElement = trackBeginEnd.begin_element; + trackElement = trackBeginEnd.begin_element->AsTrack(); if (x == firstX && y == firstY && trackElement == firstElement) { break; } - int32_t trackType = trackElement->AsTrack()->GetTrackType(); + int32_t trackType = trackElement->GetTrackType(); switch (trackType) { case TRACK_ELEM_25_DEG_UP_TO_FLAT: case TRACK_ELEM_60_DEG_UP_TO_FLAT: - if (trackElement->AsTrack()->HasChain()) + if (trackElement->HasChain()) { outXYElement->x = x; outXYElement->y = y; - outXYElement->element = trackElement; + outXYElement->element = reinterpret_cast(trackElement); return; } break; case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT: case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT: - if (trackElement->AsTrack()->HasChain()) + if (trackElement->HasChain()) { - TileElement* tileElement = map_get_first_element_at(trackBeginEnd.begin_x >> 5, trackBeginEnd.begin_y >> 5); - do + TileElement* tileElement = map_get_track_element_at_of_type_seq( + trackBeginEnd.begin_x, trackBeginEnd.begin_y, trackBeginEnd.begin_z / 8, trackType, 0); + + if (tileElement != nullptr) { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - if (tileElement->AsTrack()->GetTrackType() != trackType) - continue; - if (tileElement->AsTrack()->GetSequenceIndex() != 0) - continue; - if (tileElement->base_height != trackBeginEnd.begin_z / 8) - continue; outXYElement->x = trackBeginEnd.begin_x; outXYElement->y = trackBeginEnd.begin_y; outXYElement->element = tileElement; return; - } while (!(tileElement++)->IsLastForTile()); + } } break; case TRACK_ELEM_END_STATION: @@ -4962,14 +4956,14 @@ static void ride_create_vehicles_find_first_block(Ride* ride, CoordsXYE* outXYEl case TRACK_ELEM_BLOCK_BRAKES: outXYElement->x = x; outXYElement->y = y; - outXYElement->element = trackElement; + outXYElement->element = reinterpret_cast(trackElement); return; } } outXYElement->x = firstX; outXYElement->y = firstY; - outXYElement->element = firstElement; + outXYElement->element = reinterpret_cast(firstElement); } /** @@ -5009,15 +5003,7 @@ static bool ride_create_vehicles(Ride* ride, CoordsXYE* element, int32_t isApply x = element->x - CoordsDirectionDelta[direction].x; y = element->y - CoordsDirectionDelta[direction].y; - tileElement = map_get_first_element_at(x >> 5, y >> 5); - do - { - if (tileElement->base_height != z) - continue; - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - break; - } while (!(tileElement++)->IsLastForTile()); + tileElement = reinterpret_cast(map_get_track_element_at(x, y, z)); z = tileElement->base_height; direction = tileElement->GetDirection(); @@ -5275,15 +5261,7 @@ static bool ride_create_cable_lift(ride_id_t rideIndex, bool isApplying) int32_t x = ride->cable_lift_x; int32_t y = ride->cable_lift_y; int32_t z = ride->cable_lift_z; - TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); - do - { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - if (tileElement->base_height != z) - continue; - break; - } while (!(tileElement++)->IsLastForTile()); + auto tileElement = map_get_track_element_at(x, y, z); int32_t direction = tileElement->GetDirection(); rct_vehicle* head = nullptr; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 97aeb55a96..ff28513d1b 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2836,7 +2836,7 @@ static bool vehicle_can_depart_synchronised(rct_vehicle* vehicle) int32_t y = location.y * 32; int32_t z = ride->stations[station].Height; - TileElement* tileElement = map_get_track_element_at(x, y, z); + auto tileElement = map_get_track_element_at(x, y, z); if (tileElement == nullptr) { return false; @@ -3989,14 +3989,14 @@ loc_6D8E36: return; } - TileElement* tileElement = map_get_track_element_at(vehicle->track_x, vehicle->track_y, vehicle->track_z / 8); + auto trackElement = map_get_track_element_at(vehicle->track_x, vehicle->track_y, vehicle->track_z / 8); - if (tileElement == nullptr) + if (trackElement == nullptr) { return; } - vehicle->current_station = tileElement->AsTrack()->GetStationIndex(); + vehicle->current_station = trackElement->GetStationIndex(); vehicle->num_laps++; if (vehicle->sub_state != 0) @@ -4270,10 +4270,10 @@ static void loc_6DA9F9(rct_vehicle* vehicle, int32_t x, int32_t y, int32_t bx, i vehicle->track_x = bx; vehicle->track_y = dx; - TileElement* tileElement = map_get_track_element_at(vehicle->track_x, vehicle->track_y, vehicle->track_z >> 3); + auto trackElement = map_get_track_element_at(vehicle->track_x, vehicle->track_y, vehicle->track_z >> 3); Ride* ride = get_ride(vehicle->ride); - vehicle->track_type = (tileElement->AsTrack()->GetTrackType() << 2) | (ride->boat_hire_return_direction & 3); + vehicle->track_type = (trackElement->GetTrackType() << 2) | (ride->boat_hire_return_direction & 3); vehicle->track_progress = 0; vehicle->status = VEHICLE_STATUS_TRAVELLING; @@ -6762,15 +6762,15 @@ static void vehicle_update_block_brakes_open_previous_section(rct_vehicle* vehic x = trackBeginEnd.begin_x; y = trackBeginEnd.begin_y; z = trackBeginEnd.begin_z; - tileElement = map_get_track_element_at(x, y, z >> 3); - if (tileElement == nullptr) + auto trackElement = map_get_track_element_at(x, y, z >> 3); + if (trackElement == nullptr) { return; } - tileElement->AsTrack()->SetBlockBrakeClosed(false); - map_invalidate_element(x, y, tileElement); + trackElement->SetBlockBrakeClosed(false); + map_invalidate_element(x, y, reinterpret_cast(trackElement)); - int32_t trackType = tileElement->AsTrack()->GetTrackType(); + int32_t trackType = trackElement->GetTrackType(); if (trackType == TRACK_ELEM_BLOCK_BRAKES || trackType == TRACK_ELEM_END_STATION) { Ride* ride = get_ride(vehicle->ride); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 4170987951..994e96e457 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -3454,7 +3454,7 @@ void game_command_modify_tile( * @param y y units, not tiles. * @param z Base height. */ -TileElement* map_get_track_element_at(int32_t x, int32_t y, int32_t z) +TrackElement* map_get_track_element_at(int32_t x, int32_t y, int32_t z) { TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); do @@ -3464,7 +3464,7 @@ TileElement* map_get_track_element_at(int32_t x, int32_t y, int32_t z) if (tileElement->base_height != z) continue; - return tileElement; + return tileElement->AsTrack(); } while (!(tileElement++)->IsLastForTile()); return nullptr; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index b165ca3ebe..fb4b844934 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -268,7 +268,7 @@ bool map_large_scenery_get_origin( void map_offset_with_rotation(int16_t* x, int16_t* y, int16_t offsetX, int16_t offsetY, uint8_t rotation); CoordsXY translate_3d_to_2d_with_z(int32_t rotation, CoordsXYZ pos); -TileElement* map_get_track_element_at(int32_t x, int32_t y, int32_t z); +TrackElement* map_get_track_element_at(int32_t x, int32_t y, int32_t z); TileElement* map_get_track_element_at_of_type(int32_t x, int32_t y, int32_t z, int32_t trackType); TileElement* map_get_track_element_at_of_type_seq(int32_t x, int32_t y, int32_t z, int32_t trackType, int32_t sequence); TileElement* map_get_track_element_at_of_type_from_ride( diff --git a/test/tests/TileElements.cpp b/test/tests/TileElements.cpp index 5456a0cf2a..83d50c1fd0 100644 --- a/test/tests/TileElements.cpp +++ b/test/tests/TileElements.cpp @@ -82,7 +82,7 @@ TEST_F(TileElementWantsFootpathConnection, SlopedPath) TEST_F(TileElementWantsFootpathConnection, Stall) { // Stalls usually have one path direction flag, but can have multiple (info kiosk for example) - const TileElement* const stallElement = map_get_track_element_at(19 << 5, 15 << 5, 14); + const TrackElement* const stallElement = map_get_track_element_at(19 << 5, 15 << 5, 14); ASSERT_NE(stallElement, nullptr); EXPECT_TRUE(tile_element_wants_path_connection_towards({ 19, 15, 14, 0 }, nullptr)); EXPECT_FALSE(tile_element_wants_path_connection_towards({ 19, 15, 14, 1 }, nullptr)); From 602821a3891b9049d35e479bc6c51102162980db Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 16 Mar 2019 12:37:32 +0100 Subject: [PATCH 039/506] Split path surface objects into paths and queues --- src/openrct2-ui/windows/Footpath.cpp | 9 +-------- src/openrct2/object/FootpathObject.cpp | 14 ++++++++----- src/openrct2/object/FootpathObject.h | 6 ++++++ .../paint/tile_element/Paint.Path.cpp | 20 +++---------------- src/openrct2/world/Footpath.cpp | 13 +++++++++--- src/openrct2/world/Footpath.h | 8 ++++---- 6 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index de3891bbeb..ed010060a3 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -613,14 +613,7 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) int32_t selectedPath = gFootpathSelectedId; PathSurfaceEntry* pathType = get_path_surface_entry(selectedPath); - if (gFootpathSelectedType == SELECTED_PATH_TYPE_NORMAL) - { - image += pathType->image; - } - else - { - image += pathType->queue_image; - } + image += pathType->image; // Draw construction image int32_t x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2; diff --git a/src/openrct2/object/FootpathObject.cpp b/src/openrct2/object/FootpathObject.cpp index 7216586912..83403af7fc 100644 --- a/src/openrct2/object/FootpathObject.cpp +++ b/src/openrct2/object/FootpathObject.cpp @@ -27,7 +27,7 @@ void FootpathObject::ReadLegacy(IReadObjectContext* context, IStream* stream) GetImageTable().Read(context, stream); // Validate properties - if (_legacyType.support_type >= FOOTPATH_ENTRY_SUPPORT_TYPE_COUNT) + if (_legacyType.support_type >= RAILING_ENTRY_SUPPORT_TYPE_COUNT) { context->LogError(OBJECT_ERROR_INVALID_PROPERTY, "SUPPORT_TYPE not supported."); } @@ -42,10 +42,14 @@ void FootpathObject::Load() _pathSurfaceEntry.string_idx = _legacyType.string_idx; _pathSurfaceEntry.image = _legacyType.image; - _pathSurfaceEntry.queue_image = _legacyType.image + 51; _pathSurfaceEntry.preview = _legacyType.image + 71; _pathSurfaceEntry.flags = _legacyType.flags; + _queueEntry.string_idx = _legacyType.string_idx; + _queueEntry.image = _legacyType.image + 51; + _queueEntry.preview = _legacyType.image + 72; + _queueEntry.flags = _legacyType.flags | FOOTPATH_ENTRY_FLAG_IS_QUEUE; + _pathRailingsEntry.string_idx = _legacyType.string_idx; _pathRailingsEntry.bridge_image = _legacyType.bridge_image; _pathRailingsEntry.preview = _legacyType.image + 71; @@ -69,15 +73,15 @@ void FootpathObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t int32_t x = width / 2; int32_t y = height / 2; gfx_draw_sprite(dpi, _pathSurfaceEntry.preview, x - 49, y - 17, 0); - gfx_draw_sprite(dpi, _pathSurfaceEntry.preview + 1, x + 4, y - 17, 0); + gfx_draw_sprite(dpi, _queueEntry.preview, x + 4, y - 17, 0); } static uint8_t ParseSupportType(const std::string& s) { if (s == "pole") - return FOOTPATH_ENTRY_SUPPORT_TYPE_POLE; + return RAILING_ENTRY_SUPPORT_TYPE_POLE; else /* if (s == "box") */ - return FOOTPATH_ENTRY_SUPPORT_TYPE_BOX; + return RAILING_ENTRY_SUPPORT_TYPE_BOX; } void FootpathObject::ReadJson(IReadObjectContext* context, const json_t* root) diff --git a/src/openrct2/object/FootpathObject.h b/src/openrct2/object/FootpathObject.h index 986962f94b..b0398809ef 100644 --- a/src/openrct2/object/FootpathObject.h +++ b/src/openrct2/object/FootpathObject.h @@ -17,6 +17,7 @@ class FootpathObject final : public Object private: rct_footpath_entry _legacyType = {}; PathSurfaceEntry _pathSurfaceEntry = {}; + PathSurfaceEntry _queueEntry = {}; PathRailingsEntry _pathRailingsEntry = {}; public: @@ -35,6 +36,11 @@ public: return &_pathSurfaceEntry; } + PathSurfaceEntry* GetQueueEntry() + { + return &_queueEntry; + } + PathRailingsEntry* GetPathRailingsEntry() { return &_pathRailingsEntry; diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index d1702af8b8..8172801679 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -932,7 +932,7 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile if (footpathEntry != nullptr && railingEntry != nullptr) { - if (railingEntry->support_type == FOOTPATH_ENTRY_SUPPORT_TYPE_POLE) + if (railingEntry->support_type == RAILING_ENTRY_SUPPORT_TYPE_POLE) { path_paint_pole_support( session, tile_element, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags); @@ -1008,14 +1008,7 @@ void path_paint_box_support( imageId = byte_98D6E0[edi]; } - if (pathElement->IsQueue()) - { - imageId += footpathEntry->queue_image; - } - else - { - imageId += footpathEntry->image; - } + imageId += footpathEntry->image; if (!session->DidPassSurface) { @@ -1164,14 +1157,7 @@ void path_paint_pole_support( imageId = byte_98D6E0[edi]; } - if (pathElement->IsQueue()) - { - imageId += footpathEntry->queue_image; - } - else - { - imageId += footpathEntry->image; - } + imageId += footpathEntry->image; // Below Surface if (!session->DidPassSurface) diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 2d9d705377..fe07ff13db 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1568,7 +1568,10 @@ uint8_t PathElement::GetRailingEntryIndex() const PathSurfaceEntry* PathElement::GetPathEntry() const { - return get_path_surface_entry(GetPathEntryIndex()); + if (!IsQueue()) + return get_path_surface_entry(GetPathEntryIndex()); + else + return get_path_surface_entry(GetPathEntryIndex() + 32); } PathRailingsEntry* PathElement::GetRailingEntry() const @@ -2159,10 +2162,14 @@ PathSurfaceEntry* get_path_surface_entry(int32_t entryIndex) { PathSurfaceEntry* result = nullptr; auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); - auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_PATHS, entryIndex); + // TODO: Change when moving to the new save format. + auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_PATHS, entryIndex % MAX_PATH_OBJECTS); if (obj != nullptr) { - result = ((FootpathObject*)obj)->GetPathSurfaceEntry(); + if (entryIndex < MAX_PATH_OBJECTS) + result = ((FootpathObject*)obj)->GetPathSurfaceEntry(); + else + result = ((FootpathObject*)obj)->GetQueueEntry(); } return result; } diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 79ba0f6dbb..33cba7114c 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -43,7 +43,6 @@ struct PathSurfaceEntry { rct_string_id string_idx; uint32_t image; - uint32_t queue_image; uint32_t preview; uint8_t flags; }; @@ -94,14 +93,15 @@ enum enum { - FOOTPATH_ENTRY_SUPPORT_TYPE_BOX = 0, - FOOTPATH_ENTRY_SUPPORT_TYPE_POLE = 1, - FOOTPATH_ENTRY_SUPPORT_TYPE_COUNT + RAILING_ENTRY_SUPPORT_TYPE_BOX = 0, + RAILING_ENTRY_SUPPORT_TYPE_POLE = 1, + RAILING_ENTRY_SUPPORT_TYPE_COUNT }; enum { FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR = (1 << 2), + FOOTPATH_ENTRY_FLAG_IS_QUEUE = (1 << 3), }; enum From 1c0877fc6c29dad85147825208502cd773957d9f Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 16 Mar 2019 14:20:03 +0100 Subject: [PATCH 040/506] Fix missed occurrence of SCROLLING_MODE_NONE --- src/openrct2/object/StationObject.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/object/StationObject.cpp b/src/openrct2/object/StationObject.cpp index d0d48eb874..918100d927 100644 --- a/src/openrct2/object/StationObject.cpp +++ b/src/openrct2/object/StationObject.cpp @@ -13,6 +13,7 @@ #include "../core/String.hpp" #include "../drawing/Drawing.h" #include "../localisation/Localisation.h" +#include "../world/Banner.h" #include "ObjectJsonHelpers.h" void StationObject::Load() @@ -82,7 +83,7 @@ void StationObject::ReadJson(IReadObjectContext* context, const json_t* root) { auto properties = json_object_get(root, "properties"); Height = ObjectJsonHelpers::GetInteger(properties, "height", 0); - ScrollingMode = ObjectJsonHelpers::GetInteger(properties, "scrollingMode", 0xFF); + ScrollingMode = ObjectJsonHelpers::GetInteger(properties, "scrollingMode", SCROLLING_MODE_NONE); Flags = ObjectJsonHelpers::GetFlags( properties, { { "hasPrimaryColour", STATION_OBJECT_FLAGS::HAS_PRIMARY_COLOUR }, From 6884eac24c50b307f346002c665c510cdc41c0fe Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 16 Mar 2019 14:21:44 +0100 Subject: [PATCH 041/506] Turn railing support type into enum class --- src/openrct2/object/FootpathObject.cpp | 12 ++++++------ src/openrct2/paint/tile_element/Paint.Path.cpp | 2 +- src/openrct2/world/Footpath.h | 18 +++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/openrct2/object/FootpathObject.cpp b/src/openrct2/object/FootpathObject.cpp index 83403af7fc..15b0bb1699 100644 --- a/src/openrct2/object/FootpathObject.cpp +++ b/src/openrct2/object/FootpathObject.cpp @@ -18,7 +18,7 @@ void FootpathObject::ReadLegacy(IReadObjectContext* context, IStream* stream) { stream->Seek(10, STREAM_SEEK_CURRENT); - _legacyType.support_type = stream->ReadValue(); + _legacyType.support_type = static_cast(stream->ReadValue()); _legacyType.flags = stream->ReadValue(); _legacyType.scrolling_mode = stream->ReadValue(); stream->Seek(1, STREAM_SEEK_CURRENT); @@ -27,9 +27,9 @@ void FootpathObject::ReadLegacy(IReadObjectContext* context, IStream* stream) GetImageTable().Read(context, stream); // Validate properties - if (_legacyType.support_type >= RAILING_ENTRY_SUPPORT_TYPE_COUNT) + if (_legacyType.support_type >= RailingEntrySupportType::Count) { - context->LogError(OBJECT_ERROR_INVALID_PROPERTY, "SUPPORT_TYPE not supported."); + context->LogError(OBJECT_ERROR_INVALID_PROPERTY, "RailingEntrySupportType not supported."); } } @@ -76,12 +76,12 @@ void FootpathObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t gfx_draw_sprite(dpi, _queueEntry.preview, x + 4, y - 17, 0); } -static uint8_t ParseSupportType(const std::string& s) +static RailingEntrySupportType ParseSupportType(const std::string& s) { if (s == "pole") - return RAILING_ENTRY_SUPPORT_TYPE_POLE; + return RailingEntrySupportType::Pole; else /* if (s == "box") */ - return RAILING_ENTRY_SUPPORT_TYPE_BOX; + return RailingEntrySupportType::Box; } void FootpathObject::ReadJson(IReadObjectContext* context, const json_t* root) diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 8172801679..6bebe317a0 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -932,7 +932,7 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile if (footpathEntry != nullptr && railingEntry != nullptr) { - if (railingEntry->support_type == RAILING_ENTRY_SUPPORT_TYPE_POLE) + if (railingEntry->support_type == RailingEntrySupportType::Pole) { path_paint_pole_support( session, tile_element, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags); diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 33cba7114c..4b08589347 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -26,13 +26,20 @@ constexpr auto FootpathMinHeight = 2; #define FOOTPATH_ELEMENT_INSERT_QUEUE 0x80 +enum class RailingEntrySupportType : uint8_t +{ + Box = 0, + Pole = 1, + Count +}; + #pragma pack(push, 1) struct rct_footpath_entry { rct_string_id string_idx; // 0x00 uint32_t image; // 0x02 uint32_t bridge_image; // 0x06 - uint8_t support_type; // 0x0A + RailingEntrySupportType support_type; // 0x0A uint8_t flags; // 0x0B uint8_t scrolling_mode; // 0x0C }; @@ -53,7 +60,7 @@ struct PathRailingsEntry uint32_t preview; uint32_t bridge_image; uint32_t railings_image; - uint8_t support_type; + RailingEntrySupportType support_type; uint8_t flags; uint8_t scrolling_mode; }; @@ -91,13 +98,6 @@ enum FOOTPATH_PROPERTIES_ADDITIONS_FLAG_GHOST = (1 << 7), }; -enum -{ - RAILING_ENTRY_SUPPORT_TYPE_BOX = 0, - RAILING_ENTRY_SUPPORT_TYPE_POLE = 1, - RAILING_ENTRY_SUPPORT_TYPE_COUNT -}; - enum { FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR = (1 << 2), From 7e2ff6d752cbd35f3ca6ec0d22ddb87b48bfe7c8 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 16 Mar 2019 15:43:36 +0100 Subject: [PATCH 042/506] Fix alignment --- src/openrct2/world/Footpath.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 4b08589347..2266989c83 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -36,12 +36,12 @@ enum class RailingEntrySupportType : uint8_t #pragma pack(push, 1) struct rct_footpath_entry { - rct_string_id string_idx; // 0x00 - uint32_t image; // 0x02 - uint32_t bridge_image; // 0x06 + rct_string_id string_idx; // 0x00 + uint32_t image; // 0x02 + uint32_t bridge_image; // 0x06 RailingEntrySupportType support_type; // 0x0A - uint8_t flags; // 0x0B - uint8_t scrolling_mode; // 0x0C + uint8_t flags; // 0x0B + uint8_t scrolling_mode; // 0x0C }; assert_struct_size(rct_footpath_entry, 13); #pragma pack(pop) From c80c7b5cd24bed81763137d78c7e613c94d851d1 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 16:23:26 +0000 Subject: [PATCH 043/506] Use LargeSceneryElement for return type --- src/openrct2/ride/TrackDesignSave.cpp | 36 +++++++++++++-------------- src/openrct2/world/Map.cpp | 29 +++++++++++---------- src/openrct2/world/Map.h | 4 +-- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/openrct2/ride/TrackDesignSave.cpp b/src/openrct2/ride/TrackDesignSave.cpp index a6e690d7a2..dc8edab2b3 100644 --- a/src/openrct2/ride/TrackDesignSave.cpp +++ b/src/openrct2/ride/TrackDesignSave.cpp @@ -306,19 +306,19 @@ static void track_design_save_add_scenery(int32_t x, int32_t y, TileElement* til track_design_save_push_tile_element_desc(entry, x, y, tileElement->base_height, flags, primaryColour, secondaryColour); } -static void track_design_save_add_large_scenery(int32_t x, int32_t y, TileElement* tileElement) +static void track_design_save_add_large_scenery(int32_t x, int32_t y, LargeSceneryElement* tileElement) { rct_large_scenery_tile *sceneryTiles, *tile; int32_t x0, y0, z0, z; int32_t direction, sequence; - int32_t entryType = tileElement->AsLargeScenery()->GetEntryIndex(); + int32_t entryType = tileElement->GetEntryIndex(); auto entry = object_entry_get_entry(OBJECT_TYPE_LARGE_SCENERY, entryType); sceneryTiles = get_large_scenery_entry(entryType)->large_scenery.tiles; z = tileElement->base_height; direction = tileElement->GetDirection(); - sequence = tileElement->AsLargeScenery()->GetSequenceIndex(); + sequence = tileElement->GetSequenceIndex(); if (!map_large_scenery_get_origin(x, y, z, direction, sequence, &x0, &y0, &z0, nullptr)) { @@ -336,18 +336,18 @@ static void track_design_save_add_large_scenery(int32_t x, int32_t y, TileElemen x = x0 + offsetX; y = y0 + offsetY; z = (z0 + tile->z_offset) / 8; - tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence); - if (tileElement != nullptr) + auto largeElement = map_get_large_scenery_segment(x, y, z, direction, sequence); + if (largeElement != nullptr) { if (sequence == 0) { - uint8_t flags = tileElement->GetDirection(); - uint8_t primaryColour = tileElement->AsLargeScenery()->GetPrimaryColour(); - uint8_t secondaryColour = tileElement->AsLargeScenery()->GetSecondaryColour(); + uint8_t flags = largeElement->GetDirection(); + uint8_t primaryColour = largeElement->GetPrimaryColour(); + uint8_t secondaryColour = largeElement->GetSecondaryColour(); track_design_save_push_tile_element_desc(entry, x, y, z, flags, primaryColour, secondaryColour); } - track_design_save_push_tile_element(x, y, tileElement); + track_design_save_push_tile_element(x, y, reinterpret_cast(largeElement)); } } } @@ -402,7 +402,7 @@ static bool track_design_save_add_tile_element(int32_t interactionType, int32_t track_design_save_add_scenery(x, y, tileElement); return true; case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY: - track_design_save_add_large_scenery(x, y, tileElement); + track_design_save_add_large_scenery(x, y, tileElement->AsLargeScenery()); return true; case VIEWPORT_INTERACTION_ITEM_WALL: track_design_save_add_wall(x, y, tileElement); @@ -499,19 +499,19 @@ static void track_design_save_remove_scenery(int32_t x, int32_t y, TileElement* track_design_save_pop_tile_element_desc(entry, x, y, tileElement->base_height, flags); } -static void track_design_save_remove_large_scenery(int32_t x, int32_t y, TileElement* tileElement) +static void track_design_save_remove_large_scenery(int32_t x, int32_t y, LargeSceneryElement* tileElement) { rct_large_scenery_tile *sceneryTiles, *tile; int32_t x0, y0, z0, z; int32_t direction, sequence; - int32_t entryType = tileElement->AsLargeScenery()->GetEntryIndex(); + int32_t entryType = tileElement->GetEntryIndex(); auto entry = object_entry_get_entry(OBJECT_TYPE_LARGE_SCENERY, entryType); sceneryTiles = get_large_scenery_entry(entryType)->large_scenery.tiles; z = tileElement->base_height; direction = tileElement->GetDirection(); - sequence = tileElement->AsLargeScenery()->GetSequenceIndex(); + sequence = tileElement->GetSequenceIndex(); if (!map_large_scenery_get_origin(x, y, z, direction, sequence, &x0, &y0, &z0, nullptr)) { @@ -529,15 +529,15 @@ static void track_design_save_remove_large_scenery(int32_t x, int32_t y, TileEle x = x0 + offsetX; y = y0 + offsetY; z = (z0 + tile->z_offset) / 8; - tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence); - if (tileElement != nullptr) + auto largeElement = map_get_large_scenery_segment(x, y, z, direction, sequence); + if (largeElement != nullptr) { if (sequence == 0) { - uint8_t flags = tileElement->GetDirection(); + uint8_t flags = largeElement->GetDirection(); track_design_save_pop_tile_element_desc(entry, x, y, z, flags); } - track_design_save_pop_tile_element(x, y, tileElement); + track_design_save_pop_tile_element(x, y, reinterpret_cast(largeElement)); } } } @@ -584,7 +584,7 @@ static void track_design_save_remove_tile_element(int32_t interactionType, int32 track_design_save_remove_scenery(x, y, tileElement); break; case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY: - track_design_save_remove_large_scenery(x, y, tileElement); + track_design_save_remove_large_scenery(x, y, tileElement->AsLargeScenery()); break; case VIEWPORT_INTERACTION_ITEM_WALL: track_design_save_remove_wall(x, y, tileElement); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 994e96e457..5fe49c0794 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -816,7 +816,7 @@ void game_command_set_large_scenery_colour( gCommandPosition.y = y + 16; gCommandPosition.z = z; - TileElement* tile_element = map_get_large_scenery_segment(x, y, base_height, tile_element_direction, tileIndex); + auto tile_element = map_get_large_scenery_segment(x, y, base_height, tile_element_direction, tileIndex); if (tile_element == nullptr) { @@ -830,7 +830,7 @@ void game_command_set_large_scenery_colour( return; } - rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry(); + rct_scenery_entry* scenery_entry = tile_element->GetEntry(); // Work out the base tile coordinates (Tile with index 0) LocationXYZ16 baseTile = { @@ -865,11 +865,11 @@ void game_command_set_large_scenery_colour( if (flags & GAME_COMMAND_FLAG_APPLY) { - TileElement* tileElement = map_get_large_scenery_segment( + auto tileElement = map_get_large_scenery_segment( currentTile.x, currentTile.y, base_height, tile_element_direction, i); - tileElement->AsLargeScenery()->SetPrimaryColour(colour1); - tileElement->AsLargeScenery()->SetSecondaryColour(colour2); + tileElement->SetPrimaryColour(colour1); + tileElement->SetSecondaryColour(colour2); map_invalidate_tile_full(currentTile.x, currentTile.y); } @@ -2868,7 +2868,7 @@ int32_t map_get_highest_z(int32_t tileX, int32_t tileY) return z; } -TileElement* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence) +LargeSceneryElement* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence) { TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); if (tileElement == nullptr) @@ -2886,7 +2886,7 @@ TileElement* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z, int3 if ((tileElement->GetDirection()) != direction) continue; - return tileElement; + return tileElement->AsLargeScenery(); } while (!(tileElement++)->IsLastForTile()); return nullptr; } @@ -2990,18 +2990,17 @@ TileElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, i bool map_large_scenery_get_origin( int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence, int32_t* outX, int32_t* outY, int32_t* outZ, - TileElement** outElement) + LargeSceneryElement** outElement) { - TileElement* tileElement; rct_scenery_entry* sceneryEntry; rct_large_scenery_tile* tile; int16_t offsetX, offsetY; - tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence); + auto tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence); if (tileElement == nullptr) return false; - sceneryEntry = tileElement->AsLargeScenery()->GetEntry(); + sceneryEntry = tileElement->GetEntry(); tile = &sceneryEntry->large_scenery.tiles[sequence]; offsetX = tile->x_offset; @@ -3023,7 +3022,7 @@ bool map_large_scenery_get_origin( bool sign_set_colour( int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence, uint8_t mainColour, uint8_t textColour) { - TileElement* tileElement; + LargeSceneryElement* tileElement; rct_scenery_entry* sceneryEntry; rct_large_scenery_tile *sceneryTiles, *tile; int16_t offsetX, offsetY; @@ -3034,7 +3033,7 @@ bool sign_set_colour( return false; } - sceneryEntry = tileElement->AsLargeScenery()->GetEntry(); + sceneryEntry = tileElement->GetEntry(); sceneryTiles = sceneryEntry->large_scenery.tiles; // Iterate through each tile of the large scenery element @@ -3051,8 +3050,8 @@ bool sign_set_colour( tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence); if (tileElement != nullptr) { - tileElement->AsLargeScenery()->SetPrimaryColour(mainColour); - tileElement->AsLargeScenery()->SetSecondaryColour(textColour); + tileElement->SetPrimaryColour(mainColour); + tileElement->SetSecondaryColour(textColour); map_invalidate_tile(x, y, tileElement->base_height * 8, tileElement->clearance_height * 8); } diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index fb4b844934..ad572ed24a 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -260,10 +260,10 @@ int32_t tile_element_get_corner_height(const TileElement* tileElement, int32_t d void map_clear_all_elements(); -TileElement* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence); +LargeSceneryElement* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence); bool map_large_scenery_get_origin( int32_t x, int32_t y, int32_t z, int32_t direction, int32_t sequence, int32_t* outX, int32_t* outY, int32_t* outZ, - TileElement** outElement); + LargeSceneryElement** outElement); void map_offset_with_rotation(int16_t* x, int16_t* y, int16_t offsetX, int16_t offsetY, uint8_t rotation); CoordsXY translate_3d_to_2d_with_z(int32_t rotation, CoordsXYZ pos); From 2c2239b13175bff21aaf13b27afb00a1a0ec9827 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 16:29:02 +0000 Subject: [PATCH 044/506] Use small scenery element as return --- src/openrct2/world/Map.cpp | 4 ++-- src/openrct2/world/Map.h | 2 +- src/openrct2/world/SmallScenery.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 5fe49c0794..30daeef2bd 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2966,7 +2966,7 @@ EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, b return nullptr; } -TileElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant) +SmallSceneryElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant) { TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); if (tileElement != nullptr) @@ -2982,7 +2982,7 @@ TileElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, i if (tileElement->AsSmallScenery()->GetEntryIndex() != type) continue; - return tileElement; + return tileElement->AsSmallScenery(); } while (!(tileElement++)->IsLastForTile()); } return nullptr; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index ad572ed24a..28ef550fd2 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -147,7 +147,7 @@ TileElement* map_get_surface_element_at(int32_t x, int32_t y); TileElement* map_get_surface_element_at(CoordsXY coords); TileElement* map_get_path_element_at(int32_t x, int32_t y, int32_t z); TileElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction); -TileElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant); +SmallSceneryElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant); EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, bool ghost); diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index a62fe4673b..f6846c5d9f 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -42,7 +42,7 @@ static money32 SmallScenerySetColour( } } - TileElement* tileElement = map_get_small_scenery_element_at(x, y, baseHeight, sceneryType, quadrant); + auto tileElement = map_get_small_scenery_element_at(x, y, baseHeight, sceneryType, quadrant); if (tileElement == nullptr) { @@ -56,8 +56,8 @@ static money32 SmallScenerySetColour( if (flags & GAME_COMMAND_FLAG_APPLY) { - tileElement->AsSmallScenery()->SetPrimaryColour(primaryColour); - tileElement->AsSmallScenery()->SetSecondaryColour(secondaryColour); + tileElement->SetPrimaryColour(primaryColour); + tileElement->SetSecondaryColour(secondaryColour); map_invalidate_tile_full(x, y); } From 6c92594c4b2a9c463e2b3805267c7a8579f41236 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 16:32:13 +0000 Subject: [PATCH 045/506] Use wall element as return --- src/openrct2/ride/Vehicle.cpp | 28 ++++++++++++++-------------- src/openrct2/world/Map.cpp | 4 ++-- src/openrct2/world/Map.h | 2 +- src/openrct2/world/Wall.cpp | 10 +++++----- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index ff28513d1b..4ad8c3ef01 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -7382,9 +7382,9 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) * * rct2: 0x006DEDB1 */ -static void vehicle_play_scenery_door_open_sound(rct_vehicle* vehicle, TileElement* tileElement) +static void vehicle_play_scenery_door_open_sound(rct_vehicle* vehicle, WallElement* tileElement) { - rct_scenery_entry* wallEntry = tileElement->AsWall()->GetEntry(); + rct_scenery_entry* wallEntry = tileElement->GetEntry(); int32_t doorSoundType = wall_entry_get_door_sound(wallEntry); if (doorSoundType != 0) { @@ -7400,9 +7400,9 @@ static void vehicle_play_scenery_door_open_sound(rct_vehicle* vehicle, TileEleme * * rct2: 0x006DED7A */ -static void vehicle_play_scenery_door_close_sound(rct_vehicle* vehicle, TileElement* tileElement) +static void vehicle_play_scenery_door_close_sound(rct_vehicle* vehicle, WallElement* tileElement) { - rct_scenery_entry* wallEntry = tileElement->AsWall()->GetEntry(); + rct_scenery_entry* wallEntry = tileElement->GetEntry(); int32_t doorSoundType = wall_entry_get_door_sound(wallEntry); if (doorSoundType != 0) { @@ -7432,7 +7432,7 @@ static void vehicle_update_scenery_door(rct_vehicle* vehicle) int32_t z = (vehicle->track_z - trackBlock->z + trackCoordinates->z_end) >> 3; int32_t direction = (vehicle->track_direction + trackCoordinates->rotation_end) & 3; - TileElement* tileElement = map_get_wall_element_at(x, y, z, direction); + auto tileElement = map_get_wall_element_at(x, y, z, direction); if (tileElement == nullptr) { return; @@ -7440,15 +7440,15 @@ static void vehicle_update_scenery_door(rct_vehicle* vehicle) if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) { - tileElement->AsWall()->SetAnimationIsBackwards(false); - tileElement->AsWall()->SetAnimationFrame(1); + tileElement->SetAnimationIsBackwards(false); + tileElement->SetAnimationFrame(1); map_animation_create(MAP_ANIMATION_TYPE_WALL_DOOR, x, y, z); vehicle_play_scenery_door_open_sound(vehicle, tileElement); } else { - tileElement->AsWall()->SetAnimationIsBackwards(false); - tileElement->AsWall()->SetAnimationFrame(6); + tileElement->SetAnimationIsBackwards(false); + tileElement->SetAnimationFrame(6); vehicle_play_scenery_door_close_sound(vehicle, tileElement); } } @@ -7512,7 +7512,7 @@ static void vehicle_update_handle_scenery_door(rct_vehicle* vehicle) int32_t direction = (vehicle->track_direction + trackCoordinates->rotation_begin) & 3; direction = direction_reverse(direction); - TileElement* tileElement = map_get_wall_element_at(x, y, z, direction); + auto tileElement = map_get_wall_element_at(x, y, z, direction); if (tileElement == nullptr) { return; @@ -7520,15 +7520,15 @@ static void vehicle_update_handle_scenery_door(rct_vehicle* vehicle) if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) { - tileElement->AsWall()->SetAnimationIsBackwards(true); - tileElement->AsWall()->SetAnimationFrame(1); + tileElement->SetAnimationIsBackwards(true); + tileElement->SetAnimationFrame(1); map_animation_create(MAP_ANIMATION_TYPE_WALL_DOOR, x, y, z); vehicle_play_scenery_door_open_sound(vehicle, tileElement); } else { - tileElement->AsWall()->SetAnimationIsBackwards(true); - tileElement->AsWall()->SetAnimationFrame(6); + tileElement->SetAnimationIsBackwards(true); + tileElement->SetAnimationFrame(6); vehicle_play_scenery_door_close_sound(vehicle, tileElement); } } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 30daeef2bd..c824021b02 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -3622,7 +3622,7 @@ void map_offset_with_rotation(int16_t* x, int16_t* y, int16_t offsetX, int16_t o } } -TileElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction) +WallElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction) { TileElement* tileElement = map_get_first_element_at(x >> 5, y >> 5); do @@ -3634,7 +3634,7 @@ TileElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t di if (tileElement->GetDirection() != direction) continue; - return tileElement; + return tileElement->AsWall(); } while (!(tileElement++)->IsLastForTile()); return nullptr; } diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 28ef550fd2..d8229981f1 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -146,7 +146,7 @@ BannerElement* map_get_banner_element_at(int32_t x, int32_t y, int32_t z, uint8_ TileElement* map_get_surface_element_at(int32_t x, int32_t y); TileElement* map_get_surface_element_at(CoordsXY coords); TileElement* map_get_path_element_at(int32_t x, int32_t y, int32_t z); -TileElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction); +WallElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction); SmallSceneryElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int32_t z, int32_t type, uint8_t quadrant); EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 44606ae9ea..8830764011 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -571,7 +571,7 @@ static money32 WallSetColour( return MONEY32_UNDEFINED; } - TileElement* wallElement = map_get_wall_element_at(x, y, baseHeight, direction); + auto wallElement = map_get_wall_element_at(x, y, baseHeight, direction); if (wallElement == nullptr) { return 0; @@ -584,13 +584,13 @@ static money32 WallSetColour( if (flags & GAME_COMMAND_FLAG_APPLY) { - rct_scenery_entry* scenery_entry = wallElement->AsWall()->GetEntry(); - wallElement->AsWall()->SetPrimaryColour(primaryColour); - wallElement->AsWall()->SetSecondaryColour(secondaryColour); + rct_scenery_entry* scenery_entry = wallElement->GetEntry(); + wallElement->SetPrimaryColour(primaryColour); + wallElement->SetSecondaryColour(secondaryColour); if (scenery_entry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) { - wallElement->AsWall()->SetTertiaryColour(tertiaryColour); + wallElement->SetTertiaryColour(tertiaryColour); } map_invalidate_tile_zoom1(x, y, z, z + 72); } From cb087e3b4e820b92813815fd25751b72326e51e8 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 16:41:18 +0000 Subject: [PATCH 046/506] Fix formatting. Initialise to bad value --- src/openrct2/actions/ParkSetParameterAction.hpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/ParkSetParameterAction.hpp b/src/openrct2/actions/ParkSetParameterAction.hpp index 6fc33aee35..65b86bf1c3 100644 --- a/src/openrct2/actions/ParkSetParameterAction.hpp +++ b/src/openrct2/actions/ParkSetParameterAction.hpp @@ -25,7 +25,7 @@ enum class ParkParameter : uint8_t DEFINE_GAME_ACTION(ParkSetParameterAction, GAME_COMMAND_SET_PARK_OPEN, GameActionResult) { private: - uint8_t _parameter; + uint8_t _parameter{ static_cast(ParkParameter::Count) }; uint64_t _value; constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_CLOSE_PARK, STR_CANT_OPEN_PARK, STR_NONE, STR_NONE }; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 65578f8b94..1697acd506 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -334,7 +334,8 @@ public: gMapSizeMinus2 = _s6.map_size_minus_2; gMapSize = _s6.map_size; gMapSizeMaxXY = _s6.map_max_xy; - gSamePriceThroughoutPark = _s6.same_price_throughout | (static_cast(_s6.same_price_throughout_extended) << 32); + gSamePriceThroughoutPark = _s6.same_price_throughout + | (static_cast(_s6.same_price_throughout_extended) << 32); _suggestedGuestMaximum = _s6.suggested_max_guests; gScenarioParkRatingWarningDays = _s6.park_rating_warning_days; gLastEntranceStyle = _s6.last_entrance_style; From 1274a3fae400318732ba0c17964d2d3bc31a612d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 20:08:57 +0000 Subject: [PATCH 047/506] Fix #8885. Incorrect function for calculating lowest water height. Looks like a good old ctrl+c, ctrl+v and then forgot to actually modify it correctly. --- src/openrct2/actions/WaterRaiseAction.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index 65b4104859..d95fefd359 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -136,14 +136,15 @@ private: if (tile_element == nullptr) continue; - uint8_t height = tile_element->AsSurface()->GetWaterHeight(); - if (height != 0) + uint8_t height = tile_element->base_height; + if (tile_element->AsSurface()->GetWaterHeight() > 0) { - height *= 2; - if (maxHeight > height) - { - maxHeight = height; - } + height = tile_element->AsSurface()->GetWaterHeight() * 2; + } + + if (maxHeight > height) + { + maxHeight = height; } } } From 77238c1e5eed200f38db7cdf3ed6370f815b1e0c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 20:45:52 +0000 Subject: [PATCH 048/506] Add staff set patrol area and fire actions --- src/openrct2-ui/windows/Staff.cpp | 7 +- src/openrct2-ui/windows/StaffFirePrompt.cpp | 8 +- src/openrct2-ui/windows/StaffList.cpp | 6 +- .../actions/GameActionRegistration.cpp | 4 + src/openrct2/actions/StaffFireAction.hpp | 72 ++++++++++++++ .../actions/StaffSetPatrolAreaAction.hpp | 99 +++++++++++++++++++ 6 files changed, 190 insertions(+), 6 deletions(-) create mode 100644 src/openrct2/actions/StaffFireAction.hpp create mode 100644 src/openrct2/actions/StaffSetPatrolAreaAction.hpp diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index c31fc30c34..b99f068e9b 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -1225,7 +1226,8 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, { _staffPatrolAreaPaintValue = PatrolAreaValue::SET; } - game_do_command(dest_x, 1, dest_y, w->number, GAME_COMMAND_SET_STAFF_PATROL, 0, 0); + auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(w->number, { dest_x, dest_y }); + GameActions::Execute(&staffSetPatrolAreaAction); } } @@ -1263,7 +1265,8 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex, if (_staffPatrolAreaPaintValue == PatrolAreaValue::UNSET && patrolAreaValue == false) return; // Since area is already the value we want, skip... - game_do_command(dest_x, 1, dest_y, w->number, GAME_COMMAND_SET_STAFF_PATROL, 0, 0); + auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(w->number, { dest_x, dest_y }); + GameActions::Execute(&staffSetPatrolAreaAction); } void window_staff_overview_tool_up(rct_window* w, rct_widgetindex widgetIndex, int32_t x, int32_t y) diff --git a/src/openrct2-ui/windows/StaffFirePrompt.cpp b/src/openrct2-ui/windows/StaffFirePrompt.cpp index 31acc4e44d..6937e84312 100644 --- a/src/openrct2-ui/windows/StaffFirePrompt.cpp +++ b/src/openrct2-ui/windows/StaffFirePrompt.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -103,12 +104,13 @@ rct_window* window_staff_fire_prompt_open(Peep* peep) */ static void window_staff_fire_mouseup(rct_window *w, rct_widgetindex widgetIndex) { - Peep* peep = &get_sprite(w->number)->peep; - switch (widgetIndex){ case WIDX_YES: - game_do_command(peep->x, 1, peep->y, w->number, GAME_COMMAND_FIRE_STAFF_MEMBER, 0, 0); + { + auto staffFireAction = StaffFireAction(w->number); + GameActions::Execute(&staffFireAction); break; + } case WIDX_CANCEL: case WIDX_CLOSE: window_close(w); diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index 34379e3f24..a02e4efd50 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -465,7 +466,10 @@ void window_staff_list_scrollmousedown(rct_window* w, int32_t scrollIndex, int32 if (i == 0) { if (_quick_fire_mode) - game_do_command(peep->x, 1, peep->y, spriteIndex, GAME_COMMAND_FIRE_STAFF_MEMBER, 0, 0); + { + auto staffFireAction = StaffFireAction(spriteIndex); + GameActions::Execute(&staffFireAction); + } else { auto intent = Intent(WC_PEEP); diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index cf6fd67727..fc31c174f9 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -46,11 +46,13 @@ #include "SignSetStyleAction.hpp" #include "SmallSceneryPlaceAction.hpp" #include "SmallSceneryRemoveAction.hpp" +#include "StaffFireAction.hpp" #include "StaffHireNewAction.hpp" #include "StaffSetColourAction.hpp" #include "StaffSetCostumeAction.hpp" #include "StaffSetNameAction.hpp" #include "StaffSetOrdersAction.hpp" +#include "StaffSetPatrolAreaAction.hpp" #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "TrackSetBrakeSpeedAction.hpp" @@ -92,11 +94,13 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/StaffFireAction.hpp b/src/openrct2/actions/StaffFireAction.hpp new file mode 100644 index 0000000000..e209e1be0e --- /dev/null +++ b/src/openrct2/actions/StaffFireAction.hpp @@ -0,0 +1,72 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 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 "../interface/Window.h" +#include "../peep/Peep.h" +#include "../world/Sprite.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(StaffFireAction, GAME_COMMAND_FIRE_STAFF_MEMBER, GameActionResult) +{ +private: + uint16_t _spriteId; + +public: + StaffFireAction() + { + } + StaffFireAction(uint16_t spriteId) + : _spriteId(spriteId) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_spriteId); + } + + GameActionResult::Ptr Query() const override + { + if (_spriteId >= MAX_SPRITES) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + auto peep = GET_PEEP(_spriteId); + if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + auto peep = GET_PEEP(_spriteId); + if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + window_close_by_class(WC_FIRE_PROMPT); + peep_sprite_remove(peep); + return MakeResult(); + } +}; diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp new file mode 100644 index 0000000000..b287dbeecc --- /dev/null +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp @@ -0,0 +1,99 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 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 "../interface/Window.h" +#include "../peep/Peep.h" +#include "../peep/Staff.h" +#include "../world/Sprite.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(StaffSetPatrolAreaAction, GAME_COMMAND_SET_STAFF_PATROL, GameActionResult) +{ +private: + uint16_t _spriteId; + CoordsXY _loc; + +public: + StaffSetPatrolAreaAction() + { + } + StaffSetPatrolAreaAction(uint16_t spriteId, CoordsXY loc) + : _spriteId(spriteId) + , _loc(loc) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_spriteId) << DS_TAG(_loc); + } + + GameActionResult::Ptr Query() const override + { + if (_spriteId >= MAX_SPRITES) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + auto peep = GET_PEEP(_spriteId); + if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + auto peep = GET_PEEP(_spriteId); + if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) + { + log_error("Invalid spriteId."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + int32_t patrolOffset = peep->staff_id * STAFF_PATROL_AREA_SIZE; + + staff_toggle_patrol_area(peep->staff_id, _loc.x, _loc.y); + + int32_t ispatrolling = 0; + for (int32_t i = 0; i < 128; i++) + { + ispatrolling |= gStaffPatrolAreas[patrolOffset + i]; + } + + gStaffModes[peep->staff_id] &= ~(1 << 1); + if (ispatrolling) + { + gStaffModes[peep->staff_id] |= (1 << 1); + } + + for (int32_t y = 0; y < 4 * 32; y += 32) + { + for (int32_t x = 0; x < 4 * 32; x += 32) + { + map_invalidate_tile_full((_loc.x & 0x1F80) + x, (_loc.y & 0x1F80) + y); + } + } + staff_update_greyed_patrol_areas(); + + return MakeResult(); + } +}; From 0b231c8b380202ab0a307b067f5d85f7fcdceb7d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 20:47:54 +0000 Subject: [PATCH 049/506] Remove old game commands --- src/openrct2/Game.cpp | 4 +- src/openrct2/Game.h | 8 ++-- src/openrct2/peep/Staff.cpp | 87 ------------------------------------- src/openrct2/peep/Staff.h | 4 -- 4 files changed, 6 insertions(+), 97 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 791f428806..78018158ce 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1291,8 +1291,8 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_staff_patrol, - game_command_fire_staff_member, + nullptr, + nullptr, nullptr, nullptr, game_command_set_park_open, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index e0b759675a..cd2d18c298 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -49,10 +49,10 @@ enum GAME_COMMAND GAME_COMMAND_LOWER_WATER, // GA GAME_COMMAND_SET_BRAKES_SPEED, // GA GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA - GAME_COMMAND_SET_STAFF_PATROL, - GAME_COMMAND_FIRE_STAFF_MEMBER, - GAME_COMMAND_SET_STAFF_ORDERS, // GA - GAME_COMMAND_SET_PARK_NAME, // GA + GAME_COMMAND_SET_STAFF_PATROL, // GA + GAME_COMMAND_FIRE_STAFF_MEMBER, // GA + GAME_COMMAND_SET_STAFF_ORDERS, // GA + GAME_COMMAND_SET_PARK_NAME, // GA GAME_COMMAND_SET_PARK_OPEN, GAME_COMMAND_BUY_LAND_RIGHTS, GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 80203cf89c..39053bb261 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -82,93 +82,6 @@ void staff_reset_modes() staff_update_greyed_patrol_areas(); } -/** - * - * rct2: 0x006C09D1 - */ -void game_command_set_staff_patrol( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - if (*ebx & GAME_COMMAND_FLAG_APPLY) - { - int32_t x = *eax; - int32_t y = *ecx; - uint16_t sprite_id = *edx; - if (sprite_id >= MAX_SPRITES) - { - *ebx = MONEY32_UNDEFINED; - log_warning("Invalid sprite id %u", sprite_id); - return; - } - rct_sprite* sprite = get_sprite(sprite_id); - if (sprite->generic.sprite_identifier != SPRITE_IDENTIFIER_PEEP || sprite->peep.type != PEEP_TYPE_STAFF) - { - *ebx = MONEY32_UNDEFINED; - log_warning("Invalid type of sprite %u for game command", sprite_id); - return; - } - Peep* peep = &sprite->peep; - int32_t patrolOffset = peep->staff_id * STAFF_PATROL_AREA_SIZE; - - staff_toggle_patrol_area(peep->staff_id, x, y); - - int32_t ispatrolling = 0; - for (int32_t i = 0; i < 128; i++) - { - ispatrolling |= gStaffPatrolAreas[patrolOffset + i]; - } - - gStaffModes[peep->staff_id] &= ~2; - if (ispatrolling) - { - gStaffModes[peep->staff_id] |= 2; - } - - for (int32_t y2 = 0; y2 < 4; y2++) - { - for (int32_t x2 = 0; x2 < 4; x2++) - { - map_invalidate_tile_full((x & 0x1F80) + (x2 * 32), (y & 0x1F80) + (y2 * 32)); - } - } - staff_update_greyed_patrol_areas(); - } - *ebx = 0; -} - -/** - * - * rct2: 0x006C0B83 - */ -void game_command_fire_staff_member( - [[maybe_unused]] int32_t* eax, int32_t* ebx, [[maybe_unused]] int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_WAGES; - if (*ebx & GAME_COMMAND_FLAG_APPLY) - { - window_close_by_class(WC_FIRE_PROMPT); - uint16_t sprite_id = *edx; - if (sprite_id >= MAX_SPRITES) - { - log_warning("Invalid game command, sprite_id = %u", sprite_id); - *ebx = MONEY32_UNDEFINED; - return; - } - Peep* peep = &get_sprite(sprite_id)->peep; - if (peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) - { - log_warning( - "Invalid game command, peep->sprite_identifier = %u, peep->type = %u", peep->sprite_identifier, peep->type); - *ebx = MONEY32_UNDEFINED; - return; - } - peep_sprite_remove(peep); - } - *ebx = 0; -} - /** * Hires a new staff member of the given type. */ diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 30ef68ef5f..1c712f17a6 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -75,10 +75,6 @@ void game_command_hire_new_staff_member( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_callback_hire_new_staff_member( 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_staff_patrol( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_fire_staff_member( - 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_staff_name( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_pickup_staff( From ca92d63b2085f0f2809c3eb47478d5964931fc7e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 20:50:00 +0000 Subject: [PATCH 050/506] Put the correct copyright date on --- src/openrct2/actions/StaffFireAction.hpp | 2 +- src/openrct2/actions/StaffSetPatrolAreaAction.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/StaffFireAction.hpp b/src/openrct2/actions/StaffFireAction.hpp index e209e1be0e..30369e3c00 100644 --- a/src/openrct2/actions/StaffFireAction.hpp +++ b/src/openrct2/actions/StaffFireAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp index b287dbeecc..04339908ff 100644 --- a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 From 3b69c1c75eb4e2f1aa329a747f3348cd971d3d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 16 Mar 2019 13:53:26 -0700 Subject: [PATCH 051/506] Fix #8055: Ignore rendering specific fields for sprite checksum. (#8895) --- src/openrct2/network/Network.cpp | 2 +- src/openrct2/world/Sprite.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index a50594001b..69b291eddd 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 "2" +#define NETWORK_STREAM_VERSION "3" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index faf327f4e1..7ec54cb326 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -251,7 +251,10 @@ rct_sprite_checksum sprite_checksum() && sprite->generic.sprite_identifier != SPRITE_IDENTIFIER_MISC) { auto copy = *sprite; + + // Only required for rendering/invalidation, has no meaning to the game state. copy.generic.sprite_left = copy.generic.sprite_right = copy.generic.sprite_top = copy.generic.sprite_bottom = 0; + copy.generic.sprite_width = copy.generic.sprite_height_negative = copy.generic.sprite_height_positive = 0; if (copy.generic.sprite_identifier == SPRITE_IDENTIFIER_PEEP) { From 9e316f9191bda229e4a2e3d129644d7062462ab7 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 21:07:50 +0000 Subject: [PATCH 052/506] Fix formatting --- src/openrct2-ui/windows/StaffFirePrompt.cpp | 2 +- src/openrct2-ui/windows/StaffList.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/StaffFirePrompt.cpp b/src/openrct2-ui/windows/StaffFirePrompt.cpp index 6937e84312..d26be2fda0 100644 --- a/src/openrct2-ui/windows/StaffFirePrompt.cpp +++ b/src/openrct2-ui/windows/StaffFirePrompt.cpp @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index a02e4efd50..64e9e8c547 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -15,8 +15,8 @@ #include #include #include -#include #include +#include #include #include #include From 2af13904c59dac9c6815801f0220aad99da83288 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sun, 17 Mar 2019 08:16:15 +0100 Subject: [PATCH 053/506] Update copyright notices for 2019. (#8903) --- src/openrct2-cli/Cli.cpp | 2 +- src/openrct2-dll/openrct2-dll.cpp | 2 +- src/openrct2-ui/CursorData.cpp | 2 +- src/openrct2-ui/CursorRepository.cpp | 2 +- src/openrct2-ui/CursorRepository.h | 2 +- src/openrct2-ui/SDLException.h | 2 +- src/openrct2-ui/TextComposition.cpp | 2 +- src/openrct2-ui/TextComposition.h | 2 +- src/openrct2-ui/Ui.cpp | 2 +- src/openrct2-ui/Ui.h | 2 +- src/openrct2-ui/UiContext.Android.cpp | 2 +- src/openrct2-ui/UiContext.Linux.cpp | 2 +- src/openrct2-ui/UiContext.Win32.cpp | 2 +- src/openrct2-ui/UiContext.cpp | 2 +- src/openrct2-ui/UiContext.h | 2 +- src/openrct2-ui/UiContext.macOS.mm | 2 +- src/openrct2-ui/WindowManager.cpp | 2 +- src/openrct2-ui/WindowManager.h | 2 +- src/openrct2-ui/audio/AudioChannel.cpp | 2 +- src/openrct2-ui/audio/AudioContext.cpp | 2 +- src/openrct2-ui/audio/AudioContext.h | 2 +- src/openrct2-ui/audio/AudioFormat.h | 2 +- src/openrct2-ui/audio/AudioMixer.cpp | 2 +- src/openrct2-ui/audio/FileAudioSource.cpp | 2 +- src/openrct2-ui/audio/MemoryAudioSource.cpp | 2 +- src/openrct2-ui/drawing/BitmapReader.cpp | 2 +- src/openrct2-ui/drawing/BitmapReader.h | 2 +- src/openrct2-ui/drawing/engines/DrawingEngineFactory.hpp | 2 +- .../drawing/engines/HardwareDisplayDrawingEngine.cpp | 2 +- src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.h | 2 +- .../drawing/engines/opengl/ApplyTransparencyShader.cpp | 2 +- .../drawing/engines/opengl/ApplyTransparencyShader.h | 2 +- src/openrct2-ui/drawing/engines/opengl/DrawCommands.h | 2 +- src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h | 2 +- src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h | 2 +- src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h | 2 +- src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h | 2 +- src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/TextureCache.h | 2 +- src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp | 2 +- src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.h | 2 +- src/openrct2-ui/input/Input.cpp | 2 +- src/openrct2-ui/input/Input.h | 2 +- src/openrct2-ui/input/KeyboardShortcut.cpp | 2 +- src/openrct2-ui/input/KeyboardShortcuts.cpp | 2 +- src/openrct2-ui/input/KeyboardShortcuts.h | 2 +- src/openrct2-ui/input/MouseInput.cpp | 2 +- src/openrct2-ui/interface/Dropdown.h | 2 +- src/openrct2-ui/interface/Graph.cpp | 2 +- src/openrct2-ui/interface/Graph.h | 2 +- src/openrct2-ui/interface/InGameConsole.cpp | 2 +- src/openrct2-ui/interface/InGameConsole.h | 2 +- src/openrct2-ui/interface/LandTool.cpp | 2 +- src/openrct2-ui/interface/LandTool.h | 2 +- src/openrct2-ui/interface/Theme.cpp | 2 +- src/openrct2-ui/interface/Theme.h | 2 +- src/openrct2-ui/interface/Viewport.h | 2 +- src/openrct2-ui/interface/ViewportInteraction.cpp | 2 +- src/openrct2-ui/interface/Widget.cpp | 2 +- src/openrct2-ui/interface/Widget.h | 2 +- src/openrct2-ui/interface/Window.cpp | 2 +- src/openrct2-ui/interface/Window.h | 2 +- src/openrct2-ui/title/TitleSequencePlayer.cpp | 2 +- src/openrct2-ui/title/TitleSequencePlayer.h | 2 +- src/openrct2-ui/windows/About.cpp | 2 +- src/openrct2-ui/windows/Banner.cpp | 2 +- src/openrct2-ui/windows/Changelog.cpp | 2 +- src/openrct2-ui/windows/Cheats.cpp | 2 +- src/openrct2-ui/windows/ClearScenery.cpp | 2 +- src/openrct2-ui/windows/CustomCurrency.cpp | 2 +- src/openrct2-ui/windows/DebugPaint.cpp | 2 +- src/openrct2-ui/windows/DemolishRidePrompt.cpp | 2 +- src/openrct2-ui/windows/Dropdown.cpp | 2 +- src/openrct2-ui/windows/EditorBottomToolbar.cpp | 2 +- src/openrct2-ui/windows/EditorInventionsList.cpp | 2 +- src/openrct2-ui/windows/EditorMain.cpp | 2 +- src/openrct2-ui/windows/EditorObjectSelection.cpp | 2 +- src/openrct2-ui/windows/EditorObjectiveOptions.cpp | 2 +- src/openrct2-ui/windows/EditorScenarioOptions.cpp | 2 +- src/openrct2-ui/windows/Error.cpp | 2 +- src/openrct2-ui/windows/Finances.cpp | 2 +- src/openrct2-ui/windows/Footpath.cpp | 2 +- src/openrct2-ui/windows/GameBottomToolbar.cpp | 2 +- src/openrct2-ui/windows/Guest.cpp | 2 +- src/openrct2-ui/windows/GuestList.cpp | 2 +- src/openrct2-ui/windows/InstallTrack.cpp | 2 +- src/openrct2-ui/windows/Land.cpp | 2 +- src/openrct2-ui/windows/LandRights.cpp | 2 +- src/openrct2-ui/windows/LoadSave.cpp | 2 +- src/openrct2-ui/windows/Main.cpp | 2 +- src/openrct2-ui/windows/Map.cpp | 2 +- src/openrct2-ui/windows/MapGen.cpp | 2 +- src/openrct2-ui/windows/MapTooltip.cpp | 2 +- src/openrct2-ui/windows/MazeConstruction.cpp | 2 +- src/openrct2-ui/windows/Multiplayer.cpp | 2 +- src/openrct2-ui/windows/MusicCredits.cpp | 2 +- src/openrct2-ui/windows/NetworkStatus.cpp | 2 +- src/openrct2-ui/windows/NewCampaign.cpp | 2 +- src/openrct2-ui/windows/NewRide.cpp | 2 +- src/openrct2-ui/windows/News.cpp | 2 +- src/openrct2-ui/windows/NewsOptions.cpp | 2 +- src/openrct2-ui/windows/Options.cpp | 2 +- src/openrct2-ui/windows/Park.cpp | 2 +- src/openrct2-ui/windows/Player.cpp | 2 +- src/openrct2-ui/windows/Research.cpp | 2 +- src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2-ui/windows/RideList.cpp | 2 +- src/openrct2-ui/windows/SavePrompt.cpp | 2 +- src/openrct2-ui/windows/Scenery.cpp | 2 +- src/openrct2-ui/windows/ServerList.cpp | 2 +- src/openrct2-ui/windows/ServerStart.cpp | 2 +- src/openrct2-ui/windows/ShortcutKeyChange.cpp | 2 +- src/openrct2-ui/windows/ShortcutKeys.cpp | 2 +- src/openrct2-ui/windows/Sign.cpp | 2 +- src/openrct2-ui/windows/Staff.cpp | 2 +- src/openrct2-ui/windows/StaffFirePrompt.cpp | 2 +- src/openrct2-ui/windows/StaffList.cpp | 2 +- src/openrct2-ui/windows/TextInput.cpp | 2 +- src/openrct2-ui/windows/Themes.cpp | 2 +- src/openrct2-ui/windows/TileInspector.cpp | 2 +- src/openrct2-ui/windows/TitleCommandEditor.cpp | 2 +- src/openrct2-ui/windows/TitleEditor.cpp | 2 +- src/openrct2-ui/windows/TitleExit.cpp | 2 +- src/openrct2-ui/windows/TitleLogo.cpp | 2 +- src/openrct2-ui/windows/TitleMenu.cpp | 2 +- src/openrct2-ui/windows/TitleOptions.cpp | 2 +- src/openrct2-ui/windows/TitleScenarioSelect.cpp | 2 +- src/openrct2-ui/windows/Tooltip.cpp | 2 +- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2-ui/windows/TrackDesignManage.cpp | 2 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- src/openrct2-ui/windows/TrackList.cpp | 2 +- src/openrct2-ui/windows/ViewClipping.cpp | 2 +- src/openrct2-ui/windows/Viewport.cpp | 2 +- src/openrct2-ui/windows/Water.cpp | 2 +- src/openrct2-ui/windows/Window.h | 2 +- src/openrct2-win/openrct2-win.cpp | 2 +- src/openrct2/Cheats.cpp | 2 +- src/openrct2/Cheats.h | 2 +- src/openrct2/CmdlineSprite.cpp | 2 +- src/openrct2/CmdlineSprite.h | 2 +- src/openrct2/Context.cpp | 2 +- src/openrct2/Context.h | 2 +- src/openrct2/Date.cpp | 2 +- src/openrct2/Date.h | 2 +- src/openrct2/Diagnostic.cpp | 2 +- src/openrct2/Diagnostic.h | 2 +- src/openrct2/Editor.cpp | 2 +- src/openrct2/Editor.h | 2 +- src/openrct2/EditorObjectSelectionSession.cpp | 2 +- src/openrct2/EditorObjectSelectionSession.h | 2 +- src/openrct2/FileClassifier.cpp | 2 +- src/openrct2/FileClassifier.h | 2 +- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- src/openrct2/GameState.cpp | 2 +- src/openrct2/GameState.h | 2 +- src/openrct2/Input.cpp | 2 +- src/openrct2/Input.h | 2 +- src/openrct2/Intro.cpp | 2 +- src/openrct2/Intro.h | 2 +- src/openrct2/OpenRCT2.cpp | 2 +- src/openrct2/OpenRCT2.h | 2 +- src/openrct2/ParkImporter.cpp | 2 +- src/openrct2/ParkImporter.h | 2 +- src/openrct2/PlatformEnvironment.cpp | 2 +- src/openrct2/PlatformEnvironment.h | 2 +- src/openrct2/ReplayManager.cpp | 2 +- src/openrct2/ReplayManager.h | 2 +- src/openrct2/Version.cpp | 2 +- src/openrct2/Version.h | 2 +- src/openrct2/actions/BannerSetNameAction.hpp | 2 +- src/openrct2/actions/ClimateSetAction.hpp | 2 +- src/openrct2/actions/FootpathRemoveAction.hpp | 2 +- src/openrct2/actions/GameAction.cpp | 2 +- src/openrct2/actions/GameAction.h | 2 +- src/openrct2/actions/GameActionCompat.cpp | 2 +- src/openrct2/actions/GameActionRegistration.cpp | 2 +- src/openrct2/actions/GuestSetNameAction.hpp | 2 +- src/openrct2/actions/LandSetHeightAction.hpp | 2 +- src/openrct2/actions/LargeSceneryRemoveAction.hpp | 2 +- src/openrct2/actions/MazeSetTrackAction.hpp | 2 +- src/openrct2/actions/ParkMarketingAction.hpp | 2 +- src/openrct2/actions/ParkSetLoanAction.hpp | 2 +- src/openrct2/actions/ParkSetNameAction.hpp | 2 +- src/openrct2/actions/ParkSetResearchFundingAction.hpp | 2 +- src/openrct2/actions/PauseToggleAction.hpp | 2 +- src/openrct2/actions/PlaceParkEntranceAction.hpp | 2 +- src/openrct2/actions/PlacePeepSpawnAction.hpp | 2 +- src/openrct2/actions/RideCreateAction.hpp | 2 +- src/openrct2/actions/RideDemolishAction.hpp | 2 +- src/openrct2/actions/RideSetAppearanceAction.hpp | 2 +- src/openrct2/actions/RideSetColourScheme.hpp | 2 +- src/openrct2/actions/RideSetName.hpp | 2 +- src/openrct2/actions/RideSetStatus.hpp | 2 +- src/openrct2/actions/SetParkEntranceFeeAction.hpp | 2 +- src/openrct2/actions/SignSetNameAction.hpp | 2 +- src/openrct2/actions/SmallSceneryRemoveAction.hpp | 2 +- src/openrct2/actions/StaffSetColourAction.hpp | 2 +- src/openrct2/actions/StaffSetCostumeAction.hpp | 2 +- src/openrct2/actions/StaffSetNameAction.hpp | 2 +- src/openrct2/actions/StaffSetOrdersAction.hpp | 2 +- src/openrct2/actions/TrackPlaceAction.hpp | 2 +- src/openrct2/actions/TrackRemoveAction.hpp | 2 +- src/openrct2/actions/WallRemoveAction.hpp | 2 +- src/openrct2/audio/Audio.cpp | 2 +- src/openrct2/audio/AudioChannel.h | 2 +- src/openrct2/audio/AudioContext.h | 2 +- src/openrct2/audio/AudioMixer.cpp | 2 +- src/openrct2/audio/AudioMixer.h | 2 +- src/openrct2/audio/AudioSource.h | 2 +- src/openrct2/audio/DummyAudioContext.cpp | 2 +- src/openrct2/audio/NullAudioSource.cpp | 2 +- src/openrct2/audio/audio.h | 2 +- src/openrct2/cmdline/BenchGfxCommmands.cpp | 2 +- src/openrct2/cmdline/CommandLine.cpp | 2 +- src/openrct2/cmdline/CommandLine.hpp | 2 +- src/openrct2/cmdline/ConvertCommand.cpp | 2 +- src/openrct2/cmdline/RootCommands.cpp | 2 +- src/openrct2/cmdline/ScreenshotCommands.cpp | 2 +- src/openrct2/cmdline/SimulateCommands.cpp | 2 +- src/openrct2/cmdline/SpriteCommands.cpp | 2 +- src/openrct2/cmdline/UriHandler.cpp | 2 +- src/openrct2/common.h | 2 +- src/openrct2/config/Config.cpp | 2 +- src/openrct2/config/Config.h | 2 +- src/openrct2/config/ConfigEnum.hpp | 2 +- src/openrct2/config/IniReader.cpp | 2 +- src/openrct2/config/IniReader.hpp | 2 +- src/openrct2/config/IniWriter.cpp | 2 +- src/openrct2/config/IniWriter.hpp | 2 +- src/openrct2/core/Collections.hpp | 2 +- src/openrct2/core/Console.cpp | 2 +- src/openrct2/core/Console.hpp | 2 +- src/openrct2/core/Crypt.OpenSSL.cpp | 2 +- src/openrct2/core/Crypt.h | 2 +- src/openrct2/core/DataSerialiser.h | 2 +- src/openrct2/core/DataSerialiserTag.h | 2 +- src/openrct2/core/DataSerialiserTraits.h | 2 +- src/openrct2/core/Diagnostics.cpp | 2 +- src/openrct2/core/Diagnostics.hpp | 2 +- src/openrct2/core/Endianness.h | 2 +- src/openrct2/core/File.cpp | 2 +- src/openrct2/core/File.h | 2 +- src/openrct2/core/FileIndex.hpp | 2 +- src/openrct2/core/FileScanner.cpp | 2 +- src/openrct2/core/FileScanner.h | 2 +- src/openrct2/core/FileStream.hpp | 2 +- src/openrct2/core/Guard.cpp | 2 +- src/openrct2/core/Guard.hpp | 2 +- src/openrct2/core/IStream.cpp | 2 +- src/openrct2/core/IStream.hpp | 2 +- src/openrct2/core/Imaging.cpp | 2 +- src/openrct2/core/Imaging.h | 2 +- src/openrct2/core/JobPool.hpp | 2 +- src/openrct2/core/Json.cpp | 2 +- src/openrct2/core/Json.hpp | 2 +- src/openrct2/core/Memory.hpp | 2 +- src/openrct2/core/MemoryStream.cpp | 2 +- src/openrct2/core/MemoryStream.h | 2 +- src/openrct2/core/Nullable.hpp | 2 +- src/openrct2/core/Path.cpp | 2 +- src/openrct2/core/Path.hpp | 2 +- src/openrct2/core/Registration.hpp | 2 +- src/openrct2/core/String.cpp | 2 +- src/openrct2/core/String.hpp | 2 +- src/openrct2/core/StringBuilder.hpp | 2 +- src/openrct2/core/StringReader.hpp | 2 +- src/openrct2/core/Zip.cpp | 2 +- src/openrct2/core/Zip.h | 2 +- src/openrct2/core/ZipAndroid.cpp | 2 +- src/openrct2/drawing/AVX2Drawing.cpp | 2 +- src/openrct2/drawing/Drawing.Sprite.cpp | 2 +- src/openrct2/drawing/Drawing.String.cpp | 2 +- src/openrct2/drawing/Drawing.cpp | 2 +- src/openrct2/drawing/Drawing.h | 2 +- src/openrct2/drawing/DrawingFast.cpp | 2 +- src/openrct2/drawing/Font.cpp | 2 +- src/openrct2/drawing/Font.h | 2 +- src/openrct2/drawing/IDrawingContext.h | 2 +- src/openrct2/drawing/IDrawingEngine.h | 2 +- src/openrct2/drawing/Image.cpp | 2 +- src/openrct2/drawing/ImageImporter.cpp | 2 +- src/openrct2/drawing/ImageImporter.h | 2 +- src/openrct2/drawing/LightFX.cpp | 2 +- src/openrct2/drawing/LightFX.h | 2 +- src/openrct2/drawing/Line.cpp | 2 +- src/openrct2/drawing/NewDrawing.cpp | 2 +- src/openrct2/drawing/NewDrawing.h | 2 +- src/openrct2/drawing/Rain.cpp | 2 +- src/openrct2/drawing/Rain.h | 2 +- src/openrct2/drawing/Rect.cpp | 2 +- src/openrct2/drawing/SSE41Drawing.cpp | 2 +- src/openrct2/drawing/ScrollingText.cpp | 2 +- src/openrct2/drawing/TTF.cpp | 2 +- src/openrct2/drawing/TTF.h | 2 +- src/openrct2/drawing/Text.cpp | 2 +- src/openrct2/drawing/Text.h | 2 +- src/openrct2/drawing/X8DrawingEngine.cpp | 2 +- src/openrct2/drawing/X8DrawingEngine.h | 2 +- src/openrct2/interface/Chat.cpp | 2 +- src/openrct2/interface/Chat.h | 2 +- src/openrct2/interface/Colour.cpp | 2 +- src/openrct2/interface/Colour.h | 2 +- src/openrct2/interface/Cursors.h | 2 +- src/openrct2/interface/FontFamilies.cpp | 2 +- src/openrct2/interface/FontFamilies.h | 2 +- src/openrct2/interface/Fonts.cpp | 2 +- src/openrct2/interface/Fonts.h | 2 +- src/openrct2/interface/InteractiveConsole.cpp | 2 +- src/openrct2/interface/InteractiveConsole.h | 2 +- src/openrct2/interface/Screenshot.cpp | 2 +- src/openrct2/interface/Screenshot.h | 2 +- src/openrct2/interface/StdInOutConsole.cpp | 2 +- src/openrct2/interface/Viewport.cpp | 2 +- src/openrct2/interface/Viewport.h | 2 +- src/openrct2/interface/Widget.h | 2 +- src/openrct2/interface/Window.cpp | 2 +- src/openrct2/interface/Window.h | 2 +- src/openrct2/interface/Window_internal.h | 2 +- src/openrct2/localisation/ConversionTables.cpp | 2 +- src/openrct2/localisation/ConversionTables.h | 2 +- src/openrct2/localisation/Convert.cpp | 2 +- src/openrct2/localisation/Currency.cpp | 2 +- src/openrct2/localisation/Currency.h | 2 +- src/openrct2/localisation/Date.h | 2 +- src/openrct2/localisation/FormatCodes.cpp | 2 +- src/openrct2/localisation/FormatCodes.h | 2 +- src/openrct2/localisation/Language.cpp | 2 +- src/openrct2/localisation/Language.h | 2 +- src/openrct2/localisation/LanguagePack.cpp | 2 +- src/openrct2/localisation/LanguagePack.h | 2 +- src/openrct2/localisation/Localisation.Date.cpp | 2 +- src/openrct2/localisation/Localisation.cpp | 2 +- src/openrct2/localisation/Localisation.h | 2 +- src/openrct2/localisation/LocalisationService.cpp | 2 +- src/openrct2/localisation/LocalisationService.h | 2 +- src/openrct2/localisation/RealNames.cpp | 2 +- src/openrct2/localisation/StringIds.h | 2 +- src/openrct2/localisation/UTF8.cpp | 2 +- src/openrct2/localisation/User.cpp | 2 +- src/openrct2/localisation/User.h | 2 +- src/openrct2/management/Award.cpp | 2 +- src/openrct2/management/Award.h | 2 +- src/openrct2/management/Finance.cpp | 2 +- src/openrct2/management/Finance.h | 2 +- src/openrct2/management/Marketing.cpp | 2 +- src/openrct2/management/Marketing.h | 2 +- src/openrct2/management/NewsItem.cpp | 2 +- src/openrct2/management/NewsItem.h | 2 +- src/openrct2/management/Research.cpp | 2 +- src/openrct2/management/Research.h | 2 +- src/openrct2/network/DiscordService.cpp | 2 +- src/openrct2/network/DiscordService.h | 2 +- src/openrct2/network/Http.cpp | 2 +- src/openrct2/network/Http.h | 2 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkAction.cpp | 2 +- src/openrct2/network/NetworkAction.h | 2 +- src/openrct2/network/NetworkConnection.cpp | 2 +- src/openrct2/network/NetworkConnection.h | 2 +- src/openrct2/network/NetworkGroup.cpp | 2 +- src/openrct2/network/NetworkGroup.h | 2 +- src/openrct2/network/NetworkKey.cpp | 2 +- src/openrct2/network/NetworkKey.h | 2 +- src/openrct2/network/NetworkPacket.cpp | 2 +- src/openrct2/network/NetworkPacket.h | 2 +- src/openrct2/network/NetworkPlayer.cpp | 2 +- src/openrct2/network/NetworkPlayer.h | 2 +- src/openrct2/network/NetworkServerAdvertiser.cpp | 2 +- src/openrct2/network/NetworkServerAdvertiser.h | 2 +- src/openrct2/network/NetworkTypes.h | 2 +- src/openrct2/network/NetworkUser.cpp | 2 +- src/openrct2/network/NetworkUser.h | 2 +- src/openrct2/network/ServerList.cpp | 2 +- src/openrct2/network/ServerList.h | 2 +- src/openrct2/network/TcpSocket.cpp | 2 +- src/openrct2/network/TcpSocket.h | 2 +- src/openrct2/network/Twitch.cpp | 2 +- src/openrct2/network/network.h | 2 +- src/openrct2/network/twitch.h | 2 +- src/openrct2/object/BannerObject.cpp | 2 +- src/openrct2/object/BannerObject.h | 2 +- src/openrct2/object/DefaultObjects.cpp | 2 +- src/openrct2/object/DefaultObjects.h | 2 +- src/openrct2/object/EntranceObject.cpp | 2 +- src/openrct2/object/EntranceObject.h | 2 +- src/openrct2/object/FootpathItemObject.cpp | 2 +- src/openrct2/object/FootpathItemObject.h | 2 +- src/openrct2/object/FootpathObject.cpp | 2 +- src/openrct2/object/FootpathObject.h | 2 +- src/openrct2/object/ImageTable.cpp | 2 +- src/openrct2/object/ImageTable.h | 2 +- src/openrct2/object/LargeSceneryObject.cpp | 2 +- src/openrct2/object/LargeSceneryObject.h | 2 +- src/openrct2/object/Object.cpp | 2 +- src/openrct2/object/Object.h | 2 +- src/openrct2/object/ObjectFactory.cpp | 2 +- src/openrct2/object/ObjectFactory.h | 2 +- src/openrct2/object/ObjectJsonHelpers.cpp | 2 +- src/openrct2/object/ObjectJsonHelpers.h | 2 +- src/openrct2/object/ObjectLimits.h | 2 +- src/openrct2/object/ObjectList.cpp | 2 +- src/openrct2/object/ObjectList.h | 2 +- src/openrct2/object/ObjectManager.cpp | 2 +- src/openrct2/object/ObjectManager.h | 2 +- src/openrct2/object/ObjectRepository.cpp | 2 +- src/openrct2/object/ObjectRepository.h | 2 +- src/openrct2/object/RideObject.cpp | 2 +- src/openrct2/object/RideObject.h | 2 +- src/openrct2/object/SceneryGroupObject.cpp | 2 +- src/openrct2/object/SceneryGroupObject.h | 2 +- src/openrct2/object/SceneryObject.cpp | 2 +- src/openrct2/object/SceneryObject.h | 2 +- src/openrct2/object/SmallSceneryObject.cpp | 2 +- src/openrct2/object/SmallSceneryObject.h | 2 +- src/openrct2/object/StationObject.cpp | 2 +- src/openrct2/object/StationObject.h | 2 +- src/openrct2/object/StringTable.cpp | 2 +- src/openrct2/object/StringTable.h | 2 +- src/openrct2/object/TerrainEdgeObject.cpp | 2 +- src/openrct2/object/TerrainEdgeObject.h | 2 +- src/openrct2/object/TerrainSurfaceObject.cpp | 2 +- src/openrct2/object/TerrainSurfaceObject.h | 2 +- src/openrct2/object/WallObject.cpp | 2 +- src/openrct2/object/WallObject.h | 2 +- src/openrct2/object/WaterObject.cpp | 2 +- src/openrct2/object/WaterObject.h | 2 +- src/openrct2/paint/Paint.cpp | 2 +- src/openrct2/paint/Paint.h | 2 +- src/openrct2/paint/PaintHelpers.cpp | 2 +- src/openrct2/paint/Painter.cpp | 2 +- src/openrct2/paint/Painter.h | 2 +- src/openrct2/paint/Supports.cpp | 2 +- src/openrct2/paint/Supports.h | 2 +- src/openrct2/paint/VirtualFloor.cpp | 2 +- src/openrct2/paint/VirtualFloor.h | 2 +- src/openrct2/paint/sprite/Paint.Litter.cpp | 2 +- src/openrct2/paint/sprite/Paint.Misc.cpp | 2 +- src/openrct2/paint/sprite/Paint.Peep.cpp | 2 +- src/openrct2/paint/sprite/Paint.Sprite.cpp | 2 +- src/openrct2/paint/sprite/Paint.Sprite.h | 2 +- src/openrct2/paint/tile_element/Paint.Banner.cpp | 2 +- src/openrct2/paint/tile_element/Paint.Entrance.cpp | 2 +- src/openrct2/paint/tile_element/Paint.LargeScenery.cpp | 2 +- src/openrct2/paint/tile_element/Paint.Path.cpp | 2 +- src/openrct2/paint/tile_element/Paint.SmallScenery.cpp | 2 +- src/openrct2/paint/tile_element/Paint.Surface.cpp | 2 +- src/openrct2/paint/tile_element/Paint.Surface.h | 2 +- src/openrct2/paint/tile_element/Paint.TileElement.cpp | 2 +- src/openrct2/paint/tile_element/Paint.TileElement.h | 2 +- src/openrct2/paint/tile_element/Paint.Wall.cpp | 2 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/peep/GuestPathfinding.cpp | 2 +- src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/peep/Peep.h | 2 +- src/openrct2/peep/PeepData.cpp | 2 +- src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/peep/Staff.h | 2 +- src/openrct2/platform/Android.cpp | 2 +- src/openrct2/platform/Crash.cpp | 2 +- src/openrct2/platform/Crash.h | 2 +- src/openrct2/platform/Linux.cpp | 2 +- src/openrct2/platform/Platform.Android.cpp | 2 +- src/openrct2/platform/Platform.Linux.cpp | 2 +- src/openrct2/platform/Platform.Posix.cpp | 2 +- src/openrct2/platform/Platform.Win32.cpp | 2 +- src/openrct2/platform/Platform.macOS.mm | 2 +- src/openrct2/platform/Platform2.h | 2 +- src/openrct2/platform/Posix.cpp | 2 +- src/openrct2/platform/Shared.cpp | 2 +- src/openrct2/platform/Windows.cpp | 2 +- src/openrct2/platform/macos.mm | 2 +- src/openrct2/platform/platform.h | 2 +- src/openrct2/rct1/RCT1.h | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct1/Tables.cpp | 2 +- src/openrct2/rct1/Tables.h | 2 +- src/openrct2/rct12/RCT12.cpp | 2 +- src/openrct2/rct12/RCT12.h | 2 +- src/openrct2/rct12/SawyerChunk.cpp | 2 +- src/openrct2/rct12/SawyerChunk.h | 2 +- src/openrct2/rct12/SawyerChunkReader.cpp | 2 +- src/openrct2/rct12/SawyerChunkReader.h | 2 +- src/openrct2/rct12/SawyerChunkWriter.cpp | 2 +- src/openrct2/rct12/SawyerChunkWriter.h | 2 +- src/openrct2/rct12/SawyerEncoding.cpp | 2 +- src/openrct2/rct12/SawyerEncoding.h | 2 +- src/openrct2/rct2/RCT2.h | 2 +- src/openrct2/rct2/S6Exporter.cpp | 2 +- src/openrct2/rct2/S6Exporter.h | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/CableLift.cpp | 2 +- src/openrct2/ride/CableLift.h | 2 +- src/openrct2/ride/MusicList.cpp | 2 +- src/openrct2/ride/MusicList.h | 2 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/Ride.h | 2 +- src/openrct2/ride/RideData.cpp | 2 +- src/openrct2/ride/RideData.h | 2 +- src/openrct2/ride/RideGroupManager.cpp | 2 +- src/openrct2/ride/RideGroupManager.h | 2 +- src/openrct2/ride/RideRatings.cpp | 2 +- src/openrct2/ride/RideRatings.h | 2 +- src/openrct2/ride/RideTypes.h | 2 +- src/openrct2/ride/ShopItem.cpp | 2 +- src/openrct2/ride/ShopItem.h | 2 +- src/openrct2/ride/Station.cpp | 2 +- src/openrct2/ride/Station.h | 2 +- src/openrct2/ride/Track.cpp | 2 +- src/openrct2/ride/Track.h | 2 +- src/openrct2/ride/TrackData.cpp | 2 +- src/openrct2/ride/TrackData.h | 2 +- src/openrct2/ride/TrackDataOld.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 2 +- src/openrct2/ride/TrackDesign.h | 2 +- src/openrct2/ride/TrackDesignRepository.cpp | 2 +- src/openrct2/ride/TrackDesignRepository.h | 2 +- src/openrct2/ride/TrackDesignSave.cpp | 2 +- src/openrct2/ride/TrackPaint.cpp | 2 +- src/openrct2/ride/TrackPaint.h | 2 +- src/openrct2/ride/Vehicle.cpp | 2 +- src/openrct2/ride/Vehicle.h | 2 +- src/openrct2/ride/VehicleData.cpp | 2 +- src/openrct2/ride/VehicleData.h | 2 +- src/openrct2/ride/VehiclePaint.cpp | 2 +- src/openrct2/ride/VehiclePaint.h | 2 +- src/openrct2/ride/coaster/AirPoweredVerticalCoaster.cpp | 2 +- src/openrct2/ride/coaster/BobsleighCoaster.cpp | 2 +- src/openrct2/ride/coaster/BolligerMabillardTrack.cpp | 2 +- src/openrct2/ride/coaster/BolligerMabillardTrack.h | 2 +- src/openrct2/ride/coaster/CompactInvertedCoaster.cpp | 2 +- src/openrct2/ride/coaster/CorkscrewRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/FlyingRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/GigaCoaster.cpp | 2 +- src/openrct2/ride/coaster/HeartlineTwisterCoaster.cpp | 2 +- src/openrct2/ride/coaster/InvertedHairpinCoaster.cpp | 2 +- src/openrct2/ride/coaster/InvertedImpulseCoaster.cpp | 2 +- src/openrct2/ride/coaster/InvertedRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/JuniorRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/JuniorRollerCoaster.h | 2 +- src/openrct2/ride/coaster/LayDownRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/LimLaunchedRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/LoopingRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/MineRide.cpp | 2 +- src/openrct2/ride/coaster/MineTrainCoaster.cpp | 2 +- src/openrct2/ride/coaster/MiniRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/MiniSuspendedCoaster.cpp | 2 +- src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/ReverseFreefallCoaster.cpp | 2 +- src/openrct2/ride/coaster/ReverserRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/SideFrictionRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/StandUpRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/Steeplechase.cpp | 2 +- src/openrct2/ride/coaster/SuspendedSwingingCoaster.cpp | 2 +- src/openrct2/ride/coaster/TwisterRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/VerticalDropRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/VirginiaReel.cpp | 2 +- src/openrct2/ride/coaster/WildMouse.cpp | 2 +- src/openrct2/ride/coaster/WoodenRollerCoaster.cpp | 2 +- src/openrct2/ride/coaster/WoodenWildMouse.cpp | 2 +- src/openrct2/ride/gentle/CarRide.cpp | 2 +- src/openrct2/ride/gentle/CircusShow.cpp | 2 +- src/openrct2/ride/gentle/CrookedHouse.cpp | 2 +- src/openrct2/ride/gentle/Dodgems.cpp | 2 +- src/openrct2/ride/gentle/FerrisWheel.cpp | 2 +- src/openrct2/ride/gentle/FlyingSaucers.cpp | 2 +- src/openrct2/ride/gentle/GhostTrain.cpp | 2 +- src/openrct2/ride/gentle/HauntedHouse.cpp | 2 +- src/openrct2/ride/gentle/Maze.cpp | 2 +- src/openrct2/ride/gentle/MerryGoRound.cpp | 2 +- src/openrct2/ride/gentle/MiniGolf.cpp | 2 +- src/openrct2/ride/gentle/MiniHelicopters.cpp | 2 +- src/openrct2/ride/gentle/MonorailCycles.cpp | 2 +- src/openrct2/ride/gentle/ObservationTower.cpp | 2 +- src/openrct2/ride/gentle/SpaceRings.cpp | 2 +- src/openrct2/ride/gentle/SpiralSlide.cpp | 2 +- src/openrct2/ride/shops/Facility.cpp | 2 +- src/openrct2/ride/shops/Shop.cpp | 2 +- src/openrct2/ride/thrill/3dCinema.cpp | 2 +- src/openrct2/ride/thrill/Enterprise.cpp | 2 +- src/openrct2/ride/thrill/GoKarts.cpp | 2 +- src/openrct2/ride/thrill/LaunchedFreefall.cpp | 2 +- src/openrct2/ride/thrill/MagicCarpet.cpp | 2 +- src/openrct2/ride/thrill/MotionSimulator.cpp | 2 +- src/openrct2/ride/thrill/PirateShip.cpp | 2 +- src/openrct2/ride/thrill/RotoDrop.cpp | 2 +- src/openrct2/ride/thrill/SwingingInverterShip.cpp | 2 +- src/openrct2/ride/thrill/TopSpin.cpp | 2 +- src/openrct2/ride/thrill/Twist.cpp | 2 +- src/openrct2/ride/transport/Chairlift.cpp | 2 +- src/openrct2/ride/transport/Lift.cpp | 2 +- src/openrct2/ride/transport/MiniatureRailway.cpp | 2 +- src/openrct2/ride/transport/Monorail.cpp | 2 +- src/openrct2/ride/transport/SuspendedMonorail.cpp | 2 +- src/openrct2/ride/water/BoatHire.cpp | 2 +- src/openrct2/ride/water/DingySlide.cpp | 2 +- src/openrct2/ride/water/LogFlume.cpp | 2 +- src/openrct2/ride/water/RiverRapids.cpp | 2 +- src/openrct2/ride/water/SplashBoats.cpp | 2 +- src/openrct2/ride/water/SubmarineRide.cpp | 2 +- src/openrct2/ride/water/WaterCoaster.cpp | 2 +- src/openrct2/scenario/Scenario.cpp | 2 +- src/openrct2/scenario/Scenario.h | 2 +- src/openrct2/scenario/ScenarioRepository.cpp | 2 +- src/openrct2/scenario/ScenarioRepository.h | 2 +- src/openrct2/scenario/ScenarioSources.cpp | 2 +- src/openrct2/scenario/ScenarioSources.h | 2 +- src/openrct2/sprites.h | 2 +- src/openrct2/title/TitleScreen.cpp | 2 +- src/openrct2/title/TitleScreen.h | 2 +- src/openrct2/title/TitleSequence.cpp | 2 +- src/openrct2/title/TitleSequence.h | 2 +- src/openrct2/title/TitleSequenceManager.cpp | 2 +- src/openrct2/title/TitleSequenceManager.h | 2 +- src/openrct2/title/TitleSequencePlayer.h | 2 +- src/openrct2/ui/DummyUiContext.cpp | 2 +- src/openrct2/ui/DummyWindowManager.cpp | 2 +- src/openrct2/ui/UiContext.h | 2 +- src/openrct2/ui/WindowManager.h | 2 +- src/openrct2/util/SawyerCoding.cpp | 2 +- src/openrct2/util/SawyerCoding.h | 2 +- src/openrct2/util/Util.cpp | 2 +- src/openrct2/util/Util.h | 2 +- src/openrct2/windows/Intent.cpp | 2 +- src/openrct2/windows/Intent.h | 2 +- src/openrct2/windows/_legacy.cpp | 2 +- src/openrct2/windows/tile_inspector.h | 2 +- src/openrct2/world/Balloon.cpp | 2 +- src/openrct2/world/Banner.cpp | 2 +- src/openrct2/world/Banner.h | 2 +- src/openrct2/world/Climate.cpp | 2 +- src/openrct2/world/Climate.h | 2 +- src/openrct2/world/Duck.cpp | 2 +- src/openrct2/world/Entrance.cpp | 2 +- src/openrct2/world/Entrance.h | 2 +- src/openrct2/world/Footpath.cpp | 2 +- src/openrct2/world/Footpath.h | 2 +- src/openrct2/world/Fountain.cpp | 2 +- src/openrct2/world/Fountain.h | 2 +- src/openrct2/world/LargeScenery.cpp | 2 +- src/openrct2/world/LargeScenery.h | 2 +- src/openrct2/world/Location.hpp | 2 +- src/openrct2/world/Map.cpp | 2 +- src/openrct2/world/Map.h | 2 +- src/openrct2/world/MapAnimation.cpp | 2 +- src/openrct2/world/MapAnimation.h | 2 +- src/openrct2/world/MapGen.cpp | 2 +- src/openrct2/world/MapGen.h | 2 +- src/openrct2/world/MapHelpers.cpp | 2 +- src/openrct2/world/MapHelpers.h | 2 +- src/openrct2/world/MoneyEffect.cpp | 2 +- src/openrct2/world/Park.cpp | 2 +- src/openrct2/world/Park.h | 2 +- src/openrct2/world/Particle.cpp | 2 +- src/openrct2/world/Scenery.cpp | 2 +- src/openrct2/world/Scenery.h | 2 +- src/openrct2/world/SmallScenery.cpp | 2 +- src/openrct2/world/SmallScenery.h | 2 +- src/openrct2/world/Sprite.cpp | 2 +- src/openrct2/world/Sprite.h | 2 +- src/openrct2/world/Surface.cpp | 2 +- src/openrct2/world/Surface.h | 2 +- src/openrct2/world/TileElement.cpp | 2 +- src/openrct2/world/TileElement.h | 2 +- src/openrct2/world/TileInspector.cpp | 2 +- src/openrct2/world/TileInspector.h | 2 +- src/openrct2/world/Wall.cpp | 2 +- src/openrct2/world/Wall.h | 2 +- src/openrct2/world/Water.h | 2 +- 684 files changed, 684 insertions(+), 684 deletions(-) diff --git a/src/openrct2-cli/Cli.cpp b/src/openrct2-cli/Cli.cpp index 7587c39413..a063be9185 100644 --- a/src/openrct2-cli/Cli.cpp +++ b/src/openrct2-cli/Cli.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-dll/openrct2-dll.cpp b/src/openrct2-dll/openrct2-dll.cpp index 9fdf22ea51..213147af8a 100644 --- a/src/openrct2-dll/openrct2-dll.cpp +++ b/src/openrct2-dll/openrct2-dll.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/CursorData.cpp b/src/openrct2-ui/CursorData.cpp index 1b2d920ff8..4c24f24a64 100644 --- a/src/openrct2-ui/CursorData.cpp +++ b/src/openrct2-ui/CursorData.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/CursorRepository.cpp b/src/openrct2-ui/CursorRepository.cpp index 19a1e2f687..d8070612bd 100644 --- a/src/openrct2-ui/CursorRepository.cpp +++ b/src/openrct2-ui/CursorRepository.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/CursorRepository.h b/src/openrct2-ui/CursorRepository.h index 60c1705dab..3f415dac05 100644 --- a/src/openrct2-ui/CursorRepository.h +++ b/src/openrct2-ui/CursorRepository.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/SDLException.h b/src/openrct2-ui/SDLException.h index 9e16709b18..8bc3991e26 100644 --- a/src/openrct2-ui/SDLException.h +++ b/src/openrct2-ui/SDLException.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/TextComposition.cpp b/src/openrct2-ui/TextComposition.cpp index ec0cf6d0ea..e6c9b516c4 100644 --- a/src/openrct2-ui/TextComposition.cpp +++ b/src/openrct2-ui/TextComposition.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/TextComposition.h b/src/openrct2-ui/TextComposition.h index ab656caa29..ce8dceb9f4 100644 --- a/src/openrct2-ui/TextComposition.h +++ b/src/openrct2-ui/TextComposition.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/Ui.cpp b/src/openrct2-ui/Ui.cpp index 3dbe526b61..22ebaeada3 100644 --- a/src/openrct2-ui/Ui.cpp +++ b/src/openrct2-ui/Ui.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/Ui.h b/src/openrct2-ui/Ui.h index 195411031d..991e0ef338 100644 --- a/src/openrct2-ui/Ui.h +++ b/src/openrct2-ui/Ui.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.Android.cpp b/src/openrct2-ui/UiContext.Android.cpp index a5152e090f..a911a3bc49 100644 --- a/src/openrct2-ui/UiContext.Android.cpp +++ b/src/openrct2-ui/UiContext.Android.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index 4c391581ed..bf927707f7 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.Win32.cpp b/src/openrct2-ui/UiContext.Win32.cpp index 621daa96a4..67b6365b97 100644 --- a/src/openrct2-ui/UiContext.Win32.cpp +++ b/src/openrct2-ui/UiContext.Win32.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index f15ff3e78d..0c2b9b6b80 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.h b/src/openrct2-ui/UiContext.h index cbfb44b418..fae1ad6926 100644 --- a/src/openrct2-ui/UiContext.h +++ b/src/openrct2-ui/UiContext.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/UiContext.macOS.mm b/src/openrct2-ui/UiContext.macOS.mm index eb7b24a46b..a07836a712 100644 --- a/src/openrct2-ui/UiContext.macOS.mm +++ b/src/openrct2-ui/UiContext.macOS.mm @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index edd6f12b19..8c8e497466 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/WindowManager.h b/src/openrct2-ui/WindowManager.h index 0f13c8579f..4e6c0286eb 100644 --- a/src/openrct2-ui/WindowManager.h +++ b/src/openrct2-ui/WindowManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/AudioChannel.cpp b/src/openrct2-ui/audio/AudioChannel.cpp index 6aba2cfec7..4e9872a757 100644 --- a/src/openrct2-ui/audio/AudioChannel.cpp +++ b/src/openrct2-ui/audio/AudioChannel.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/AudioContext.cpp b/src/openrct2-ui/audio/AudioContext.cpp index ecb9caf59e..c9e5833bc3 100644 --- a/src/openrct2-ui/audio/AudioContext.cpp +++ b/src/openrct2-ui/audio/AudioContext.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/AudioContext.h b/src/openrct2-ui/audio/AudioContext.h index a0df39e572..7078e59923 100644 --- a/src/openrct2-ui/audio/AudioContext.h +++ b/src/openrct2-ui/audio/AudioContext.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/AudioFormat.h b/src/openrct2-ui/audio/AudioFormat.h index 40341bfd85..bba2feb6ed 100644 --- a/src/openrct2-ui/audio/AudioFormat.h +++ b/src/openrct2-ui/audio/AudioFormat.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/AudioMixer.cpp b/src/openrct2-ui/audio/AudioMixer.cpp index a4d4f859fb..31ee027ba0 100644 --- a/src/openrct2-ui/audio/AudioMixer.cpp +++ b/src/openrct2-ui/audio/AudioMixer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/FileAudioSource.cpp b/src/openrct2-ui/audio/FileAudioSource.cpp index 51e54e91f3..f623cfcb22 100644 --- a/src/openrct2-ui/audio/FileAudioSource.cpp +++ b/src/openrct2-ui/audio/FileAudioSource.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/audio/MemoryAudioSource.cpp b/src/openrct2-ui/audio/MemoryAudioSource.cpp index 64b85ab71b..693f159275 100644 --- a/src/openrct2-ui/audio/MemoryAudioSource.cpp +++ b/src/openrct2-ui/audio/MemoryAudioSource.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/BitmapReader.cpp b/src/openrct2-ui/drawing/BitmapReader.cpp index ef76134898..820e782ae4 100644 --- a/src/openrct2-ui/drawing/BitmapReader.cpp +++ b/src/openrct2-ui/drawing/BitmapReader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/BitmapReader.h b/src/openrct2-ui/drawing/BitmapReader.h index 4328b01c15..232fdc3491 100644 --- a/src/openrct2-ui/drawing/BitmapReader.h +++ b/src/openrct2-ui/drawing/BitmapReader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/DrawingEngineFactory.hpp b/src/openrct2-ui/drawing/engines/DrawingEngineFactory.hpp index 64924a7999..f78083a076 100644 --- a/src/openrct2-ui/drawing/engines/DrawingEngineFactory.hpp +++ b/src/openrct2-ui/drawing/engines/DrawingEngineFactory.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp index cc1895738e..c50b86bfab 100644 --- a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp index 440a0bd3d2..4ef671c301 100644 --- a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp index fe7e15c3d1..6ee690e44a 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.h b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.h index 8312da39ad..e0677a667a 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp index 983b36e856..5eb10a33bd 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.h b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.h index df740994c8..c61c33b3ef 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h index 3d78a49e27..464c37a0f3 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawCommands.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp index 8a4104f975..19cba2d1e2 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h index c7c79c1a9c..2ecb36f0ec 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp index 4486471162..c2bf52ec31 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h index d335e84f35..1d5f2dc081 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h +++ b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h b/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h index 0f13b94039..8a730ae853 100644 --- a/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h +++ b/src/openrct2-ui/drawing/engines/opengl/GLSLTypes.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp index 54404f6489..6408a2217d 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h index 06918caf23..a426f2058c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h index b5c894af35..f0e3fa3313 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index f3279ebb04..7b79d116e6 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp index 8b2b01583d..fe1c15945b 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h index 180daa1d96..8e226911af 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp index 0d2738ac55..44f4e92f18 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h index f974bdb33f..6eef387c8d 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp index dd902c6a21..9d113dfb49 100644 --- a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h index bbbe0767ae..d76c53d6ab 100644 --- a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h +++ b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 211bfb0558..caf65149a0 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index 430f9658af..c763e5c448 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp index d134ee1256..ebfbb2739a 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.h b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.h index 5b824ff43e..0db234995b 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.h +++ b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/Input.cpp b/src/openrct2-ui/input/Input.cpp index 080cc29f27..ca612907ef 100644 --- a/src/openrct2-ui/input/Input.cpp +++ b/src/openrct2-ui/input/Input.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/Input.h b/src/openrct2-ui/input/Input.h index f5c593b634..d37e91a736 100644 --- a/src/openrct2-ui/input/Input.h +++ b/src/openrct2-ui/input/Input.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/KeyboardShortcut.cpp b/src/openrct2-ui/input/KeyboardShortcut.cpp index 291fc6cc0e..e2e3818c01 100644 --- a/src/openrct2-ui/input/KeyboardShortcut.cpp +++ b/src/openrct2-ui/input/KeyboardShortcut.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/KeyboardShortcuts.cpp b/src/openrct2-ui/input/KeyboardShortcuts.cpp index 79bffcb762..e6e7422ae8 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.cpp +++ b/src/openrct2-ui/input/KeyboardShortcuts.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/KeyboardShortcuts.h b/src/openrct2-ui/input/KeyboardShortcuts.h index 9b546be59e..b0418d6dcd 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.h +++ b/src/openrct2-ui/input/KeyboardShortcuts.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/input/MouseInput.cpp b/src/openrct2-ui/input/MouseInput.cpp index 316645ccbb..9978cac6f2 100644 --- a/src/openrct2-ui/input/MouseInput.cpp +++ b/src/openrct2-ui/input/MouseInput.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Dropdown.h b/src/openrct2-ui/interface/Dropdown.h index ff1002826a..b1c7e54303 100644 --- a/src/openrct2-ui/interface/Dropdown.h +++ b/src/openrct2-ui/interface/Dropdown.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Graph.cpp b/src/openrct2-ui/interface/Graph.cpp index fd625524fe..8203908f44 100644 --- a/src/openrct2-ui/interface/Graph.cpp +++ b/src/openrct2-ui/interface/Graph.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Graph.h b/src/openrct2-ui/interface/Graph.h index f818a6c059..288aa871cb 100644 --- a/src/openrct2-ui/interface/Graph.h +++ b/src/openrct2-ui/interface/Graph.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/InGameConsole.cpp b/src/openrct2-ui/interface/InGameConsole.cpp index 2f0c4c2c19..81ee2d3780 100644 --- a/src/openrct2-ui/interface/InGameConsole.cpp +++ b/src/openrct2-ui/interface/InGameConsole.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/InGameConsole.h b/src/openrct2-ui/interface/InGameConsole.h index faf91ab152..e84b48b155 100644 --- a/src/openrct2-ui/interface/InGameConsole.h +++ b/src/openrct2-ui/interface/InGameConsole.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/LandTool.cpp b/src/openrct2-ui/interface/LandTool.cpp index 6204676cdd..acfe9088c6 100644 --- a/src/openrct2-ui/interface/LandTool.cpp +++ b/src/openrct2-ui/interface/LandTool.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/LandTool.h b/src/openrct2-ui/interface/LandTool.h index 979ee421ff..24a2a3f3e4 100644 --- a/src/openrct2-ui/interface/LandTool.h +++ b/src/openrct2-ui/interface/LandTool.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Theme.cpp b/src/openrct2-ui/interface/Theme.cpp index 8afd239d7d..87c6c44a1c 100644 --- a/src/openrct2-ui/interface/Theme.cpp +++ b/src/openrct2-ui/interface/Theme.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Theme.h b/src/openrct2-ui/interface/Theme.h index 9e9df952eb..4be5d8d5c9 100644 --- a/src/openrct2-ui/interface/Theme.h +++ b/src/openrct2-ui/interface/Theme.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Viewport.h b/src/openrct2-ui/interface/Viewport.h index 1982da7c86..4618010908 100644 --- a/src/openrct2-ui/interface/Viewport.h +++ b/src/openrct2-ui/interface/Viewport.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 0b9b40fb20..3379a78cd1 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Widget.cpp b/src/openrct2-ui/interface/Widget.cpp index 663a78ffdb..48a291ab54 100644 --- a/src/openrct2-ui/interface/Widget.cpp +++ b/src/openrct2-ui/interface/Widget.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Widget.h b/src/openrct2-ui/interface/Widget.h index c107f94bc7..981aa980d7 100644 --- a/src/openrct2-ui/interface/Widget.h +++ b/src/openrct2-ui/interface/Widget.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Window.cpp b/src/openrct2-ui/interface/Window.cpp index d5cac3a33f..6ee962f876 100644 --- a/src/openrct2-ui/interface/Window.cpp +++ b/src/openrct2-ui/interface/Window.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/interface/Window.h b/src/openrct2-ui/interface/Window.h index d5c91ea3da..e107ceb0d5 100644 --- a/src/openrct2-ui/interface/Window.h +++ b/src/openrct2-ui/interface/Window.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/title/TitleSequencePlayer.cpp b/src/openrct2-ui/title/TitleSequencePlayer.cpp index 30aef26573..3e6117ada0 100644 --- a/src/openrct2-ui/title/TitleSequencePlayer.cpp +++ b/src/openrct2-ui/title/TitleSequencePlayer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/title/TitleSequencePlayer.h b/src/openrct2-ui/title/TitleSequencePlayer.h index bcf9ae6e6a..ceead91e35 100644 --- a/src/openrct2-ui/title/TitleSequencePlayer.h +++ b/src/openrct2-ui/title/TitleSequencePlayer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/About.cpp b/src/openrct2-ui/windows/About.cpp index dc961cf33a..6ea30ba5a1 100644 --- a/src/openrct2-ui/windows/About.cpp +++ b/src/openrct2-ui/windows/About.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index 44467e0d20..d080dcbd50 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Changelog.cpp b/src/openrct2-ui/windows/Changelog.cpp index 151e356ca6..97c3308f59 100644 --- a/src/openrct2-ui/windows/Changelog.cpp +++ b/src/openrct2-ui/windows/Changelog.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index d00b47db97..b3d9e75757 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ClearScenery.cpp b/src/openrct2-ui/windows/ClearScenery.cpp index 24bb6e3a0c..81f46e46ca 100644 --- a/src/openrct2-ui/windows/ClearScenery.cpp +++ b/src/openrct2-ui/windows/ClearScenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/CustomCurrency.cpp b/src/openrct2-ui/windows/CustomCurrency.cpp index 9899710761..84f5008d3d 100644 --- a/src/openrct2-ui/windows/CustomCurrency.cpp +++ b/src/openrct2-ui/windows/CustomCurrency.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/DebugPaint.cpp b/src/openrct2-ui/windows/DebugPaint.cpp index 182febca51..21e1a8aa60 100644 --- a/src/openrct2-ui/windows/DebugPaint.cpp +++ b/src/openrct2-ui/windows/DebugPaint.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/DemolishRidePrompt.cpp b/src/openrct2-ui/windows/DemolishRidePrompt.cpp index e0e48fc76d..930a72252f 100644 --- a/src/openrct2-ui/windows/DemolishRidePrompt.cpp +++ b/src/openrct2-ui/windows/DemolishRidePrompt.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Dropdown.cpp b/src/openrct2-ui/windows/Dropdown.cpp index a6f48a3ec3..2de05a1501 100644 --- a/src/openrct2-ui/windows/Dropdown.cpp +++ b/src/openrct2-ui/windows/Dropdown.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index 89bea6e32d..6d33965ef0 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 5ee9337483..43fd558152 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorMain.cpp b/src/openrct2-ui/windows/EditorMain.cpp index ee97ea15ce..fbeaac9c0c 100644 --- a/src/openrct2-ui/windows/EditorMain.cpp +++ b/src/openrct2-ui/windows/EditorMain.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index a00d519cdf..6d4a524195 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index c83f6af756..1a3874d308 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index dfdcf13897..df9942005b 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Error.cpp b/src/openrct2-ui/windows/Error.cpp index 432c91cb5b..1fc785bc4d 100644 --- a/src/openrct2-ui/windows/Error.cpp +++ b/src/openrct2-ui/windows/Error.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 4f0cc9306e..a5f7fb1323 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index ed010060a3..e6c92f9b86 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index c50653b43c..c334f9721a 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 8eaa297c2f..a1d0139936 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index 997091c225..7cc6422a24 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 7abd2ad2b9..cb80258cb6 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index 887f7f4cb1..83bf68207b 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index 253457130c..c7ae24657e 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index f0fabc2b90..e090441d79 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Main.cpp b/src/openrct2-ui/windows/Main.cpp index 9464562608..78f29e9da4 100644 --- a/src/openrct2-ui/windows/Main.cpp +++ b/src/openrct2-ui/windows/Main.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 0b4b29c4e5..105dceff32 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 39ee2ffa29..05727b331d 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/MapTooltip.cpp b/src/openrct2-ui/windows/MapTooltip.cpp index 0963afc765..83b9032c2e 100644 --- a/src/openrct2-ui/windows/MapTooltip.cpp +++ b/src/openrct2-ui/windows/MapTooltip.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/MazeConstruction.cpp b/src/openrct2-ui/windows/MazeConstruction.cpp index 9f60d6146f..39510dc001 100644 --- a/src/openrct2-ui/windows/MazeConstruction.cpp +++ b/src/openrct2-ui/windows/MazeConstruction.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Multiplayer.cpp b/src/openrct2-ui/windows/Multiplayer.cpp index c9cbfc04c5..a9db4551f3 100644 --- a/src/openrct2-ui/windows/Multiplayer.cpp +++ b/src/openrct2-ui/windows/Multiplayer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/MusicCredits.cpp b/src/openrct2-ui/windows/MusicCredits.cpp index a24e7a58cb..0b4907f75e 100644 --- a/src/openrct2-ui/windows/MusicCredits.cpp +++ b/src/openrct2-ui/windows/MusicCredits.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/NetworkStatus.cpp b/src/openrct2-ui/windows/NetworkStatus.cpp index c78a2ecfb9..22d55383f5 100644 --- a/src/openrct2-ui/windows/NetworkStatus.cpp +++ b/src/openrct2-ui/windows/NetworkStatus.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index 9c2ca6339f..856a6e0776 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 35ea8c477f..f820aa3fea 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index e642ec077e..b0f863dfd4 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/NewsOptions.cpp b/src/openrct2-ui/windows/NewsOptions.cpp index ec47cbd4a7..dfd7fcf95b 100644 --- a/src/openrct2-ui/windows/NewsOptions.cpp +++ b/src/openrct2-ui/windows/NewsOptions.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index e45f8d35ce..d870dfa642 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index ebd224fc6d..c654a2004f 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index 7c6b99e3e9..8425d8bee3 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Research.cpp b/src/openrct2-ui/windows/Research.cpp index b64e2c5f6c..ce8fad6617 100644 --- a/src/openrct2-ui/windows/Research.cpp +++ b/src/openrct2-ui/windows/Research.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 01d596c6b6..3bc0fbb034 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 388c903d83..0e7ffa05d1 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index f66b137540..79f834af15 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/SavePrompt.cpp b/src/openrct2-ui/windows/SavePrompt.cpp index 92fa50696e..ba95404a92 100644 --- a/src/openrct2-ui/windows/SavePrompt.cpp +++ b/src/openrct2-ui/windows/SavePrompt.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index d20843848e..595e053c40 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 18256723c6..4561afc690 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index 207ab3f05e..5fc1d49cd0 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ShortcutKeyChange.cpp b/src/openrct2-ui/windows/ShortcutKeyChange.cpp index 2a1a6f6bf9..9989b1c0b7 100644 --- a/src/openrct2-ui/windows/ShortcutKeyChange.cpp +++ b/src/openrct2-ui/windows/ShortcutKeyChange.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ShortcutKeys.cpp b/src/openrct2-ui/windows/ShortcutKeys.cpp index a0db7fb12c..d3f53f6c51 100644 --- a/src/openrct2-ui/windows/ShortcutKeys.cpp +++ b/src/openrct2-ui/windows/ShortcutKeys.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index 5c02229952..938e0e5ef2 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index c31fc30c34..4b5a6f8dad 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/StaffFirePrompt.cpp b/src/openrct2-ui/windows/StaffFirePrompt.cpp index 31acc4e44d..965ed606d3 100644 --- a/src/openrct2-ui/windows/StaffFirePrompt.cpp +++ b/src/openrct2-ui/windows/StaffFirePrompt.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index 34379e3f24..9de7e33540 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TextInput.cpp b/src/openrct2-ui/windows/TextInput.cpp index 6ac78dcec5..70148edac3 100644 --- a/src/openrct2-ui/windows/TextInput.cpp +++ b/src/openrct2-ui/windows/TextInput.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Themes.cpp b/src/openrct2-ui/windows/Themes.cpp index 85f41a37ea..c0f2713422 100644 --- a/src/openrct2-ui/windows/Themes.cpp +++ b/src/openrct2-ui/windows/Themes.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 7bee7f47db..10af49f1ca 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index 4acf7ec8d3..ccde014f22 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleEditor.cpp b/src/openrct2-ui/windows/TitleEditor.cpp index 022d605fae..f6855bda54 100644 --- a/src/openrct2-ui/windows/TitleEditor.cpp +++ b/src/openrct2-ui/windows/TitleEditor.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleExit.cpp b/src/openrct2-ui/windows/TitleExit.cpp index a8da964a7f..f3b7225c48 100644 --- a/src/openrct2-ui/windows/TitleExit.cpp +++ b/src/openrct2-ui/windows/TitleExit.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleLogo.cpp b/src/openrct2-ui/windows/TitleLogo.cpp index d9cf99afa1..392fccfd69 100644 --- a/src/openrct2-ui/windows/TitleLogo.cpp +++ b/src/openrct2-ui/windows/TitleLogo.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleMenu.cpp b/src/openrct2-ui/windows/TitleMenu.cpp index 54ed089a81..b204728c0a 100644 --- a/src/openrct2-ui/windows/TitleMenu.cpp +++ b/src/openrct2-ui/windows/TitleMenu.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleOptions.cpp b/src/openrct2-ui/windows/TitleOptions.cpp index dc4ec747fa..e744097a1d 100644 --- a/src/openrct2-ui/windows/TitleOptions.cpp +++ b/src/openrct2-ui/windows/TitleOptions.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TitleScenarioSelect.cpp b/src/openrct2-ui/windows/TitleScenarioSelect.cpp index 6be6a7113d..496e30fb56 100644 --- a/src/openrct2-ui/windows/TitleScenarioSelect.cpp +++ b/src/openrct2-ui/windows/TitleScenarioSelect.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Tooltip.cpp b/src/openrct2-ui/windows/Tooltip.cpp index 876ee10024..fa5c25e7d5 100644 --- a/src/openrct2-ui/windows/Tooltip.cpp +++ b/src/openrct2-ui/windows/Tooltip.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index d1681b5efb..e26b4507ba 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TrackDesignManage.cpp b/src/openrct2-ui/windows/TrackDesignManage.cpp index b74e679e0d..b2d7f0d7bf 100644 --- a/src/openrct2-ui/windows/TrackDesignManage.cpp +++ b/src/openrct2-ui/windows/TrackDesignManage.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 34aad6ab1c..3b6c6d9dfd 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index b81e0111da..0f574a7aee 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/ViewClipping.cpp b/src/openrct2-ui/windows/ViewClipping.cpp index 0a461e1c74..ab720aa3ab 100644 --- a/src/openrct2-ui/windows/ViewClipping.cpp +++ b/src/openrct2-ui/windows/ViewClipping.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Viewport.cpp b/src/openrct2-ui/windows/Viewport.cpp index dd6d7c96dc..bc61db577d 100644 --- a/src/openrct2-ui/windows/Viewport.cpp +++ b/src/openrct2-ui/windows/Viewport.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Water.cpp b/src/openrct2-ui/windows/Water.cpp index aaaf504ddd..afe55d8305 100644 --- a/src/openrct2-ui/windows/Water.cpp +++ b/src/openrct2-ui/windows/Water.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 85bfb918a5..8c8d770e81 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2-win/openrct2-win.cpp b/src/openrct2-win/openrct2-win.cpp index 73ed66dda9..1d7f2da57d 100644 --- a/src/openrct2-win/openrct2-win.cpp +++ b/src/openrct2-win/openrct2-win.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index a46c25fca9..fd096225cc 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index bcc8a18880..9adb950882 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/CmdlineSprite.cpp b/src/openrct2/CmdlineSprite.cpp index 89671fadd0..d3b4bf375b 100644 --- a/src/openrct2/CmdlineSprite.cpp +++ b/src/openrct2/CmdlineSprite.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/CmdlineSprite.h b/src/openrct2/CmdlineSprite.h index 3d3a4a22b8..a5b2f0e9a3 100644 --- a/src/openrct2/CmdlineSprite.h +++ b/src/openrct2/CmdlineSprite.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index c27269f374..5a6b48ec72 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index ba940adc04..902bf87293 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Date.cpp b/src/openrct2/Date.cpp index 698d99d17e..ff1e1eff60 100644 --- a/src/openrct2/Date.cpp +++ b/src/openrct2/Date.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Date.h b/src/openrct2/Date.h index db6bb90493..6811c5d56b 100644 --- a/src/openrct2/Date.h +++ b/src/openrct2/Date.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Diagnostic.cpp b/src/openrct2/Diagnostic.cpp index 47744e5176..7e595c4f1b 100644 --- a/src/openrct2/Diagnostic.cpp +++ b/src/openrct2/Diagnostic.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Diagnostic.h b/src/openrct2/Diagnostic.h index ef1bbc013e..908cae8621 100644 --- a/src/openrct2/Diagnostic.h +++ b/src/openrct2/Diagnostic.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index f28f53713c..02c54eb959 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Editor.h b/src/openrct2/Editor.h index d3acde5d4f..8810f12ab1 100644 --- a/src/openrct2/Editor.h +++ b/src/openrct2/Editor.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 3968f03bda..4bc2921f7f 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/EditorObjectSelectionSession.h b/src/openrct2/EditorObjectSelectionSession.h index 454d2e0ab4..0b6f94fb11 100644 --- a/src/openrct2/EditorObjectSelectionSession.h +++ b/src/openrct2/EditorObjectSelectionSession.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/FileClassifier.cpp b/src/openrct2/FileClassifier.cpp index c2ea8b7fca..42b956eb66 100644 --- a/src/openrct2/FileClassifier.cpp +++ b/src/openrct2/FileClassifier.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/FileClassifier.h b/src/openrct2/FileClassifier.h index 207e57d7a9..0fbc118180 100644 --- a/src/openrct2/FileClassifier.h +++ b/src/openrct2/FileClassifier.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 791f428806..333bb07afa 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index e0b759675a..7a495fb1ab 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index cb6de02a1e..ef8c596324 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index 479ef0d6b5..b613163c64 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Input.cpp b/src/openrct2/Input.cpp index ebcdd6216b..16102939c4 100644 --- a/src/openrct2/Input.cpp +++ b/src/openrct2/Input.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Input.h b/src/openrct2/Input.h index 15d49d3708..de73ff7800 100644 --- a/src/openrct2/Input.h +++ b/src/openrct2/Input.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Intro.cpp b/src/openrct2/Intro.cpp index 3feaf93ccb..f245d4d342 100644 --- a/src/openrct2/Intro.cpp +++ b/src/openrct2/Intro.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Intro.h b/src/openrct2/Intro.h index dba1ba9bde..95f00d662a 100644 --- a/src/openrct2/Intro.h +++ b/src/openrct2/Intro.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/OpenRCT2.cpp b/src/openrct2/OpenRCT2.cpp index 175cb0e4d2..30dd4abcae 100644 --- a/src/openrct2/OpenRCT2.cpp +++ b/src/openrct2/OpenRCT2.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/OpenRCT2.h b/src/openrct2/OpenRCT2.h index 1185307bf6..ac57ac4e17 100644 --- a/src/openrct2/OpenRCT2.h +++ b/src/openrct2/OpenRCT2.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ParkImporter.cpp b/src/openrct2/ParkImporter.cpp index fdc2d14e8a..f891d3d80f 100644 --- a/src/openrct2/ParkImporter.cpp +++ b/src/openrct2/ParkImporter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ParkImporter.h b/src/openrct2/ParkImporter.h index e2ae34fdee..c65c977e69 100644 --- a/src/openrct2/ParkImporter.h +++ b/src/openrct2/ParkImporter.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/PlatformEnvironment.cpp b/src/openrct2/PlatformEnvironment.cpp index f595fd4a18..45314a1c05 100644 --- a/src/openrct2/PlatformEnvironment.cpp +++ b/src/openrct2/PlatformEnvironment.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/PlatformEnvironment.h b/src/openrct2/PlatformEnvironment.h index 30747c9e32..d912e29285 100644 --- a/src/openrct2/PlatformEnvironment.h +++ b/src/openrct2/PlatformEnvironment.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index 0b9c2312ed..456948824f 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ReplayManager.h b/src/openrct2/ReplayManager.h index 976ae4dcb9..04ca15ba85 100644 --- a/src/openrct2/ReplayManager.h +++ b/src/openrct2/ReplayManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Version.cpp b/src/openrct2/Version.cpp index 1c2ccd9ded..27321357db 100644 --- a/src/openrct2/Version.cpp +++ b/src/openrct2/Version.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/Version.h b/src/openrct2/Version.h index 29da424899..5a1a3212e9 100644 --- a/src/openrct2/Version.h +++ b/src/openrct2/Version.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/BannerSetNameAction.hpp b/src/openrct2/actions/BannerSetNameAction.hpp index f8638adbda..f58ad620bc 100644 --- a/src/openrct2/actions/BannerSetNameAction.hpp +++ b/src/openrct2/actions/BannerSetNameAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/ClimateSetAction.hpp b/src/openrct2/actions/ClimateSetAction.hpp index 1613c95bd0..870f20fab4 100644 --- a/src/openrct2/actions/ClimateSetAction.hpp +++ b/src/openrct2/actions/ClimateSetAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/FootpathRemoveAction.hpp b/src/openrct2/actions/FootpathRemoveAction.hpp index 94dfef978c..8869ed492b 100644 --- a/src/openrct2/actions/FootpathRemoveAction.hpp +++ b/src/openrct2/actions/FootpathRemoveAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index c07bfe2a82..38b797778c 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index f98f78b98f..2210d3fdff 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index fd235d54f7..b30569dd0e 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index cf6fd67727..065612940d 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/GuestSetNameAction.hpp b/src/openrct2/actions/GuestSetNameAction.hpp index 09dcbbbdec..31cd19b604 100644 --- a/src/openrct2/actions/GuestSetNameAction.hpp +++ b/src/openrct2/actions/GuestSetNameAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/LandSetHeightAction.hpp b/src/openrct2/actions/LandSetHeightAction.hpp index 0e505602e8..535cde1322 100644 --- a/src/openrct2/actions/LandSetHeightAction.hpp +++ b/src/openrct2/actions/LandSetHeightAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/LargeSceneryRemoveAction.hpp b/src/openrct2/actions/LargeSceneryRemoveAction.hpp index 4de461e788..7d2f567c01 100644 --- a/src/openrct2/actions/LargeSceneryRemoveAction.hpp +++ b/src/openrct2/actions/LargeSceneryRemoveAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/MazeSetTrackAction.hpp b/src/openrct2/actions/MazeSetTrackAction.hpp index 4df00ae4f1..431dfb3017 100644 --- a/src/openrct2/actions/MazeSetTrackAction.hpp +++ b/src/openrct2/actions/MazeSetTrackAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/ParkMarketingAction.hpp b/src/openrct2/actions/ParkMarketingAction.hpp index 8b8179671c..8de0b7e87f 100644 --- a/src/openrct2/actions/ParkMarketingAction.hpp +++ b/src/openrct2/actions/ParkMarketingAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/ParkSetLoanAction.hpp b/src/openrct2/actions/ParkSetLoanAction.hpp index d92587db82..c5dca530e6 100644 --- a/src/openrct2/actions/ParkSetLoanAction.hpp +++ b/src/openrct2/actions/ParkSetLoanAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/ParkSetNameAction.hpp b/src/openrct2/actions/ParkSetNameAction.hpp index acf2d50728..1896e00c26 100644 --- a/src/openrct2/actions/ParkSetNameAction.hpp +++ b/src/openrct2/actions/ParkSetNameAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/ParkSetResearchFundingAction.hpp b/src/openrct2/actions/ParkSetResearchFundingAction.hpp index 641f564967..cde01cbce4 100644 --- a/src/openrct2/actions/ParkSetResearchFundingAction.hpp +++ b/src/openrct2/actions/ParkSetResearchFundingAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/PauseToggleAction.hpp b/src/openrct2/actions/PauseToggleAction.hpp index a6a460f6e0..52d6bcd689 100644 --- a/src/openrct2/actions/PauseToggleAction.hpp +++ b/src/openrct2/actions/PauseToggleAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/PlaceParkEntranceAction.hpp b/src/openrct2/actions/PlaceParkEntranceAction.hpp index ade56a24c0..007217fcc7 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.hpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/PlacePeepSpawnAction.hpp b/src/openrct2/actions/PlacePeepSpawnAction.hpp index 60c5269bde..4d3472eda4 100644 --- a/src/openrct2/actions/PlacePeepSpawnAction.hpp +++ b/src/openrct2/actions/PlacePeepSpawnAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index ccab3c90af..93e35cd2cc 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 3d1a461b18..59f391454c 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideSetAppearanceAction.hpp b/src/openrct2/actions/RideSetAppearanceAction.hpp index 4f58296046..0701910143 100644 --- a/src/openrct2/actions/RideSetAppearanceAction.hpp +++ b/src/openrct2/actions/RideSetAppearanceAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideSetColourScheme.hpp b/src/openrct2/actions/RideSetColourScheme.hpp index a91a0255d1..f68d531a74 100644 --- a/src/openrct2/actions/RideSetColourScheme.hpp +++ b/src/openrct2/actions/RideSetColourScheme.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideSetName.hpp b/src/openrct2/actions/RideSetName.hpp index d94f533d0f..076c32ce21 100644 --- a/src/openrct2/actions/RideSetName.hpp +++ b/src/openrct2/actions/RideSetName.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index 09cd1246f1..5dff42ab41 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/SetParkEntranceFeeAction.hpp b/src/openrct2/actions/SetParkEntranceFeeAction.hpp index 58e1d8cc9f..734bfa099a 100644 --- a/src/openrct2/actions/SetParkEntranceFeeAction.hpp +++ b/src/openrct2/actions/SetParkEntranceFeeAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/SignSetNameAction.hpp b/src/openrct2/actions/SignSetNameAction.hpp index 15a3e3c820..6e0ee08df0 100644 --- a/src/openrct2/actions/SignSetNameAction.hpp +++ b/src/openrct2/actions/SignSetNameAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/SmallSceneryRemoveAction.hpp b/src/openrct2/actions/SmallSceneryRemoveAction.hpp index 499099afb5..c4cd06c141 100644 --- a/src/openrct2/actions/SmallSceneryRemoveAction.hpp +++ b/src/openrct2/actions/SmallSceneryRemoveAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/StaffSetColourAction.hpp b/src/openrct2/actions/StaffSetColourAction.hpp index 1e30cb18fb..dd5f6aacb6 100644 --- a/src/openrct2/actions/StaffSetColourAction.hpp +++ b/src/openrct2/actions/StaffSetColourAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/StaffSetCostumeAction.hpp b/src/openrct2/actions/StaffSetCostumeAction.hpp index 17355bb762..f6ebb14110 100644 --- a/src/openrct2/actions/StaffSetCostumeAction.hpp +++ b/src/openrct2/actions/StaffSetCostumeAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/StaffSetNameAction.hpp b/src/openrct2/actions/StaffSetNameAction.hpp index d06538e992..5a912e1d2a 100644 --- a/src/openrct2/actions/StaffSetNameAction.hpp +++ b/src/openrct2/actions/StaffSetNameAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/StaffSetOrdersAction.hpp b/src/openrct2/actions/StaffSetOrdersAction.hpp index 06eab21379..e9ce50fbfd 100644 --- a/src/openrct2/actions/StaffSetOrdersAction.hpp +++ b/src/openrct2/actions/StaffSetOrdersAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index 74dab23c72..745aea9d98 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/TrackRemoveAction.hpp b/src/openrct2/actions/TrackRemoveAction.hpp index fb73e5c763..d78d81cf6c 100644 --- a/src/openrct2/actions/TrackRemoveAction.hpp +++ b/src/openrct2/actions/TrackRemoveAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/actions/WallRemoveAction.hpp b/src/openrct2/actions/WallRemoveAction.hpp index ea385c75dd..b11059b920 100644 --- a/src/openrct2/actions/WallRemoveAction.hpp +++ b/src/openrct2/actions/WallRemoveAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index a52ab8e2b3..d96e24b70d 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/AudioChannel.h b/src/openrct2/audio/AudioChannel.h index c3eca7df73..a0823c7386 100644 --- a/src/openrct2/audio/AudioChannel.h +++ b/src/openrct2/audio/AudioChannel.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/AudioContext.h b/src/openrct2/audio/AudioContext.h index 254d898fef..9093270c53 100644 --- a/src/openrct2/audio/AudioContext.h +++ b/src/openrct2/audio/AudioContext.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/AudioMixer.cpp b/src/openrct2/audio/AudioMixer.cpp index 5a4df89319..28b3ab21a5 100644 --- a/src/openrct2/audio/AudioMixer.cpp +++ b/src/openrct2/audio/AudioMixer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/AudioMixer.h b/src/openrct2/audio/AudioMixer.h index e5b88bc514..5e20af6ad4 100644 --- a/src/openrct2/audio/AudioMixer.h +++ b/src/openrct2/audio/AudioMixer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/AudioSource.h b/src/openrct2/audio/AudioSource.h index 7b5bedc962..60869206fe 100644 --- a/src/openrct2/audio/AudioSource.h +++ b/src/openrct2/audio/AudioSource.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/DummyAudioContext.cpp b/src/openrct2/audio/DummyAudioContext.cpp index 9730a294b4..71fedfa927 100644 --- a/src/openrct2/audio/DummyAudioContext.cpp +++ b/src/openrct2/audio/DummyAudioContext.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/NullAudioSource.cpp b/src/openrct2/audio/NullAudioSource.cpp index 33d15922d2..52a6d33731 100644 --- a/src/openrct2/audio/NullAudioSource.cpp +++ b/src/openrct2/audio/NullAudioSource.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/audio/audio.h b/src/openrct2/audio/audio.h index b855813b55..85e2b079cf 100644 --- a/src/openrct2/audio/audio.h +++ b/src/openrct2/audio/audio.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/BenchGfxCommmands.cpp b/src/openrct2/cmdline/BenchGfxCommmands.cpp index 806d0eaaf4..343a715c21 100644 --- a/src/openrct2/cmdline/BenchGfxCommmands.cpp +++ b/src/openrct2/cmdline/BenchGfxCommmands.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/CommandLine.cpp b/src/openrct2/cmdline/CommandLine.cpp index d15ddc2af3..adc87af25c 100644 --- a/src/openrct2/cmdline/CommandLine.cpp +++ b/src/openrct2/cmdline/CommandLine.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/CommandLine.hpp b/src/openrct2/cmdline/CommandLine.hpp index bba00a04cd..67be8c3c59 100644 --- a/src/openrct2/cmdline/CommandLine.hpp +++ b/src/openrct2/cmdline/CommandLine.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/ConvertCommand.cpp b/src/openrct2/cmdline/ConvertCommand.cpp index e5cf63812d..6355485713 100644 --- a/src/openrct2/cmdline/ConvertCommand.cpp +++ b/src/openrct2/cmdline/ConvertCommand.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/RootCommands.cpp b/src/openrct2/cmdline/RootCommands.cpp index 1c17170222..b39f1fda55 100644 --- a/src/openrct2/cmdline/RootCommands.cpp +++ b/src/openrct2/cmdline/RootCommands.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/ScreenshotCommands.cpp b/src/openrct2/cmdline/ScreenshotCommands.cpp index 54a9bf439a..a0ca954873 100644 --- a/src/openrct2/cmdline/ScreenshotCommands.cpp +++ b/src/openrct2/cmdline/ScreenshotCommands.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/SimulateCommands.cpp b/src/openrct2/cmdline/SimulateCommands.cpp index 55eacedd3f..76cd61de50 100644 --- a/src/openrct2/cmdline/SimulateCommands.cpp +++ b/src/openrct2/cmdline/SimulateCommands.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/SpriteCommands.cpp b/src/openrct2/cmdline/SpriteCommands.cpp index 311c0aa619..900894ffdc 100644 --- a/src/openrct2/cmdline/SpriteCommands.cpp +++ b/src/openrct2/cmdline/SpriteCommands.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/cmdline/UriHandler.cpp b/src/openrct2/cmdline/UriHandler.cpp index ae98c358fa..669e313bf3 100644 --- a/src/openrct2/cmdline/UriHandler.cpp +++ b/src/openrct2/cmdline/UriHandler.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/common.h b/src/openrct2/common.h index 54379a710c..68cd3f8c99 100644 --- a/src/openrct2/common.h +++ b/src/openrct2/common.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index dfc7776cbf..15e31378f8 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 3aaeb442d7..e885512bf2 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/ConfigEnum.hpp b/src/openrct2/config/ConfigEnum.hpp index 48305a2aaf..a3dfaba108 100644 --- a/src/openrct2/config/ConfigEnum.hpp +++ b/src/openrct2/config/ConfigEnum.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/IniReader.cpp b/src/openrct2/config/IniReader.cpp index 2b187e4e9c..3bc24b89c8 100644 --- a/src/openrct2/config/IniReader.cpp +++ b/src/openrct2/config/IniReader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/IniReader.hpp b/src/openrct2/config/IniReader.hpp index 20b3a6ae24..b50ac57676 100644 --- a/src/openrct2/config/IniReader.hpp +++ b/src/openrct2/config/IniReader.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/IniWriter.cpp b/src/openrct2/config/IniWriter.cpp index 7f01e6429a..e12eb420dc 100644 --- a/src/openrct2/config/IniWriter.cpp +++ b/src/openrct2/config/IniWriter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/config/IniWriter.hpp b/src/openrct2/config/IniWriter.hpp index c00a8308fd..a854d4255a 100644 --- a/src/openrct2/config/IniWriter.hpp +++ b/src/openrct2/config/IniWriter.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Collections.hpp b/src/openrct2/core/Collections.hpp index 54ef228c8b..9b3b139d64 100644 --- a/src/openrct2/core/Collections.hpp +++ b/src/openrct2/core/Collections.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Console.cpp b/src/openrct2/core/Console.cpp index b91ffc9937..f85320bfdd 100644 --- a/src/openrct2/core/Console.cpp +++ b/src/openrct2/core/Console.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Console.hpp b/src/openrct2/core/Console.hpp index 097f9ac75b..69956f8cc5 100644 --- a/src/openrct2/core/Console.hpp +++ b/src/openrct2/core/Console.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Crypt.OpenSSL.cpp b/src/openrct2/core/Crypt.OpenSSL.cpp index 9046019cd7..ff950f9c1a 100644 --- a/src/openrct2/core/Crypt.OpenSSL.cpp +++ b/src/openrct2/core/Crypt.OpenSSL.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Crypt.h b/src/openrct2/core/Crypt.h index 2cf3a44389..f3c32cf00a 100644 --- a/src/openrct2/core/Crypt.h +++ b/src/openrct2/core/Crypt.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/DataSerialiser.h b/src/openrct2/core/DataSerialiser.h index 65a0372a7f..367567d6f9 100644 --- a/src/openrct2/core/DataSerialiser.h +++ b/src/openrct2/core/DataSerialiser.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/DataSerialiserTag.h b/src/openrct2/core/DataSerialiserTag.h index d430796ef2..69b326f170 100644 --- a/src/openrct2/core/DataSerialiserTag.h +++ b/src/openrct2/core/DataSerialiserTag.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index d2edf0dd46..dde2c7b75c 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Diagnostics.cpp b/src/openrct2/core/Diagnostics.cpp index 98e2f48f1e..f841cfa3c4 100644 --- a/src/openrct2/core/Diagnostics.cpp +++ b/src/openrct2/core/Diagnostics.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Diagnostics.hpp b/src/openrct2/core/Diagnostics.hpp index 7a456db216..2981bb602b 100644 --- a/src/openrct2/core/Diagnostics.hpp +++ b/src/openrct2/core/Diagnostics.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Endianness.h b/src/openrct2/core/Endianness.h index b992e8752f..16d024cfbc 100644 --- a/src/openrct2/core/Endianness.h +++ b/src/openrct2/core/Endianness.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/File.cpp b/src/openrct2/core/File.cpp index 97e5f01db4..bae6d23440 100644 --- a/src/openrct2/core/File.cpp +++ b/src/openrct2/core/File.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/File.h b/src/openrct2/core/File.h index cbb68b83fe..3b8cd321bc 100644 --- a/src/openrct2/core/File.h +++ b/src/openrct2/core/File.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/FileIndex.hpp b/src/openrct2/core/FileIndex.hpp index 0b9ce01b92..da3e27d4df 100644 --- a/src/openrct2/core/FileIndex.hpp +++ b/src/openrct2/core/FileIndex.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/FileScanner.cpp b/src/openrct2/core/FileScanner.cpp index 68b5abc23b..718d97cc49 100644 --- a/src/openrct2/core/FileScanner.cpp +++ b/src/openrct2/core/FileScanner.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/FileScanner.h b/src/openrct2/core/FileScanner.h index 1e7b23ddf9..f87aee31a5 100644 --- a/src/openrct2/core/FileScanner.h +++ b/src/openrct2/core/FileScanner.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/FileStream.hpp b/src/openrct2/core/FileStream.hpp index 907c5c851f..ae33e05d7c 100644 --- a/src/openrct2/core/FileStream.hpp +++ b/src/openrct2/core/FileStream.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Guard.cpp b/src/openrct2/core/Guard.cpp index b8950c50f1..8419e782f0 100644 --- a/src/openrct2/core/Guard.cpp +++ b/src/openrct2/core/Guard.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Guard.hpp b/src/openrct2/core/Guard.hpp index 83edf426d1..5556232fd5 100644 --- a/src/openrct2/core/Guard.hpp +++ b/src/openrct2/core/Guard.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/IStream.cpp b/src/openrct2/core/IStream.cpp index 60a4af6d94..4a2ad084d4 100644 --- a/src/openrct2/core/IStream.cpp +++ b/src/openrct2/core/IStream.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/IStream.hpp b/src/openrct2/core/IStream.hpp index 3ff0ea1e86..c578aaf7b9 100644 --- a/src/openrct2/core/IStream.hpp +++ b/src/openrct2/core/IStream.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Imaging.cpp b/src/openrct2/core/Imaging.cpp index e48537977d..3772b7d02e 100644 --- a/src/openrct2/core/Imaging.cpp +++ b/src/openrct2/core/Imaging.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Imaging.h b/src/openrct2/core/Imaging.h index 3619281de9..74d58e5b31 100644 --- a/src/openrct2/core/Imaging.h +++ b/src/openrct2/core/Imaging.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/JobPool.hpp b/src/openrct2/core/JobPool.hpp index 5b8b39ed25..8dd6ec10af 100644 --- a/src/openrct2/core/JobPool.hpp +++ b/src/openrct2/core/JobPool.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Json.cpp b/src/openrct2/core/Json.cpp index 786f8990d1..94b129133a 100644 --- a/src/openrct2/core/Json.cpp +++ b/src/openrct2/core/Json.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Json.hpp b/src/openrct2/core/Json.hpp index d8be8d5fbb..c3d97fc408 100644 --- a/src/openrct2/core/Json.hpp +++ b/src/openrct2/core/Json.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Memory.hpp b/src/openrct2/core/Memory.hpp index 5c75f2042a..c2096c876b 100644 --- a/src/openrct2/core/Memory.hpp +++ b/src/openrct2/core/Memory.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/MemoryStream.cpp b/src/openrct2/core/MemoryStream.cpp index c309f7b757..b58f5b87f6 100644 --- a/src/openrct2/core/MemoryStream.cpp +++ b/src/openrct2/core/MemoryStream.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/MemoryStream.h b/src/openrct2/core/MemoryStream.h index 57dfc0988e..aca6badb0f 100644 --- a/src/openrct2/core/MemoryStream.h +++ b/src/openrct2/core/MemoryStream.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Nullable.hpp b/src/openrct2/core/Nullable.hpp index 2f94ec1fe8..ecc6b7f651 100644 --- a/src/openrct2/core/Nullable.hpp +++ b/src/openrct2/core/Nullable.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Path.cpp b/src/openrct2/core/Path.cpp index 18a6990c73..35064173d0 100644 --- a/src/openrct2/core/Path.cpp +++ b/src/openrct2/core/Path.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Path.hpp b/src/openrct2/core/Path.hpp index fcc5addd33..924b2698cb 100644 --- a/src/openrct2/core/Path.hpp +++ b/src/openrct2/core/Path.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Registration.hpp b/src/openrct2/core/Registration.hpp index 4602023bdb..d281aa9c69 100644 --- a/src/openrct2/core/Registration.hpp +++ b/src/openrct2/core/Registration.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index 735a312c3d..6406728e98 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index 73ce7788f1..8314655ffc 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/StringBuilder.hpp b/src/openrct2/core/StringBuilder.hpp index 38d6925b61..8b436ba568 100644 --- a/src/openrct2/core/StringBuilder.hpp +++ b/src/openrct2/core/StringBuilder.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/StringReader.hpp b/src/openrct2/core/StringReader.hpp index 1189996632..4c43316fd6 100644 --- a/src/openrct2/core/StringReader.hpp +++ b/src/openrct2/core/StringReader.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Zip.cpp b/src/openrct2/core/Zip.cpp index 5cb0995d8d..65430095e1 100644 --- a/src/openrct2/core/Zip.cpp +++ b/src/openrct2/core/Zip.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/Zip.h b/src/openrct2/core/Zip.h index f2c762a104..62176c97d4 100644 --- a/src/openrct2/core/Zip.h +++ b/src/openrct2/core/Zip.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/core/ZipAndroid.cpp b/src/openrct2/core/ZipAndroid.cpp index 07975a29a8..714a918bf2 100644 --- a/src/openrct2/core/ZipAndroid.cpp +++ b/src/openrct2/core/ZipAndroid.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/AVX2Drawing.cpp b/src/openrct2/drawing/AVX2Drawing.cpp index cbbae06b9d..709af9fa46 100644 --- a/src/openrct2/drawing/AVX2Drawing.cpp +++ b/src/openrct2/drawing/AVX2Drawing.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 7d9f06b050..8c93edcfed 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index bd998576a0..f744c0975a 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 4d529a633f..30f9dda4a0 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 20b43b188b..d56404fd90 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/DrawingFast.cpp b/src/openrct2/drawing/DrawingFast.cpp index 26133cbccd..3b2d977f85 100644 --- a/src/openrct2/drawing/DrawingFast.cpp +++ b/src/openrct2/drawing/DrawingFast.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Font.cpp b/src/openrct2/drawing/Font.cpp index c172e3018b..ed0f492d1b 100644 --- a/src/openrct2/drawing/Font.cpp +++ b/src/openrct2/drawing/Font.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Font.h b/src/openrct2/drawing/Font.h index 7604ba9068..33bf36d227 100644 --- a/src/openrct2/drawing/Font.h +++ b/src/openrct2/drawing/Font.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/IDrawingContext.h b/src/openrct2/drawing/IDrawingContext.h index eb4521c0a4..07ace81e0a 100644 --- a/src/openrct2/drawing/IDrawingContext.h +++ b/src/openrct2/drawing/IDrawingContext.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/IDrawingEngine.h b/src/openrct2/drawing/IDrawingEngine.h index 3f04551c36..4e4376d97e 100644 --- a/src/openrct2/drawing/IDrawingEngine.h +++ b/src/openrct2/drawing/IDrawingEngine.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Image.cpp b/src/openrct2/drawing/Image.cpp index 44c0cdda09..2c05826a80 100644 --- a/src/openrct2/drawing/Image.cpp +++ b/src/openrct2/drawing/Image.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/ImageImporter.cpp b/src/openrct2/drawing/ImageImporter.cpp index 9bd0f8a1c1..e58377736b 100644 --- a/src/openrct2/drawing/ImageImporter.cpp +++ b/src/openrct2/drawing/ImageImporter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/ImageImporter.h b/src/openrct2/drawing/ImageImporter.h index b89afe5cee..8355799a58 100644 --- a/src/openrct2/drawing/ImageImporter.h +++ b/src/openrct2/drawing/ImageImporter.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index 4312f62f4f..8dc6bc4b61 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/LightFX.h b/src/openrct2/drawing/LightFX.h index 4e58e0b1f7..fcdb4a3645 100644 --- a/src/openrct2/drawing/LightFX.h +++ b/src/openrct2/drawing/LightFX.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Line.cpp b/src/openrct2/drawing/Line.cpp index 43e3d17f2b..31f2ec7ab0 100644 --- a/src/openrct2/drawing/Line.cpp +++ b/src/openrct2/drawing/Line.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index dca79cba34..b96d8c4e6e 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/NewDrawing.h b/src/openrct2/drawing/NewDrawing.h index fd5df91045..dfa1e23491 100644 --- a/src/openrct2/drawing/NewDrawing.h +++ b/src/openrct2/drawing/NewDrawing.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Rain.cpp b/src/openrct2/drawing/Rain.cpp index 693d490b6e..57af305803 100644 --- a/src/openrct2/drawing/Rain.cpp +++ b/src/openrct2/drawing/Rain.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Rain.h b/src/openrct2/drawing/Rain.h index 7c49446384..591e4c59e6 100644 --- a/src/openrct2/drawing/Rain.h +++ b/src/openrct2/drawing/Rain.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Rect.cpp b/src/openrct2/drawing/Rect.cpp index ff0466c5c4..97f52596ab 100644 --- a/src/openrct2/drawing/Rect.cpp +++ b/src/openrct2/drawing/Rect.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/SSE41Drawing.cpp b/src/openrct2/drawing/SSE41Drawing.cpp index e781419b16..45cbe97caf 100644 --- a/src/openrct2/drawing/SSE41Drawing.cpp +++ b/src/openrct2/drawing/SSE41Drawing.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index d4d0126f6c..e31abdc74b 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index 104e61f55c..2489d90d15 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/TTF.h b/src/openrct2/drawing/TTF.h index d77164687e..e7df27e0de 100644 --- a/src/openrct2/drawing/TTF.h +++ b/src/openrct2/drawing/TTF.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Text.cpp b/src/openrct2/drawing/Text.cpp index dfc1e8b1fa..07ba4a506b 100644 --- a/src/openrct2/drawing/Text.cpp +++ b/src/openrct2/drawing/Text.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/Text.h b/src/openrct2/drawing/Text.h index f459878480..e12bf63d9a 100644 --- a/src/openrct2/drawing/Text.h +++ b/src/openrct2/drawing/Text.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index cf00ded57b..310dfb6280 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index 8ab558b9d3..41228594b5 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Chat.cpp b/src/openrct2/interface/Chat.cpp index 1c4b2a9ce1..5ff82edb79 100644 --- a/src/openrct2/interface/Chat.cpp +++ b/src/openrct2/interface/Chat.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Chat.h b/src/openrct2/interface/Chat.h index 4262f60a60..2653f9a1d5 100644 --- a/src/openrct2/interface/Chat.h +++ b/src/openrct2/interface/Chat.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Colour.cpp b/src/openrct2/interface/Colour.cpp index 28f0a346e6..baa62266a4 100644 --- a/src/openrct2/interface/Colour.cpp +++ b/src/openrct2/interface/Colour.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Colour.h b/src/openrct2/interface/Colour.h index 14df38630c..c8e587ba85 100644 --- a/src/openrct2/interface/Colour.h +++ b/src/openrct2/interface/Colour.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Cursors.h b/src/openrct2/interface/Cursors.h index e3b25b465b..fdb527e05c 100644 --- a/src/openrct2/interface/Cursors.h +++ b/src/openrct2/interface/Cursors.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/FontFamilies.cpp b/src/openrct2/interface/FontFamilies.cpp index d7fe3b1d54..4c16ee350b 100644 --- a/src/openrct2/interface/FontFamilies.cpp +++ b/src/openrct2/interface/FontFamilies.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/FontFamilies.h b/src/openrct2/interface/FontFamilies.h index e7f45d6085..5508aca08d 100644 --- a/src/openrct2/interface/FontFamilies.h +++ b/src/openrct2/interface/FontFamilies.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Fonts.cpp b/src/openrct2/interface/Fonts.cpp index 49b4d2a20a..08a56d1d20 100644 --- a/src/openrct2/interface/Fonts.cpp +++ b/src/openrct2/interface/Fonts.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Fonts.h b/src/openrct2/interface/Fonts.h index afe7aac0d2..af8ec51d50 100644 --- a/src/openrct2/interface/Fonts.h +++ b/src/openrct2/interface/Fonts.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 0c12365fc9..579500f49f 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/InteractiveConsole.h b/src/openrct2/interface/InteractiveConsole.h index e689c8b3f3..ec1a3181d4 100644 --- a/src/openrct2/interface/InteractiveConsole.h +++ b/src/openrct2/interface/InteractiveConsole.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 2831949b9f..2323c1b2d0 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Screenshot.h b/src/openrct2/interface/Screenshot.h index ee3923c8b2..8e0b3c60ab 100644 --- a/src/openrct2/interface/Screenshot.h +++ b/src/openrct2/interface/Screenshot.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/StdInOutConsole.cpp b/src/openrct2/interface/StdInOutConsole.cpp index b76d0dc3e5..df6c2359f3 100644 --- a/src/openrct2/interface/StdInOutConsole.cpp +++ b/src/openrct2/interface/StdInOutConsole.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 1ad01f0276..855f98a3d0 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index a348556d8e..8c0ebac2e4 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Widget.h b/src/openrct2/interface/Widget.h index bd3140e685..e4b04956a7 100644 --- a/src/openrct2/interface/Widget.h +++ b/src/openrct2/interface/Widget.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index f594809355..35a8676e30 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 98d0600802..8ab1c5973b 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index f030c0a9ac..6aa64f1e2b 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/ConversionTables.cpp b/src/openrct2/localisation/ConversionTables.cpp index ccfdde1298..066c737df6 100644 --- a/src/openrct2/localisation/ConversionTables.cpp +++ b/src/openrct2/localisation/ConversionTables.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/ConversionTables.h b/src/openrct2/localisation/ConversionTables.h index 4707f1c2e0..c99f8764f6 100644 --- a/src/openrct2/localisation/ConversionTables.h +++ b/src/openrct2/localisation/ConversionTables.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Convert.cpp b/src/openrct2/localisation/Convert.cpp index c3362ec69a..032b23ee3d 100644 --- a/src/openrct2/localisation/Convert.cpp +++ b/src/openrct2/localisation/Convert.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Currency.cpp b/src/openrct2/localisation/Currency.cpp index 99417ce160..71de644fff 100644 --- a/src/openrct2/localisation/Currency.cpp +++ b/src/openrct2/localisation/Currency.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Currency.h b/src/openrct2/localisation/Currency.h index 63de732462..4a12692be0 100644 --- a/src/openrct2/localisation/Currency.h +++ b/src/openrct2/localisation/Currency.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Date.h b/src/openrct2/localisation/Date.h index 6417794aa2..4930c413bd 100644 --- a/src/openrct2/localisation/Date.h +++ b/src/openrct2/localisation/Date.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/FormatCodes.cpp b/src/openrct2/localisation/FormatCodes.cpp index dff3f97d8d..e15c1d2409 100644 --- a/src/openrct2/localisation/FormatCodes.cpp +++ b/src/openrct2/localisation/FormatCodes.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/FormatCodes.h b/src/openrct2/localisation/FormatCodes.h index d87da883d3..c4a4f39434 100644 --- a/src/openrct2/localisation/FormatCodes.h +++ b/src/openrct2/localisation/FormatCodes.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Language.cpp b/src/openrct2/localisation/Language.cpp index c895ff88ba..bdf2eb3604 100644 --- a/src/openrct2/localisation/Language.cpp +++ b/src/openrct2/localisation/Language.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Language.h b/src/openrct2/localisation/Language.h index 5791a14229..17d0340456 100644 --- a/src/openrct2/localisation/Language.h +++ b/src/openrct2/localisation/Language.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/LanguagePack.cpp b/src/openrct2/localisation/LanguagePack.cpp index 79a1da0556..9d0953ba77 100644 --- a/src/openrct2/localisation/LanguagePack.cpp +++ b/src/openrct2/localisation/LanguagePack.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/LanguagePack.h b/src/openrct2/localisation/LanguagePack.h index 9a9e73439e..b65a933eb9 100644 --- a/src/openrct2/localisation/LanguagePack.h +++ b/src/openrct2/localisation/LanguagePack.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Localisation.Date.cpp b/src/openrct2/localisation/Localisation.Date.cpp index 8d4b8fbec5..7df295312d 100644 --- a/src/openrct2/localisation/Localisation.Date.cpp +++ b/src/openrct2/localisation/Localisation.Date.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index 12b96d9579..99ae0930be 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/Localisation.h b/src/openrct2/localisation/Localisation.h index 1a92f4095c..6039265b77 100644 --- a/src/openrct2/localisation/Localisation.h +++ b/src/openrct2/localisation/Localisation.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/LocalisationService.cpp b/src/openrct2/localisation/LocalisationService.cpp index b1fbc46f8e..97588214fc 100644 --- a/src/openrct2/localisation/LocalisationService.cpp +++ b/src/openrct2/localisation/LocalisationService.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/LocalisationService.h b/src/openrct2/localisation/LocalisationService.h index 54c7714f8f..01cc53e5a1 100644 --- a/src/openrct2/localisation/LocalisationService.h +++ b/src/openrct2/localisation/LocalisationService.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/RealNames.cpp b/src/openrct2/localisation/RealNames.cpp index 50a6693752..d3aeffec97 100644 --- a/src/openrct2/localisation/RealNames.cpp +++ b/src/openrct2/localisation/RealNames.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index c07c48951b..7f45e809ca 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/UTF8.cpp b/src/openrct2/localisation/UTF8.cpp index b1ea1760e6..6318b58b9c 100644 --- a/src/openrct2/localisation/UTF8.cpp +++ b/src/openrct2/localisation/UTF8.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/User.cpp b/src/openrct2/localisation/User.cpp index 8a23d266ce..fa91b549d8 100644 --- a/src/openrct2/localisation/User.cpp +++ b/src/openrct2/localisation/User.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/localisation/User.h b/src/openrct2/localisation/User.h index c6c4d9bbd3..d20633ed0f 100644 --- a/src/openrct2/localisation/User.h +++ b/src/openrct2/localisation/User.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index 550ca8cea7..e6a3b07ea2 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Award.h b/src/openrct2/management/Award.h index a9ca3725a0..33b901b81c 100644 --- a/src/openrct2/management/Award.h +++ b/src/openrct2/management/Award.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index b801c63bf7..e03141cce1 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Finance.h b/src/openrct2/management/Finance.h index 2a7191b3d7..7277a591e3 100644 --- a/src/openrct2/management/Finance.h +++ b/src/openrct2/management/Finance.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 733b924834..91505a3cc5 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Marketing.h b/src/openrct2/management/Marketing.h index dd082abfb7..6d4df0ebde 100644 --- a/src/openrct2/management/Marketing.h +++ b/src/openrct2/management/Marketing.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 82c4acaed6..9343c7bafd 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 7b24335af8..22be1657cf 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index bf7c5c878e..581beed56e 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 815e40d3ae..339d8115be 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/DiscordService.cpp b/src/openrct2/network/DiscordService.cpp index 1e4fa5b615..7c3e1901c2 100644 --- a/src/openrct2/network/DiscordService.cpp +++ b/src/openrct2/network/DiscordService.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/DiscordService.h b/src/openrct2/network/DiscordService.h index d98b3cace2..0de94ea68d 100644 --- a/src/openrct2/network/DiscordService.h +++ b/src/openrct2/network/DiscordService.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/Http.cpp b/src/openrct2/network/Http.cpp index 6e4b74057d..6d8d140752 100644 --- a/src/openrct2/network/Http.cpp +++ b/src/openrct2/network/Http.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/Http.h b/src/openrct2/network/Http.h index 54204e0fb3..399650320e 100644 --- a/src/openrct2/network/Http.h +++ b/src/openrct2/network/Http.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 69b291eddd..0782868f05 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkAction.cpp b/src/openrct2/network/NetworkAction.cpp index af28b7e488..bb1d338994 100644 --- a/src/openrct2/network/NetworkAction.cpp +++ b/src/openrct2/network/NetworkAction.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkAction.h b/src/openrct2/network/NetworkAction.h index b3ba7277be..8c98110831 100644 --- a/src/openrct2/network/NetworkAction.h +++ b/src/openrct2/network/NetworkAction.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkConnection.cpp b/src/openrct2/network/NetworkConnection.cpp index 4236cd1c14..ff090665f9 100644 --- a/src/openrct2/network/NetworkConnection.cpp +++ b/src/openrct2/network/NetworkConnection.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkConnection.h b/src/openrct2/network/NetworkConnection.h index 473c0c3c67..def4a85304 100644 --- a/src/openrct2/network/NetworkConnection.h +++ b/src/openrct2/network/NetworkConnection.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkGroup.cpp b/src/openrct2/network/NetworkGroup.cpp index c03bc4e203..318e6f2482 100644 --- a/src/openrct2/network/NetworkGroup.cpp +++ b/src/openrct2/network/NetworkGroup.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkGroup.h b/src/openrct2/network/NetworkGroup.h index f8e677ca67..07d7d5c878 100644 --- a/src/openrct2/network/NetworkGroup.h +++ b/src/openrct2/network/NetworkGroup.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkKey.cpp b/src/openrct2/network/NetworkKey.cpp index 22dc2c4af7..3312dc5284 100644 --- a/src/openrct2/network/NetworkKey.cpp +++ b/src/openrct2/network/NetworkKey.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkKey.h b/src/openrct2/network/NetworkKey.h index 382f83cc01..5811d5a845 100644 --- a/src/openrct2/network/NetworkKey.h +++ b/src/openrct2/network/NetworkKey.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkPacket.cpp b/src/openrct2/network/NetworkPacket.cpp index 90a3de78a6..f613a699fa 100644 --- a/src/openrct2/network/NetworkPacket.cpp +++ b/src/openrct2/network/NetworkPacket.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkPacket.h b/src/openrct2/network/NetworkPacket.h index 59aacdbf1f..6b9352c899 100644 --- a/src/openrct2/network/NetworkPacket.h +++ b/src/openrct2/network/NetworkPacket.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkPlayer.cpp b/src/openrct2/network/NetworkPlayer.cpp index c9ca397715..ccaee8f41c 100644 --- a/src/openrct2/network/NetworkPlayer.cpp +++ b/src/openrct2/network/NetworkPlayer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkPlayer.h b/src/openrct2/network/NetworkPlayer.h index 355198fdea..cf762ad76e 100644 --- a/src/openrct2/network/NetworkPlayer.h +++ b/src/openrct2/network/NetworkPlayer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 97fba2a075..84ee0c2934 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkServerAdvertiser.h b/src/openrct2/network/NetworkServerAdvertiser.h index 3ebfdc2dfd..0ab239acc2 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.h +++ b/src/openrct2/network/NetworkServerAdvertiser.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index e48a3b6059..bdd96c5434 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkUser.cpp b/src/openrct2/network/NetworkUser.cpp index ffd21e5097..5540abf698 100644 --- a/src/openrct2/network/NetworkUser.cpp +++ b/src/openrct2/network/NetworkUser.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/NetworkUser.h b/src/openrct2/network/NetworkUser.h index f3e048f2ce..78a99289d0 100644 --- a/src/openrct2/network/NetworkUser.h +++ b/src/openrct2/network/NetworkUser.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 0148492a37..d565ab0d68 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index 8207d8d1a5..22afcfbe69 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/TcpSocket.cpp b/src/openrct2/network/TcpSocket.cpp index 2da8ad3673..51bdc33ff8 100644 --- a/src/openrct2/network/TcpSocket.cpp +++ b/src/openrct2/network/TcpSocket.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/TcpSocket.h b/src/openrct2/network/TcpSocket.h index 00ae4b19d6..1e6186f20a 100644 --- a/src/openrct2/network/TcpSocket.h +++ b/src/openrct2/network/TcpSocket.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/Twitch.cpp b/src/openrct2/network/Twitch.cpp index b3c5644737..7718d2df75 100644 --- a/src/openrct2/network/Twitch.cpp +++ b/src/openrct2/network/Twitch.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index b1f6a75a3e..693bcd44dc 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/network/twitch.h b/src/openrct2/network/twitch.h index 293293bb4f..2c39a99429 100644 --- a/src/openrct2/network/twitch.h +++ b/src/openrct2/network/twitch.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/BannerObject.cpp b/src/openrct2/object/BannerObject.cpp index 9693afc893..dd9e06afe1 100644 --- a/src/openrct2/object/BannerObject.cpp +++ b/src/openrct2/object/BannerObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/BannerObject.h b/src/openrct2/object/BannerObject.h index 1792b0f747..8d59187d86 100644 --- a/src/openrct2/object/BannerObject.h +++ b/src/openrct2/object/BannerObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/DefaultObjects.cpp b/src/openrct2/object/DefaultObjects.cpp index 5f796d0dc9..e74a803490 100644 --- a/src/openrct2/object/DefaultObjects.cpp +++ b/src/openrct2/object/DefaultObjects.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/DefaultObjects.h b/src/openrct2/object/DefaultObjects.h index 7cb82271bb..65a2fbc5db 100644 --- a/src/openrct2/object/DefaultObjects.h +++ b/src/openrct2/object/DefaultObjects.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/EntranceObject.cpp b/src/openrct2/object/EntranceObject.cpp index cc6d021247..11bbfb5fd4 100644 --- a/src/openrct2/object/EntranceObject.cpp +++ b/src/openrct2/object/EntranceObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/EntranceObject.h b/src/openrct2/object/EntranceObject.h index 78611dc92e..7580ba3ed1 100644 --- a/src/openrct2/object/EntranceObject.h +++ b/src/openrct2/object/EntranceObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/FootpathItemObject.cpp b/src/openrct2/object/FootpathItemObject.cpp index 96809bf306..0463b4bb62 100644 --- a/src/openrct2/object/FootpathItemObject.cpp +++ b/src/openrct2/object/FootpathItemObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/FootpathItemObject.h b/src/openrct2/object/FootpathItemObject.h index a27d65e4ec..47c5f161fe 100644 --- a/src/openrct2/object/FootpathItemObject.h +++ b/src/openrct2/object/FootpathItemObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/FootpathObject.cpp b/src/openrct2/object/FootpathObject.cpp index 15b0bb1699..d32843f9c0 100644 --- a/src/openrct2/object/FootpathObject.cpp +++ b/src/openrct2/object/FootpathObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/FootpathObject.h b/src/openrct2/object/FootpathObject.h index b0398809ef..b48cbd7d6f 100644 --- a/src/openrct2/object/FootpathObject.h +++ b/src/openrct2/object/FootpathObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ImageTable.cpp b/src/openrct2/object/ImageTable.cpp index 35c364f2a3..adc9fa62bc 100644 --- a/src/openrct2/object/ImageTable.cpp +++ b/src/openrct2/object/ImageTable.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ImageTable.h b/src/openrct2/object/ImageTable.h index 2bf37d5305..73065f51f0 100644 --- a/src/openrct2/object/ImageTable.h +++ b/src/openrct2/object/ImageTable.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/LargeSceneryObject.cpp b/src/openrct2/object/LargeSceneryObject.cpp index aeb9c18828..2eb12afba7 100644 --- a/src/openrct2/object/LargeSceneryObject.cpp +++ b/src/openrct2/object/LargeSceneryObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/LargeSceneryObject.h b/src/openrct2/object/LargeSceneryObject.h index 1f18c26573..3642878106 100644 --- a/src/openrct2/object/LargeSceneryObject.h +++ b/src/openrct2/object/LargeSceneryObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 3487129001..35526d4021 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index 39b2a44a19..68b8855c65 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index 196ec92f3e..68ea0b21f3 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectFactory.h b/src/openrct2/object/ObjectFactory.h index 22ea8bc2b4..8fb401cac2 100644 --- a/src/openrct2/object/ObjectFactory.h +++ b/src/openrct2/object/ObjectFactory.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectJsonHelpers.cpp b/src/openrct2/object/ObjectJsonHelpers.cpp index c7da2f99b1..d6c50ce969 100644 --- a/src/openrct2/object/ObjectJsonHelpers.cpp +++ b/src/openrct2/object/ObjectJsonHelpers.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectJsonHelpers.h b/src/openrct2/object/ObjectJsonHelpers.h index 849a6df2c9..6f97a4791b 100644 --- a/src/openrct2/object/ObjectJsonHelpers.h +++ b/src/openrct2/object/ObjectJsonHelpers.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectLimits.h b/src/openrct2/object/ObjectLimits.h index 26408d4c4d..41f54ecdc8 100644 --- a/src/openrct2/object/ObjectLimits.h +++ b/src/openrct2/object/ObjectLimits.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index 7a849ddb65..45089060ac 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectList.h b/src/openrct2/object/ObjectList.h index d214ae22fb..5f1f95be84 100644 --- a/src/openrct2/object/ObjectList.h +++ b/src/openrct2/object/ObjectList.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 6e328e51f0..74838cc118 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectManager.h b/src/openrct2/object/ObjectManager.h index 263841f9af..83cf25cb69 100644 --- a/src/openrct2/object/ObjectManager.h +++ b/src/openrct2/object/ObjectManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 0f4babf4bb..9d2e34b403 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index f73f2007bd..a439a8a8ec 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 034a4b9cca..8cae6b6efa 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/RideObject.h b/src/openrct2/object/RideObject.h index 3a20477f55..bb68f5d273 100644 --- a/src/openrct2/object/RideObject.h +++ b/src/openrct2/object/RideObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SceneryGroupObject.cpp b/src/openrct2/object/SceneryGroupObject.cpp index e487646882..21b50d3705 100644 --- a/src/openrct2/object/SceneryGroupObject.cpp +++ b/src/openrct2/object/SceneryGroupObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SceneryGroupObject.h b/src/openrct2/object/SceneryGroupObject.h index c2d5e836a6..738b0ed6b2 100644 --- a/src/openrct2/object/SceneryGroupObject.h +++ b/src/openrct2/object/SceneryGroupObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SceneryObject.cpp b/src/openrct2/object/SceneryObject.cpp index 1160b94fbc..d048ea13f0 100644 --- a/src/openrct2/object/SceneryObject.cpp +++ b/src/openrct2/object/SceneryObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SceneryObject.h b/src/openrct2/object/SceneryObject.h index dfc00b954a..ae69d137c3 100644 --- a/src/openrct2/object/SceneryObject.h +++ b/src/openrct2/object/SceneryObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SmallSceneryObject.cpp b/src/openrct2/object/SmallSceneryObject.cpp index 2fb6f5f3f3..7d6e12eb40 100644 --- a/src/openrct2/object/SmallSceneryObject.cpp +++ b/src/openrct2/object/SmallSceneryObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/SmallSceneryObject.h b/src/openrct2/object/SmallSceneryObject.h index 13902fcf37..f68613444e 100644 --- a/src/openrct2/object/SmallSceneryObject.h +++ b/src/openrct2/object/SmallSceneryObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/StationObject.cpp b/src/openrct2/object/StationObject.cpp index 918100d927..29a95cf1a1 100644 --- a/src/openrct2/object/StationObject.cpp +++ b/src/openrct2/object/StationObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/StationObject.h b/src/openrct2/object/StationObject.h index 85e4cd149a..74e9b5f087 100644 --- a/src/openrct2/object/StationObject.h +++ b/src/openrct2/object/StationObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/StringTable.cpp b/src/openrct2/object/StringTable.cpp index fa1fa84ff8..61f89ccc44 100644 --- a/src/openrct2/object/StringTable.cpp +++ b/src/openrct2/object/StringTable.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/StringTable.h b/src/openrct2/object/StringTable.h index cab99ebaa1..07e833185f 100644 --- a/src/openrct2/object/StringTable.h +++ b/src/openrct2/object/StringTable.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/TerrainEdgeObject.cpp b/src/openrct2/object/TerrainEdgeObject.cpp index 7182e9dec1..ea1e87dd46 100644 --- a/src/openrct2/object/TerrainEdgeObject.cpp +++ b/src/openrct2/object/TerrainEdgeObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/TerrainEdgeObject.h b/src/openrct2/object/TerrainEdgeObject.h index cdc6f729f1..01ef6c5237 100644 --- a/src/openrct2/object/TerrainEdgeObject.h +++ b/src/openrct2/object/TerrainEdgeObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/TerrainSurfaceObject.cpp b/src/openrct2/object/TerrainSurfaceObject.cpp index a5dec79c7e..6c6c618bfd 100644 --- a/src/openrct2/object/TerrainSurfaceObject.cpp +++ b/src/openrct2/object/TerrainSurfaceObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/TerrainSurfaceObject.h b/src/openrct2/object/TerrainSurfaceObject.h index 71f2fff106..37cd4e94b4 100644 --- a/src/openrct2/object/TerrainSurfaceObject.h +++ b/src/openrct2/object/TerrainSurfaceObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/WallObject.cpp b/src/openrct2/object/WallObject.cpp index 996495975f..aa984b5d2a 100644 --- a/src/openrct2/object/WallObject.cpp +++ b/src/openrct2/object/WallObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/WallObject.h b/src/openrct2/object/WallObject.h index 5181176806..9ec22ae9e0 100644 --- a/src/openrct2/object/WallObject.h +++ b/src/openrct2/object/WallObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/WaterObject.cpp b/src/openrct2/object/WaterObject.cpp index 83dc980242..4bb59cf701 100644 --- a/src/openrct2/object/WaterObject.cpp +++ b/src/openrct2/object/WaterObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/object/WaterObject.h b/src/openrct2/object/WaterObject.h index 587d0af0cc..1e604dcd76 100644 --- a/src/openrct2/object/WaterObject.h +++ b/src/openrct2/object/WaterObject.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 6e0f83aa8b..d66483f260 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index ca7ba8277a..85796488bf 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/PaintHelpers.cpp b/src/openrct2/paint/PaintHelpers.cpp index 43a0f35f50..aa9a83eff3 100644 --- a/src/openrct2/paint/PaintHelpers.cpp +++ b/src/openrct2/paint/PaintHelpers.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 0f047c14ec..888a84190f 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Painter.h b/src/openrct2/paint/Painter.h index eac7b6f139..4302713867 100644 --- a/src/openrct2/paint/Painter.h +++ b/src/openrct2/paint/Painter.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Supports.cpp b/src/openrct2/paint/Supports.cpp index b1938da17d..9818b68711 100644 --- a/src/openrct2/paint/Supports.cpp +++ b/src/openrct2/paint/Supports.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/Supports.h b/src/openrct2/paint/Supports.h index 6959b394e7..7f19ba795a 100644 --- a/src/openrct2/paint/Supports.h +++ b/src/openrct2/paint/Supports.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index 70973d86fb..ac4cb17e82 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/VirtualFloor.h b/src/openrct2/paint/VirtualFloor.h index 645bd7942d..126a96f92d 100644 --- a/src/openrct2/paint/VirtualFloor.h +++ b/src/openrct2/paint/VirtualFloor.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/sprite/Paint.Litter.cpp b/src/openrct2/paint/sprite/Paint.Litter.cpp index fb36a79c76..0c37d0840b 100644 --- a/src/openrct2/paint/sprite/Paint.Litter.cpp +++ b/src/openrct2/paint/sprite/Paint.Litter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/sprite/Paint.Misc.cpp b/src/openrct2/paint/sprite/Paint.Misc.cpp index 5d36cea41a..b4e668e11a 100644 --- a/src/openrct2/paint/sprite/Paint.Misc.cpp +++ b/src/openrct2/paint/sprite/Paint.Misc.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/sprite/Paint.Peep.cpp b/src/openrct2/paint/sprite/Paint.Peep.cpp index 78399c376f..ea7586fb40 100644 --- a/src/openrct2/paint/sprite/Paint.Peep.cpp +++ b/src/openrct2/paint/sprite/Paint.Peep.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/sprite/Paint.Sprite.cpp b/src/openrct2/paint/sprite/Paint.Sprite.cpp index 234b6c054e..6944c91d65 100644 --- a/src/openrct2/paint/sprite/Paint.Sprite.cpp +++ b/src/openrct2/paint/sprite/Paint.Sprite.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/sprite/Paint.Sprite.h b/src/openrct2/paint/sprite/Paint.Sprite.h index 9d28015414..3a3950e217 100644 --- a/src/openrct2/paint/sprite/Paint.Sprite.h +++ b/src/openrct2/paint/sprite/Paint.Sprite.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Banner.cpp b/src/openrct2/paint/tile_element/Paint.Banner.cpp index 263e5497ce..35378767e3 100644 --- a/src/openrct2/paint/tile_element/Paint.Banner.cpp +++ b/src/openrct2/paint/tile_element/Paint.Banner.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 4abac2a560..406db6e812 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp index 9915f09fdf..b5f9677c74 100644 --- a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 6bebe317a0..061d3d84dc 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp index 02f53d3ff4..c2728279b4 100644 --- a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 243afdcd9b..0ec039b1a3 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Surface.h b/src/openrct2/paint/tile_element/Paint.Surface.h index bb78caba65..4bf1a891f1 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.h +++ b/src/openrct2/paint/tile_element/Paint.Surface.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index a9b87f8cf5..ac3098f802 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.h b/src/openrct2/paint/tile_element/Paint.TileElement.h index ac6a3baf55..378189e7f7 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.h +++ b/src/openrct2/paint/tile_element/Paint.TileElement.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/paint/tile_element/Paint.Wall.cpp b/src/openrct2/paint/tile_element/Paint.Wall.cpp index aa63cfd1f0..652d8af0e7 100644 --- a/src/openrct2/paint/tile_element/Paint.Wall.cpp +++ b/src/openrct2/paint/tile_element/Paint.Wall.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 80b105092e..b0e2f32211 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index f667799221..90c96eb0fd 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 4c92b2a201..3bb84e0d80 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 1fb258cc98..1d6550a47f 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/PeepData.cpp b/src/openrct2/peep/PeepData.cpp index c2d0d5b8e8..1bf7b8dc57 100644 --- a/src/openrct2/peep/PeepData.cpp +++ b/src/openrct2/peep/PeepData.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 80203cf89c..5fc4ce8cc7 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 30ef68ef5f..68fe2e461c 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Android.cpp b/src/openrct2/platform/Android.cpp index f9d2c50eee..b88f782e48 100644 --- a/src/openrct2/platform/Android.cpp +++ b/src/openrct2/platform/Android.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Crash.cpp b/src/openrct2/platform/Crash.cpp index 1083587c7e..0ae6f68ee1 100644 --- a/src/openrct2/platform/Crash.cpp +++ b/src/openrct2/platform/Crash.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Crash.h b/src/openrct2/platform/Crash.h index 06a56b03c4..f8e6b0184c 100644 --- a/src/openrct2/platform/Crash.h +++ b/src/openrct2/platform/Crash.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Linux.cpp b/src/openrct2/platform/Linux.cpp index 91e25d09a8..eed86f4e68 100644 --- a/src/openrct2/platform/Linux.cpp +++ b/src/openrct2/platform/Linux.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform.Android.cpp b/src/openrct2/platform/Platform.Android.cpp index 797196131e..4fe6738839 100644 --- a/src/openrct2/platform/Platform.Android.cpp +++ b/src/openrct2/platform/Platform.Android.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform.Linux.cpp b/src/openrct2/platform/Platform.Linux.cpp index 27b95a5a4e..7421b647a5 100644 --- a/src/openrct2/platform/Platform.Linux.cpp +++ b/src/openrct2/platform/Platform.Linux.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index 48b6bc2ade..7b3ee5c491 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 1b51233b21..448e149d7e 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform.macOS.mm b/src/openrct2/platform/Platform.macOS.mm index d2b9b3535b..e523ab6199 100644 --- a/src/openrct2/platform/Platform.macOS.mm +++ b/src/openrct2/platform/Platform.macOS.mm @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Platform2.h b/src/openrct2/platform/Platform2.h index f61a17b38b..3793d20d1c 100644 --- a/src/openrct2/platform/Platform2.h +++ b/src/openrct2/platform/Platform2.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Posix.cpp b/src/openrct2/platform/Posix.cpp index 1724ae1abf..d769268afa 100644 --- a/src/openrct2/platform/Posix.cpp +++ b/src/openrct2/platform/Posix.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Shared.cpp b/src/openrct2/platform/Shared.cpp index 1955bdba5f..6cc2ec2688 100644 --- a/src/openrct2/platform/Shared.cpp +++ b/src/openrct2/platform/Shared.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 34f0eb62f7..57c1ca7f64 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/macos.mm b/src/openrct2/platform/macos.mm index 45fa6087b4..58a5813bd4 100644 --- a/src/openrct2/platform/macos.mm +++ b/src/openrct2/platform/macos.mm @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/platform/platform.h b/src/openrct2/platform/platform.h index 6726dcb734..7e2ec421fd 100644 --- a/src/openrct2/platform/platform.h +++ b/src/openrct2/platform/platform.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index f8d5ac6a04..587da297f9 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 27317c6021..920eeaea8f 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index 3132b86571..242630c663 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct1/Tables.h b/src/openrct2/rct1/Tables.h index f77df9c440..3fccd2bc11 100644 --- a/src/openrct2/rct1/Tables.h +++ b/src/openrct2/rct1/Tables.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index 03f0bde5b2..017a71f932 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index d8277f102f..0784f460d6 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunk.cpp b/src/openrct2/rct12/SawyerChunk.cpp index 84db1bb0dc..f516f562f9 100644 --- a/src/openrct2/rct12/SawyerChunk.cpp +++ b/src/openrct2/rct12/SawyerChunk.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunk.h b/src/openrct2/rct12/SawyerChunk.h index 64c7073e51..d54fcc93cc 100644 --- a/src/openrct2/rct12/SawyerChunk.h +++ b/src/openrct2/rct12/SawyerChunk.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunkReader.cpp b/src/openrct2/rct12/SawyerChunkReader.cpp index 8ef527b042..ca5d6e16d6 100644 --- a/src/openrct2/rct12/SawyerChunkReader.cpp +++ b/src/openrct2/rct12/SawyerChunkReader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunkReader.h b/src/openrct2/rct12/SawyerChunkReader.h index a1407cbae1..57ca099d5c 100644 --- a/src/openrct2/rct12/SawyerChunkReader.h +++ b/src/openrct2/rct12/SawyerChunkReader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunkWriter.cpp b/src/openrct2/rct12/SawyerChunkWriter.cpp index 4a298b5bd5..e6837acbb6 100644 --- a/src/openrct2/rct12/SawyerChunkWriter.cpp +++ b/src/openrct2/rct12/SawyerChunkWriter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerChunkWriter.h b/src/openrct2/rct12/SawyerChunkWriter.h index 9fbfc156b9..117b865754 100644 --- a/src/openrct2/rct12/SawyerChunkWriter.h +++ b/src/openrct2/rct12/SawyerChunkWriter.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerEncoding.cpp b/src/openrct2/rct12/SawyerEncoding.cpp index 55758dc54a..d9ac604cbc 100644 --- a/src/openrct2/rct12/SawyerEncoding.cpp +++ b/src/openrct2/rct12/SawyerEncoding.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct12/SawyerEncoding.h b/src/openrct2/rct12/SawyerEncoding.h index 1a0ba30541..aa46c5aee2 100644 --- a/src/openrct2/rct12/SawyerEncoding.h +++ b/src/openrct2/rct12/SawyerEncoding.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index f42fc51457..a499a5cc70 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 21849810c3..f5a35049b0 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct2/S6Exporter.h b/src/openrct2/rct2/S6Exporter.h index 5c167a2b3a..418065311c 100644 --- a/src/openrct2/rct2/S6Exporter.h +++ b/src/openrct2/rct2/S6Exporter.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 2bc500f693..e4dd17b498 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 3474ef89e2..d332669938 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/CableLift.h b/src/openrct2/ride/CableLift.h index 0f1315bac3..e72df21799 100644 --- a/src/openrct2/ride/CableLift.h +++ b/src/openrct2/ride/CableLift.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/MusicList.cpp b/src/openrct2/ride/MusicList.cpp index 83c0dcb53b..75f37d32c2 100644 --- a/src/openrct2/ride/MusicList.cpp +++ b/src/openrct2/ride/MusicList.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/MusicList.h b/src/openrct2/ride/MusicList.h index 01fd2e158e..4240b7680f 100644 --- a/src/openrct2/ride/MusicList.h +++ b/src/openrct2/ride/MusicList.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 05b42e445e..9cca7acd08 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 65e347e8c9..2836ee648d 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index 23aa033e92..839e8dcf1d 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index 80442b2ed0..fea28c63f2 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideGroupManager.cpp b/src/openrct2/ride/RideGroupManager.cpp index ffc89f32c6..f6ad697d83 100644 --- a/src/openrct2/ride/RideGroupManager.cpp +++ b/src/openrct2/ride/RideGroupManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideGroupManager.h b/src/openrct2/ride/RideGroupManager.h index d917788dfd..0d66fbe931 100644 --- a/src/openrct2/ride/RideGroupManager.h +++ b/src/openrct2/ride/RideGroupManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 8ed07476ad..f0257b33d6 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideRatings.h b/src/openrct2/ride/RideRatings.h index c46a69d721..3ec272f7e3 100644 --- a/src/openrct2/ride/RideRatings.h +++ b/src/openrct2/ride/RideRatings.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/RideTypes.h b/src/openrct2/ride/RideTypes.h index d52b7753b5..9a5b081ec4 100644 --- a/src/openrct2/ride/RideTypes.h +++ b/src/openrct2/ride/RideTypes.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/ShopItem.cpp b/src/openrct2/ride/ShopItem.cpp index b317066dca..583d438779 100644 --- a/src/openrct2/ride/ShopItem.cpp +++ b/src/openrct2/ride/ShopItem.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/ShopItem.h b/src/openrct2/ride/ShopItem.h index 159ce77526..c4a639a140 100644 --- a/src/openrct2/ride/ShopItem.h +++ b/src/openrct2/ride/ShopItem.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Station.cpp b/src/openrct2/ride/Station.cpp index 0953e28283..44c0f0a4fc 100644 --- a/src/openrct2/ride/Station.cpp +++ b/src/openrct2/ride/Station.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Station.h b/src/openrct2/ride/Station.h index e37f6db9af..9b9c754938 100644 --- a/src/openrct2/ride/Station.h +++ b/src/openrct2/ride/Station.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index 1c7b64f6ee..74ea224b81 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 8f194f6955..6dbf16b74a 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackData.cpp b/src/openrct2/ride/TrackData.cpp index c0ac0fa317..35b16613d3 100644 --- a/src/openrct2/ride/TrackData.cpp +++ b/src/openrct2/ride/TrackData.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackData.h b/src/openrct2/ride/TrackData.h index 7f0f243151..a8ea771e5c 100644 --- a/src/openrct2/ride/TrackData.h +++ b/src/openrct2/ride/TrackData.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDataOld.cpp b/src/openrct2/ride/TrackDataOld.cpp index dee1aa0396..6e5fbfc098 100644 --- a/src/openrct2/ride/TrackDataOld.cpp +++ b/src/openrct2/ride/TrackDataOld.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 54eff77a42..74b2ea2ae2 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index 15f7634177..b46fc86e1d 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 39573aceba..967cfe0f28 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDesignRepository.h b/src/openrct2/ride/TrackDesignRepository.h index 930ee25d77..51d4a841d8 100644 --- a/src/openrct2/ride/TrackDesignRepository.h +++ b/src/openrct2/ride/TrackDesignRepository.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackDesignSave.cpp b/src/openrct2/ride/TrackDesignSave.cpp index dc8edab2b3..2013554cb1 100644 --- a/src/openrct2/ride/TrackDesignSave.cpp +++ b/src/openrct2/ride/TrackDesignSave.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index 183190ce72..7e839aa8c0 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/TrackPaint.h b/src/openrct2/ride/TrackPaint.h index 5ae3d689dc..4bfba44f2a 100644 --- a/src/openrct2/ride/TrackPaint.h +++ b/src/openrct2/ride/TrackPaint.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 4ad8c3ef01..18637c61e9 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index f1b91d0f05..5c4d9f8456 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/VehicleData.cpp b/src/openrct2/ride/VehicleData.cpp index 9d4b5ad81d..1412370290 100644 --- a/src/openrct2/ride/VehicleData.cpp +++ b/src/openrct2/ride/VehicleData.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/VehicleData.h b/src/openrct2/ride/VehicleData.h index 3450a42537..9a4dd6f13c 100644 --- a/src/openrct2/ride/VehicleData.h +++ b/src/openrct2/ride/VehicleData.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index e18f6af50c..20016dd01f 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/VehiclePaint.h b/src/openrct2/ride/VehiclePaint.h index 7047f4094d..af014e846d 100644 --- a/src/openrct2/ride/VehiclePaint.h +++ b/src/openrct2/ride/VehiclePaint.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/AirPoweredVerticalCoaster.cpp b/src/openrct2/ride/coaster/AirPoweredVerticalCoaster.cpp index 71b4f781ca..0857ec3a3b 100644 --- a/src/openrct2/ride/coaster/AirPoweredVerticalCoaster.cpp +++ b/src/openrct2/ride/coaster/AirPoweredVerticalCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/BobsleighCoaster.cpp b/src/openrct2/ride/coaster/BobsleighCoaster.cpp index 1e1a1f612d..77daced4b8 100644 --- a/src/openrct2/ride/coaster/BobsleighCoaster.cpp +++ b/src/openrct2/ride/coaster/BobsleighCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/BolligerMabillardTrack.cpp b/src/openrct2/ride/coaster/BolligerMabillardTrack.cpp index f77723c405..cda0732c84 100644 --- a/src/openrct2/ride/coaster/BolligerMabillardTrack.cpp +++ b/src/openrct2/ride/coaster/BolligerMabillardTrack.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/BolligerMabillardTrack.h b/src/openrct2/ride/coaster/BolligerMabillardTrack.h index 15de4bbc93..2b7e54eb8a 100644 --- a/src/openrct2/ride/coaster/BolligerMabillardTrack.h +++ b/src/openrct2/ride/coaster/BolligerMabillardTrack.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/CompactInvertedCoaster.cpp b/src/openrct2/ride/coaster/CompactInvertedCoaster.cpp index 8d69939df0..48387220e3 100644 --- a/src/openrct2/ride/coaster/CompactInvertedCoaster.cpp +++ b/src/openrct2/ride/coaster/CompactInvertedCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/CorkscrewRollerCoaster.cpp b/src/openrct2/ride/coaster/CorkscrewRollerCoaster.cpp index 8474f25652..20e829c116 100644 --- a/src/openrct2/ride/coaster/CorkscrewRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/CorkscrewRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/FlyingRollerCoaster.cpp b/src/openrct2/ride/coaster/FlyingRollerCoaster.cpp index 060637a0c1..1df9e34be4 100644 --- a/src/openrct2/ride/coaster/FlyingRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/FlyingRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/GigaCoaster.cpp b/src/openrct2/ride/coaster/GigaCoaster.cpp index da9f7910e4..13c5017238 100644 --- a/src/openrct2/ride/coaster/GigaCoaster.cpp +++ b/src/openrct2/ride/coaster/GigaCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/HeartlineTwisterCoaster.cpp b/src/openrct2/ride/coaster/HeartlineTwisterCoaster.cpp index 81874a9532..8da23bbb45 100644 --- a/src/openrct2/ride/coaster/HeartlineTwisterCoaster.cpp +++ b/src/openrct2/ride/coaster/HeartlineTwisterCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/InvertedHairpinCoaster.cpp b/src/openrct2/ride/coaster/InvertedHairpinCoaster.cpp index 58eb37a15b..2809460bac 100644 --- a/src/openrct2/ride/coaster/InvertedHairpinCoaster.cpp +++ b/src/openrct2/ride/coaster/InvertedHairpinCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/InvertedImpulseCoaster.cpp b/src/openrct2/ride/coaster/InvertedImpulseCoaster.cpp index 89c824165f..084311d291 100644 --- a/src/openrct2/ride/coaster/InvertedImpulseCoaster.cpp +++ b/src/openrct2/ride/coaster/InvertedImpulseCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/InvertedRollerCoaster.cpp b/src/openrct2/ride/coaster/InvertedRollerCoaster.cpp index 0691971476..9920c198ee 100644 --- a/src/openrct2/ride/coaster/InvertedRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/InvertedRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/JuniorRollerCoaster.cpp b/src/openrct2/ride/coaster/JuniorRollerCoaster.cpp index 5ed48af14a..60948f7c19 100644 --- a/src/openrct2/ride/coaster/JuniorRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/JuniorRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/JuniorRollerCoaster.h b/src/openrct2/ride/coaster/JuniorRollerCoaster.h index fea7b0b74f..3b7862034a 100644 --- a/src/openrct2/ride/coaster/JuniorRollerCoaster.h +++ b/src/openrct2/ride/coaster/JuniorRollerCoaster.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/LayDownRollerCoaster.cpp b/src/openrct2/ride/coaster/LayDownRollerCoaster.cpp index 6dd2782cd6..4add9c771a 100644 --- a/src/openrct2/ride/coaster/LayDownRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/LayDownRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/LimLaunchedRollerCoaster.cpp b/src/openrct2/ride/coaster/LimLaunchedRollerCoaster.cpp index 58657d786d..2398971859 100644 --- a/src/openrct2/ride/coaster/LimLaunchedRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/LimLaunchedRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/LoopingRollerCoaster.cpp b/src/openrct2/ride/coaster/LoopingRollerCoaster.cpp index dcb9daa0c3..367d3b55ec 100644 --- a/src/openrct2/ride/coaster/LoopingRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/LoopingRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/MineRide.cpp b/src/openrct2/ride/coaster/MineRide.cpp index e9db81fc9a..1cd5eb79bb 100644 --- a/src/openrct2/ride/coaster/MineRide.cpp +++ b/src/openrct2/ride/coaster/MineRide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/MineTrainCoaster.cpp b/src/openrct2/ride/coaster/MineTrainCoaster.cpp index 096f52b0a4..663647dd99 100644 --- a/src/openrct2/ride/coaster/MineTrainCoaster.cpp +++ b/src/openrct2/ride/coaster/MineTrainCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/MiniRollerCoaster.cpp b/src/openrct2/ride/coaster/MiniRollerCoaster.cpp index e87ab28589..ffcb2229a7 100644 --- a/src/openrct2/ride/coaster/MiniRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/MiniRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/MiniSuspendedCoaster.cpp b/src/openrct2/ride/coaster/MiniSuspendedCoaster.cpp index f8e160374d..727c2e719d 100644 --- a/src/openrct2/ride/coaster/MiniSuspendedCoaster.cpp +++ b/src/openrct2/ride/coaster/MiniSuspendedCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp b/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp index ed19156cd7..50aec667dc 100644 --- a/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/ReverseFreefallCoaster.cpp b/src/openrct2/ride/coaster/ReverseFreefallCoaster.cpp index cec6c2b122..6323b42c7d 100644 --- a/src/openrct2/ride/coaster/ReverseFreefallCoaster.cpp +++ b/src/openrct2/ride/coaster/ReverseFreefallCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp b/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp index 54c66923ce..4c0af567c0 100644 --- a/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/SideFrictionRollerCoaster.cpp b/src/openrct2/ride/coaster/SideFrictionRollerCoaster.cpp index 3ed6ac7a35..2b8524524f 100644 --- a/src/openrct2/ride/coaster/SideFrictionRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/SideFrictionRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/StandUpRollerCoaster.cpp b/src/openrct2/ride/coaster/StandUpRollerCoaster.cpp index 8ea706a8d5..91be57b06f 100644 --- a/src/openrct2/ride/coaster/StandUpRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/StandUpRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/Steeplechase.cpp b/src/openrct2/ride/coaster/Steeplechase.cpp index 1ca90a00b9..598ff2a7df 100644 --- a/src/openrct2/ride/coaster/Steeplechase.cpp +++ b/src/openrct2/ride/coaster/Steeplechase.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/SuspendedSwingingCoaster.cpp b/src/openrct2/ride/coaster/SuspendedSwingingCoaster.cpp index 845ae71012..9b5bbf824c 100644 --- a/src/openrct2/ride/coaster/SuspendedSwingingCoaster.cpp +++ b/src/openrct2/ride/coaster/SuspendedSwingingCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/TwisterRollerCoaster.cpp b/src/openrct2/ride/coaster/TwisterRollerCoaster.cpp index 7810708812..2fc5809516 100644 --- a/src/openrct2/ride/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/TwisterRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/VerticalDropRollerCoaster.cpp b/src/openrct2/ride/coaster/VerticalDropRollerCoaster.cpp index 00feb366f7..b560c6c41e 100644 --- a/src/openrct2/ride/coaster/VerticalDropRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/VerticalDropRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/VirginiaReel.cpp b/src/openrct2/ride/coaster/VirginiaReel.cpp index b1eefd5025..68370e32de 100644 --- a/src/openrct2/ride/coaster/VirginiaReel.cpp +++ b/src/openrct2/ride/coaster/VirginiaReel.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/WildMouse.cpp b/src/openrct2/ride/coaster/WildMouse.cpp index d8dc7bc9d0..2bcb08122d 100644 --- a/src/openrct2/ride/coaster/WildMouse.cpp +++ b/src/openrct2/ride/coaster/WildMouse.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp b/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp index 0a18fac384..bb436de158 100644 --- a/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/coaster/WoodenWildMouse.cpp b/src/openrct2/ride/coaster/WoodenWildMouse.cpp index 63fe473d4d..506090199e 100644 --- a/src/openrct2/ride/coaster/WoodenWildMouse.cpp +++ b/src/openrct2/ride/coaster/WoodenWildMouse.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/CarRide.cpp b/src/openrct2/ride/gentle/CarRide.cpp index 59d34c9c5a..e0629f4ab6 100644 --- a/src/openrct2/ride/gentle/CarRide.cpp +++ b/src/openrct2/ride/gentle/CarRide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/CircusShow.cpp b/src/openrct2/ride/gentle/CircusShow.cpp index e20fbb5c56..88896968ce 100644 --- a/src/openrct2/ride/gentle/CircusShow.cpp +++ b/src/openrct2/ride/gentle/CircusShow.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/CrookedHouse.cpp b/src/openrct2/ride/gentle/CrookedHouse.cpp index 190d9ed233..c1b468a662 100644 --- a/src/openrct2/ride/gentle/CrookedHouse.cpp +++ b/src/openrct2/ride/gentle/CrookedHouse.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/Dodgems.cpp b/src/openrct2/ride/gentle/Dodgems.cpp index c5c2fcee97..924ed4454e 100644 --- a/src/openrct2/ride/gentle/Dodgems.cpp +++ b/src/openrct2/ride/gentle/Dodgems.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/FerrisWheel.cpp b/src/openrct2/ride/gentle/FerrisWheel.cpp index 1bd1c6537b..193fe84ccc 100644 --- a/src/openrct2/ride/gentle/FerrisWheel.cpp +++ b/src/openrct2/ride/gentle/FerrisWheel.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/FlyingSaucers.cpp b/src/openrct2/ride/gentle/FlyingSaucers.cpp index 57fbec08b9..df97d22ce6 100644 --- a/src/openrct2/ride/gentle/FlyingSaucers.cpp +++ b/src/openrct2/ride/gentle/FlyingSaucers.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/GhostTrain.cpp b/src/openrct2/ride/gentle/GhostTrain.cpp index b2e061d3dd..023b0c7c05 100644 --- a/src/openrct2/ride/gentle/GhostTrain.cpp +++ b/src/openrct2/ride/gentle/GhostTrain.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/HauntedHouse.cpp b/src/openrct2/ride/gentle/HauntedHouse.cpp index d8e0a89844..568021a629 100644 --- a/src/openrct2/ride/gentle/HauntedHouse.cpp +++ b/src/openrct2/ride/gentle/HauntedHouse.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/Maze.cpp b/src/openrct2/ride/gentle/Maze.cpp index 0d0d1eefef..c09f8eb248 100644 --- a/src/openrct2/ride/gentle/Maze.cpp +++ b/src/openrct2/ride/gentle/Maze.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/MerryGoRound.cpp b/src/openrct2/ride/gentle/MerryGoRound.cpp index c3fb64540b..3b4ff34d4d 100644 --- a/src/openrct2/ride/gentle/MerryGoRound.cpp +++ b/src/openrct2/ride/gentle/MerryGoRound.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/MiniGolf.cpp b/src/openrct2/ride/gentle/MiniGolf.cpp index a196bda25d..febe16ec0e 100644 --- a/src/openrct2/ride/gentle/MiniGolf.cpp +++ b/src/openrct2/ride/gentle/MiniGolf.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/MiniHelicopters.cpp b/src/openrct2/ride/gentle/MiniHelicopters.cpp index 159129df59..845fe6aaeb 100644 --- a/src/openrct2/ride/gentle/MiniHelicopters.cpp +++ b/src/openrct2/ride/gentle/MiniHelicopters.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/MonorailCycles.cpp b/src/openrct2/ride/gentle/MonorailCycles.cpp index ef759e5992..4011499472 100644 --- a/src/openrct2/ride/gentle/MonorailCycles.cpp +++ b/src/openrct2/ride/gentle/MonorailCycles.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/ObservationTower.cpp b/src/openrct2/ride/gentle/ObservationTower.cpp index 433b768c00..0a4bcab880 100644 --- a/src/openrct2/ride/gentle/ObservationTower.cpp +++ b/src/openrct2/ride/gentle/ObservationTower.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/SpaceRings.cpp b/src/openrct2/ride/gentle/SpaceRings.cpp index 0aeb20390f..1d582fdd81 100644 --- a/src/openrct2/ride/gentle/SpaceRings.cpp +++ b/src/openrct2/ride/gentle/SpaceRings.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/gentle/SpiralSlide.cpp b/src/openrct2/ride/gentle/SpiralSlide.cpp index 355c2f8857..693351001b 100644 --- a/src/openrct2/ride/gentle/SpiralSlide.cpp +++ b/src/openrct2/ride/gentle/SpiralSlide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/shops/Facility.cpp b/src/openrct2/ride/shops/Facility.cpp index 999a62145e..c4c0a76964 100644 --- a/src/openrct2/ride/shops/Facility.cpp +++ b/src/openrct2/ride/shops/Facility.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/shops/Shop.cpp b/src/openrct2/ride/shops/Shop.cpp index 4c64cf7222..fba47f155c 100644 --- a/src/openrct2/ride/shops/Shop.cpp +++ b/src/openrct2/ride/shops/Shop.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/3dCinema.cpp b/src/openrct2/ride/thrill/3dCinema.cpp index eea1874b22..d2cf817202 100644 --- a/src/openrct2/ride/thrill/3dCinema.cpp +++ b/src/openrct2/ride/thrill/3dCinema.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/Enterprise.cpp b/src/openrct2/ride/thrill/Enterprise.cpp index 00d18d5b8d..2ee2a68f88 100644 --- a/src/openrct2/ride/thrill/Enterprise.cpp +++ b/src/openrct2/ride/thrill/Enterprise.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/GoKarts.cpp b/src/openrct2/ride/thrill/GoKarts.cpp index 73b268c438..c5f1b4fa93 100644 --- a/src/openrct2/ride/thrill/GoKarts.cpp +++ b/src/openrct2/ride/thrill/GoKarts.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/LaunchedFreefall.cpp b/src/openrct2/ride/thrill/LaunchedFreefall.cpp index 5f126e87c3..d516982cbf 100644 --- a/src/openrct2/ride/thrill/LaunchedFreefall.cpp +++ b/src/openrct2/ride/thrill/LaunchedFreefall.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/MagicCarpet.cpp b/src/openrct2/ride/thrill/MagicCarpet.cpp index 0eb94a2a83..8d4673fa44 100644 --- a/src/openrct2/ride/thrill/MagicCarpet.cpp +++ b/src/openrct2/ride/thrill/MagicCarpet.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/MotionSimulator.cpp b/src/openrct2/ride/thrill/MotionSimulator.cpp index 004be7e8f2..b7db9bf9f9 100644 --- a/src/openrct2/ride/thrill/MotionSimulator.cpp +++ b/src/openrct2/ride/thrill/MotionSimulator.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/PirateShip.cpp b/src/openrct2/ride/thrill/PirateShip.cpp index ef08368231..b9c22faf2e 100644 --- a/src/openrct2/ride/thrill/PirateShip.cpp +++ b/src/openrct2/ride/thrill/PirateShip.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/RotoDrop.cpp b/src/openrct2/ride/thrill/RotoDrop.cpp index ccbb55b6c2..8caa763862 100644 --- a/src/openrct2/ride/thrill/RotoDrop.cpp +++ b/src/openrct2/ride/thrill/RotoDrop.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/SwingingInverterShip.cpp b/src/openrct2/ride/thrill/SwingingInverterShip.cpp index f5ed22c227..eb70df3f6d 100644 --- a/src/openrct2/ride/thrill/SwingingInverterShip.cpp +++ b/src/openrct2/ride/thrill/SwingingInverterShip.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/TopSpin.cpp b/src/openrct2/ride/thrill/TopSpin.cpp index 01b977eb34..3c65e3ff37 100644 --- a/src/openrct2/ride/thrill/TopSpin.cpp +++ b/src/openrct2/ride/thrill/TopSpin.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/thrill/Twist.cpp b/src/openrct2/ride/thrill/Twist.cpp index 29d991ffd3..53c2925586 100644 --- a/src/openrct2/ride/thrill/Twist.cpp +++ b/src/openrct2/ride/thrill/Twist.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/transport/Chairlift.cpp b/src/openrct2/ride/transport/Chairlift.cpp index 11752fa1e8..06eb4676bf 100644 --- a/src/openrct2/ride/transport/Chairlift.cpp +++ b/src/openrct2/ride/transport/Chairlift.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/transport/Lift.cpp b/src/openrct2/ride/transport/Lift.cpp index 48804a7aac..d3eacb4b94 100644 --- a/src/openrct2/ride/transport/Lift.cpp +++ b/src/openrct2/ride/transport/Lift.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/transport/MiniatureRailway.cpp b/src/openrct2/ride/transport/MiniatureRailway.cpp index 6ab4d03eb3..f0b3a8d829 100644 --- a/src/openrct2/ride/transport/MiniatureRailway.cpp +++ b/src/openrct2/ride/transport/MiniatureRailway.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/transport/Monorail.cpp b/src/openrct2/ride/transport/Monorail.cpp index 4320743c49..daebf45e53 100644 --- a/src/openrct2/ride/transport/Monorail.cpp +++ b/src/openrct2/ride/transport/Monorail.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/transport/SuspendedMonorail.cpp b/src/openrct2/ride/transport/SuspendedMonorail.cpp index 365fd42f49..8069bdd190 100644 --- a/src/openrct2/ride/transport/SuspendedMonorail.cpp +++ b/src/openrct2/ride/transport/SuspendedMonorail.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/BoatHire.cpp b/src/openrct2/ride/water/BoatHire.cpp index 393761b2bd..a96fcf2276 100644 --- a/src/openrct2/ride/water/BoatHire.cpp +++ b/src/openrct2/ride/water/BoatHire.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/DingySlide.cpp b/src/openrct2/ride/water/DingySlide.cpp index 886e3e9d1c..63a7978fe3 100644 --- a/src/openrct2/ride/water/DingySlide.cpp +++ b/src/openrct2/ride/water/DingySlide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/LogFlume.cpp b/src/openrct2/ride/water/LogFlume.cpp index 1d5093f4ab..d45c381d67 100644 --- a/src/openrct2/ride/water/LogFlume.cpp +++ b/src/openrct2/ride/water/LogFlume.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/RiverRapids.cpp b/src/openrct2/ride/water/RiverRapids.cpp index faa6eae9d5..1e72267cb0 100644 --- a/src/openrct2/ride/water/RiverRapids.cpp +++ b/src/openrct2/ride/water/RiverRapids.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/SplashBoats.cpp b/src/openrct2/ride/water/SplashBoats.cpp index ddbf89e0e9..9a3ac2a625 100644 --- a/src/openrct2/ride/water/SplashBoats.cpp +++ b/src/openrct2/ride/water/SplashBoats.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/SubmarineRide.cpp b/src/openrct2/ride/water/SubmarineRide.cpp index 42220fcb35..22080563e7 100644 --- a/src/openrct2/ride/water/SubmarineRide.cpp +++ b/src/openrct2/ride/water/SubmarineRide.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ride/water/WaterCoaster.cpp b/src/openrct2/ride/water/WaterCoaster.cpp index 5d16762a33..535cc05642 100644 --- a/src/openrct2/ride/water/WaterCoaster.cpp +++ b/src/openrct2/ride/water/WaterCoaster.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 1e1be5e04f..ea10290d3d 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index 39c4667a10..f14ba66a59 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 24c2c6e028..41fe072fc5 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/ScenarioRepository.h b/src/openrct2/scenario/ScenarioRepository.h index 31146be112..c175e042d9 100644 --- a/src/openrct2/scenario/ScenarioRepository.h +++ b/src/openrct2/scenario/ScenarioRepository.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/ScenarioSources.cpp b/src/openrct2/scenario/ScenarioSources.cpp index 50de6c64e2..cbb512de93 100644 --- a/src/openrct2/scenario/ScenarioSources.cpp +++ b/src/openrct2/scenario/ScenarioSources.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/scenario/ScenarioSources.h b/src/openrct2/scenario/ScenarioSources.h index 31677333ab..4e5194511d 100644 --- a/src/openrct2/scenario/ScenarioSources.h +++ b/src/openrct2/scenario/ScenarioSources.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 5bad3cefca..392638a413 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleScreen.cpp b/src/openrct2/title/TitleScreen.cpp index 06a0ed6226..8643d5b48d 100644 --- a/src/openrct2/title/TitleScreen.cpp +++ b/src/openrct2/title/TitleScreen.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleScreen.h b/src/openrct2/title/TitleScreen.h index ef634a7afb..4ded4f646a 100644 --- a/src/openrct2/title/TitleScreen.h +++ b/src/openrct2/title/TitleScreen.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleSequence.cpp b/src/openrct2/title/TitleSequence.cpp index d771514179..c04cc3e4ea 100644 --- a/src/openrct2/title/TitleSequence.cpp +++ b/src/openrct2/title/TitleSequence.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleSequence.h b/src/openrct2/title/TitleSequence.h index d12a68a221..8bfbcd65b1 100644 --- a/src/openrct2/title/TitleSequence.h +++ b/src/openrct2/title/TitleSequence.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleSequenceManager.cpp b/src/openrct2/title/TitleSequenceManager.cpp index f2b4b5421e..1c6913d1c1 100644 --- a/src/openrct2/title/TitleSequenceManager.cpp +++ b/src/openrct2/title/TitleSequenceManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleSequenceManager.h b/src/openrct2/title/TitleSequenceManager.h index 3739c64840..dea64298ca 100644 --- a/src/openrct2/title/TitleSequenceManager.h +++ b/src/openrct2/title/TitleSequenceManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/title/TitleSequencePlayer.h b/src/openrct2/title/TitleSequencePlayer.h index 2af337b254..50889652d7 100644 --- a/src/openrct2/title/TitleSequencePlayer.h +++ b/src/openrct2/title/TitleSequencePlayer.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ui/DummyUiContext.cpp b/src/openrct2/ui/DummyUiContext.cpp index f8d42ce594..5d65b31af5 100644 --- a/src/openrct2/ui/DummyUiContext.cpp +++ b/src/openrct2/ui/DummyUiContext.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ui/DummyWindowManager.cpp b/src/openrct2/ui/DummyWindowManager.cpp index 42ae86ecdf..3550c864e8 100644 --- a/src/openrct2/ui/DummyWindowManager.cpp +++ b/src/openrct2/ui/DummyWindowManager.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index c7080d2add..2b1a336564 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/ui/WindowManager.h b/src/openrct2/ui/WindowManager.h index edb3865848..2556d9a8c5 100644 --- a/src/openrct2/ui/WindowManager.h +++ b/src/openrct2/ui/WindowManager.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/util/SawyerCoding.cpp b/src/openrct2/util/SawyerCoding.cpp index 5326d24eb4..5af5b86702 100644 --- a/src/openrct2/util/SawyerCoding.cpp +++ b/src/openrct2/util/SawyerCoding.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/util/SawyerCoding.h b/src/openrct2/util/SawyerCoding.h index 24c178928e..b29b1cdada 100644 --- a/src/openrct2/util/SawyerCoding.h +++ b/src/openrct2/util/SawyerCoding.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 027fd25bbb..350bfa149d 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index d8c45030e2..d07e13482c 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 37469b09a9..b472f740f3 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index a0429f4091..9b062e07d2 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index f051444ab0..1011c1d360 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/windows/tile_inspector.h b/src/openrct2/windows/tile_inspector.h index 3f2a4b62b4..2766549507 100644 --- a/src/openrct2/windows/tile_inspector.h +++ b/src/openrct2/windows/tile_inspector.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Balloon.cpp b/src/openrct2/world/Balloon.cpp index ee0b40520b..3e1b982150 100644 --- a/src/openrct2/world/Balloon.cpp +++ b/src/openrct2/world/Balloon.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index e97d51b537..278dd327fd 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Banner.h b/src/openrct2/world/Banner.h index a4a9cb0c5a..51cbb26b80 100644 --- a/src/openrct2/world/Banner.h +++ b/src/openrct2/world/Banner.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Climate.cpp b/src/openrct2/world/Climate.cpp index 03d1016866..08e3a13efd 100644 --- a/src/openrct2/world/Climate.cpp +++ b/src/openrct2/world/Climate.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Climate.h b/src/openrct2/world/Climate.h index b53a80a1d7..f0e7b126ea 100644 --- a/src/openrct2/world/Climate.h +++ b/src/openrct2/world/Climate.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Duck.cpp b/src/openrct2/world/Duck.cpp index 68cf9c4cdb..ce96c672f3 100644 --- a/src/openrct2/world/Duck.cpp +++ b/src/openrct2/world/Duck.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Entrance.cpp b/src/openrct2/world/Entrance.cpp index 489d68ee04..bd69c2822c 100644 --- a/src/openrct2/world/Entrance.cpp +++ b/src/openrct2/world/Entrance.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Entrance.h b/src/openrct2/world/Entrance.h index 740791b3f6..21698a922d 100644 --- a/src/openrct2/world/Entrance.h +++ b/src/openrct2/world/Entrance.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index fe07ff13db..df175c8f18 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 2266989c83..2575da28f0 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Fountain.cpp b/src/openrct2/world/Fountain.cpp index d5dad509bd..ee85628978 100644 --- a/src/openrct2/world/Fountain.cpp +++ b/src/openrct2/world/Fountain.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Fountain.h b/src/openrct2/world/Fountain.h index c0d1a4abef..49a7c4e758 100644 --- a/src/openrct2/world/Fountain.h +++ b/src/openrct2/world/Fountain.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/LargeScenery.cpp b/src/openrct2/world/LargeScenery.cpp index cc3114c5f2..97f27a4174 100644 --- a/src/openrct2/world/LargeScenery.cpp +++ b/src/openrct2/world/LargeScenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/LargeScenery.h b/src/openrct2/world/LargeScenery.h index df52e6df7a..070a68e968 100644 --- a/src/openrct2/world/LargeScenery.h +++ b/src/openrct2/world/LargeScenery.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index ae9df02b6a..f074a480e2 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index c824021b02..25d3ec1a6f 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index d8229981f1..b62a305f95 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapAnimation.cpp b/src/openrct2/world/MapAnimation.cpp index 84ee86c4a2..7190f93358 100644 --- a/src/openrct2/world/MapAnimation.cpp +++ b/src/openrct2/world/MapAnimation.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapAnimation.h b/src/openrct2/world/MapAnimation.h index 9bf6efd7b5..496c6b7fc5 100644 --- a/src/openrct2/world/MapAnimation.h +++ b/src/openrct2/world/MapAnimation.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 06f74aa5d8..f8e535872e 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapGen.h b/src/openrct2/world/MapGen.h index b2dcf79244..88c136cadb 100644 --- a/src/openrct2/world/MapGen.h +++ b/src/openrct2/world/MapGen.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapHelpers.cpp b/src/openrct2/world/MapHelpers.cpp index dd49bb6fe9..b77f788a1a 100644 --- a/src/openrct2/world/MapHelpers.cpp +++ b/src/openrct2/world/MapHelpers.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MapHelpers.h b/src/openrct2/world/MapHelpers.h index 440fec50b3..641d73c3d2 100644 --- a/src/openrct2/world/MapHelpers.h +++ b/src/openrct2/world/MapHelpers.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/MoneyEffect.cpp b/src/openrct2/world/MoneyEffect.cpp index 2af28d036c..6388fa22a6 100644 --- a/src/openrct2/world/MoneyEffect.cpp +++ b/src/openrct2/world/MoneyEffect.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index ea5c163742..4c83b610dd 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index cd54738bc9..6d0651374d 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Particle.cpp b/src/openrct2/world/Particle.cpp index b07414ac31..e2b40a64f1 100644 --- a/src/openrct2/world/Particle.cpp +++ b/src/openrct2/world/Particle.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 212232ccc2..7b233eddab 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h index beb7ef241f..528524b672 100644 --- a/src/openrct2/world/Scenery.h +++ b/src/openrct2/world/Scenery.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index f6846c5d9f..06e4649c55 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/SmallScenery.h b/src/openrct2/world/SmallScenery.h index 08e705dfbd..078df1c096 100644 --- a/src/openrct2/world/SmallScenery.h +++ b/src/openrct2/world/SmallScenery.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 7ec54cb326..08c7a02236 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 6becdade86..55b1d2ebed 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Surface.cpp b/src/openrct2/world/Surface.cpp index 4fa99a6137..decf1594b0 100644 --- a/src/openrct2/world/Surface.cpp +++ b/src/openrct2/world/Surface.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Surface.h b/src/openrct2/world/Surface.h index 21b601f9bd..dce541ecd2 100644 --- a/src/openrct2/world/Surface.h +++ b/src/openrct2/world/Surface.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/TileElement.cpp b/src/openrct2/world/TileElement.cpp index 827cd7be24..4b42addf0b 100644 --- a/src/openrct2/world/TileElement.cpp +++ b/src/openrct2/world/TileElement.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index 2eb2c7747a..4e350531ce 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 0e9aaaa54c..20f67bb87b 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/TileInspector.h b/src/openrct2/world/TileInspector.h index 426a7617fe..ab759f963f 100644 --- a/src/openrct2/world/TileInspector.h +++ b/src/openrct2/world/TileInspector.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 8830764011..230e1ddebd 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Wall.h b/src/openrct2/world/Wall.h index 3b80c5baa0..5ed51fb252 100644 --- a/src/openrct2/world/Wall.h +++ b/src/openrct2/world/Wall.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 diff --git a/src/openrct2/world/Water.h b/src/openrct2/world/Water.h index 04094813b8..e15ba65b96 100644 --- a/src/openrct2/world/Water.h +++ b/src/openrct2/world/Water.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 From 2457feb6abec974643e823e702e017e926a3cae8 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 10 Mar 2019 07:32:22 +0000 Subject: [PATCH 054/506] Create surface set style action --- .../actions/GameActionRegistration.cpp | 2 + .../actions/SurfaceSetStyleAction.hpp | 229 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 src/openrct2/actions/SurfaceSetStyleAction.hpp diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 065612940d..47ee6867af 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -51,6 +51,7 @@ #include "StaffSetCostumeAction.hpp" #include "StaffSetNameAction.hpp" #include "StaffSetOrdersAction.hpp" +#include "SurfaceSetStyleAction.hpp" #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "TrackSetBrakeSpeedAction.hpp" @@ -97,6 +98,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/SurfaceSetStyleAction.hpp b/src/openrct2/actions/SurfaceSetStyleAction.hpp new file mode 100644 index 0000000000..f9c772a596 --- /dev/null +++ b/src/openrct2/actions/SurfaceSetStyleAction.hpp @@ -0,0 +1,229 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 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 "../Context.h" +#include "../object/ObjectManager.h" +#include "../object/TerrainEdgeObject.h" +#include "../object/TerrainSurfaceObject.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(SurfaceSetStyleAction, GAME_COMMAND_CHANGE_SURFACE_STYLE, GameActionResult) +{ +private: + MapRange _range; + uint8_t _surfaceStyle; + uint8_t _edgeStyle; + +public: + SurfaceSetStyleAction() + { + } + + SurfaceSetStyleAction(MapRange range, uint8_t surfaceStyle, uint8_t edgeStyle) + : _range(range) + , _surfaceStyle(surfaceStyle) + , _edgeStyle(edgeStyle) + { + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + auto x0 = std::max(_range.GetLeft(), 32); + auto y0 = std::max(_range.GetTop(), 32); + auto x1 = std::min(_range.GetRight(), (int32_t)gMapSizeMaxXY); + auto y1 = std::min(_range.GetBottom(), (int32_t)gMapSizeMaxXY); + + MapRange validRange{ x0, y0, x1, y1 }; + auto& objManager = GetContext()->GetObjectManager(); + if (_surfaceStyle != 0xFF) + { + if (_surfaceStyle > 0x1F) + { + log_error("Invalid surface style."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_LAND_TYPE); + } + + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _surfaceStyle)); + + if (surfaceObj == nullptr) + { + log_error("Invalid surface style."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_LAND_TYPE); + } + } + + if (_edgeStyle != 0xFF) + { + if (_edgeStyle > 0xF) + { + log_error("Invalid edge style."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_LAND_TYPE); + } + + const auto edgeObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _edgeStyle)); + + if (edgeObj == nullptr) + { + log_error("Invalid edge style."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_LAND_TYPE); + } + } + + auto xMid = (validRange.GetLeft() + validRange.GetRight()) / 2 + 16; + auto yMid = (validRange.GetTop() + validRange.GetBottom()) / 2 + 16; + auto heightMid = tile_element_height(xMid, yMid) & 0xFFFF; + + res->Position.x = xMid; + res->Position.y = yMid; + res->Position.z = heightMid; + + // Do nothing if not in editor, sandbox mode or landscaping is forbidden + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode + && (gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_CHANGE_LAND_TYPE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY); + } + + money32 surfaceCost = 0; + money32 edgeCost = 0; + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park({ x, y })) + continue; + } + + auto tileElement = map_get_surface_element_at({ x, y }); + if (tileElement == nullptr) + { + continue; + } + + auto surfaceElement = tileElement->AsSurface(); + if (_surfaceStyle != 0xFF) + { + uint8_t curSurfaceStyle = surfaceElement->GetSurfaceStyle(); + + if (_surfaceStyle != curSurfaceStyle) + { + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _surfaceStyle)); + if (surfaceObj != nullptr) + { + surfaceCost += surfaceObj->Price; + } + } + } + + if (_edgeStyle != 0xFF) + { + uint8_t curEdgeStyle = surfaceElement->GetEdgeStyle(); + + if (_edgeStyle != curEdgeStyle) + { + edgeCost += 100; + } + } + } + } + res->Cost = surfaceCost + edgeCost; + + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + auto x0 = std::max(_range.GetLeft(), 32); + auto y0 = std::max(_range.GetTop(), 32); + auto x1 = std::min(_range.GetRight(), (int32_t)gMapSizeMaxXY); + auto y1 = std::min(_range.GetBottom(), (int32_t)gMapSizeMaxXY); + + MapRange validRange{ x0, y0, x1, y1 }; + + auto xMid = (validRange.GetLeft() + validRange.GetRight()) / 2 + 16; + auto yMid = (validRange.GetTop() + validRange.GetBottom()) / 2 + 16; + auto heightMid = tile_element_height(xMid, yMid) & 0xFFFF; + + res->Position.x = xMid; + res->Position.y = yMid; + res->Position.z = heightMid; + + money32 surfaceCost = 0; + money32 edgeCost = 0; + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + auto tileElement = map_get_surface_element_at({ x, y }); + if (tileElement == nullptr) + { + continue; + } + + auto surfaceElement = tileElement->AsSurface(); + if (_surfaceStyle != 0xFF) + { + uint8_t curSurfaceStyle = surfaceElement->GetSurfaceStyle(); + + if (_surfaceStyle != curSurfaceStyle) + { + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _surfaceStyle)); + if (surfaceObj != nullptr) + { + surfaceCost += surfaceObj->Price; + + surfaceElement->SetSurfaceStyle(_surfaceStyle); + + map_invalidate_tile_full(x, y); + footpath_remove_litter(x, y, tile_element_height(x, y)); + } + } + } + + if (_edgeStyle != 0xFF) + { + uint8_t curEdgeStyle = surfaceElement->GetEdgeStyle(); + + if (_edgeStyle != curEdgeStyle) + { + edgeCost += 100; + + surfaceElement->SetEdgeStyle(_edgeStyle); + map_invalidate_tile_full(x, y); + } + } + + if (surfaceElement->CanGrassGrow() && (surfaceElement->GetGrassLength() & 7) != GRASS_LENGTH_CLEAR_0) + { + surfaceElement->SetGrassLength(GRASS_LENGTH_CLEAR_0); + map_invalidate_tile_full(x, y); + } + } + } + res->Cost = surfaceCost + edgeCost; + + return res; + } +}; From c9332b4c5d7e2b31279b523ce9f575c66964e167 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 10 Mar 2019 09:15:22 +0000 Subject: [PATCH 055/506] Use the game action. Fix issues with it --- src/openrct2-ui/windows/Map.cpp | 10 ++-- src/openrct2-ui/windows/TopToolbar.cpp | 21 ++++--- .../actions/SurfaceSetStyleAction.hpp | 55 +++++++++++++------ 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 105dceff32..66fc7d905d 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -590,11 +591,10 @@ static void window_map_scrollmousedown(rct_window* w, int32_t scrollIndex, int32 gMapSelectPositionB.y = mapY + size; map_invalidate_selection_rect(); - gGameCommandErrorTitle = STR_CANT_CHANGE_LAND_TYPE; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, - gLandToolTerrainSurface | (gLandToolTerrainEdge << 8), GAME_COMMAND_CHANGE_SURFACE_STYLE, gMapSelectPositionB.x, - gMapSelectPositionB.y); + auto surfaceSetStyleAction = SurfaceSetStyleAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + gLandToolTerrainSurface, gLandToolTerrainEdge); + GameActions::Execute(&surfaceSetStyleAction); } else if (widget_is_active_tool(w, WIDX_SET_LAND_RIGHTS)) { diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index e26b4507ba..68c776e83e 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 @@ -2901,10 +2902,12 @@ static void window_top_toolbar_tool_down(rct_window* w, rct_widgetindex widgetIn case WIDX_LAND: if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) { - gGameCommandErrorTitle = STR_CANT_CHANGE_LAND_TYPE; - game_do_command( - gMapSelectPositionA.x, 1, gMapSelectPositionA.y, gLandToolTerrainSurface | (gLandToolTerrainEdge << 8), - GAME_COMMAND_CHANGE_SURFACE_STYLE, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto surfaceSetStyleAction = SurfaceSetStyleAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + gLandToolTerrainSurface, gLandToolTerrainEdge); + + GameActions::Execute(&surfaceSetStyleAction); + gCurrentToolId = TOOL_UP_DOWN_ARROW; } break; @@ -3102,10 +3105,12 @@ static void window_top_toolbar_tool_drag(rct_window* w, rct_widgetindex widgetIn { if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) { - gGameCommandErrorTitle = STR_CANT_CHANGE_LAND_TYPE; - game_do_command( - gMapSelectPositionA.x, 1, gMapSelectPositionA.y, gLandToolTerrainSurface | (gLandToolTerrainEdge << 8), - GAME_COMMAND_CHANGE_SURFACE_STYLE, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto surfaceSetStyleAction = SurfaceSetStyleAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + gLandToolTerrainSurface, gLandToolTerrainEdge); + + GameActions::Execute(&surfaceSetStyleAction); + // The tool is set to 12 here instead of 3 so that the dragging cursor is not the elevation change // cursor gCurrentToolId = TOOL_CROSSHAIR; diff --git a/src/openrct2/actions/SurfaceSetStyleAction.hpp b/src/openrct2/actions/SurfaceSetStyleAction.hpp index f9c772a596..6bfdd957cc 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.hpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.hpp @@ -10,9 +10,13 @@ #pragma once #include "../Context.h" +#include "../management/Finance.h" #include "../object/ObjectManager.h" #include "../object/TerrainEdgeObject.h" #include "../object/TerrainSurfaceObject.h" +#include "../world/Park.h" +#include "../world/Surface.h" +#include "../world/TileElement.h" #include "GameAction.h" DEFINE_GAME_ACTION(SurfaceSetStyleAction, GAME_COMMAND_CHANGE_SURFACE_STYLE, GameActionResult) @@ -34,18 +38,28 @@ public: { } + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_range) << DS_TAG(_surfaceStyle) << DS_TAG(_edgeStyle); + } + GameActionResult::Ptr Query() const override { auto res = MakeResult(); + res->ErrorTitle = STR_CANT_CHANGE_LAND_TYPE; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - auto x0 = std::max(_range.GetLeft(), 32); - auto y0 = std::max(_range.GetTop(), 32); - auto x1 = std::min(_range.GetRight(), (int32_t)gMapSizeMaxXY); - auto y1 = std::min(_range.GetBottom(), (int32_t)gMapSizeMaxXY); + auto normRange = _range.Normalise(); + auto x0 = std::max(normRange.GetLeft(), 32); + auto y0 = std::max(normRange.GetTop(), 32); + auto x1 = std::min(normRange.GetRight(), (int32_t)gMapSizeMaxXY); + auto y1 = std::min(normRange.GetBottom(), (int32_t)gMapSizeMaxXY); MapRange validRange{ x0, y0, x1, y1 }; - auto& objManager = GetContext()->GetObjectManager(); + + auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); if (_surfaceStyle != 0xFF) { if (_surfaceStyle > 0x1F) @@ -122,12 +136,11 @@ public: if (_surfaceStyle != curSurfaceStyle) { - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( + const auto surfaceObject = static_cast( objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _surfaceStyle)); - if (surfaceObj != nullptr) + if (surfaceObject != nullptr) { - surfaceCost += surfaceObj->Price; + surfaceCost += surfaceObject->Price; } } } @@ -151,12 +164,14 @@ public: GameActionResult::Ptr Execute() const override { auto res = MakeResult(); + res->ErrorTitle = STR_CANT_CHANGE_LAND_TYPE; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - auto x0 = std::max(_range.GetLeft(), 32); - auto y0 = std::max(_range.GetTop(), 32); - auto x1 = std::min(_range.GetRight(), (int32_t)gMapSizeMaxXY); - auto y1 = std::min(_range.GetBottom(), (int32_t)gMapSizeMaxXY); + auto normRange = _range.Normalise(); + auto x0 = std::max(normRange.GetLeft(), 32); + auto y0 = std::max(normRange.GetTop(), 32); + auto x1 = std::min(normRange.GetRight(), (int32_t)gMapSizeMaxXY); + auto y1 = std::min(normRange.GetBottom(), (int32_t)gMapSizeMaxXY); MapRange validRange{ x0, y0, x1, y1 }; @@ -174,6 +189,12 @@ public: { for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park({ x, y })) + continue; + } + auto tileElement = map_get_surface_element_at({ x, y }); if (tileElement == nullptr) { @@ -187,12 +208,12 @@ public: if (_surfaceStyle != curSurfaceStyle) { - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( + auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); + const auto surfaceObject = static_cast( objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _surfaceStyle)); - if (surfaceObj != nullptr) + if (surfaceObject != nullptr) { - surfaceCost += surfaceObj->Price; + surfaceCost += surfaceObject->Price; surfaceElement->SetSurfaceStyle(_surfaceStyle); From 9fc464a322b9c2e2679fdf78109449759e4b3672 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 10 Mar 2019 09:20:34 +0000 Subject: [PATCH 056/506] Remove game command Correct the copyright Include correct headers --- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 12 +- .../actions/SurfaceSetStyleAction.hpp | 3 +- src/openrct2/world/Map.cpp | 139 ------------------ src/openrct2/world/Map.h | 2 - 5 files changed, 9 insertions(+), 149 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 333bb07afa..3b9550ffad 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1280,7 +1280,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_change_surface_style, + nullptr, nullptr, game_command_set_guest_name, game_command_set_staff_name, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 7a495fb1ab..640d057b88 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -38,12 +38,12 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_PATH, // GA GAME_COMMAND_PLACE_PATH_FROM_TRACK, // GA GAME_COMMAND_REMOVE_PATH, // GA - GAME_COMMAND_CHANGE_SURFACE_STYLE, - GAME_COMMAND_SET_RIDE_PRICE, // GA - GAME_COMMAND_SET_GUEST_NAME, // GA - GAME_COMMAND_SET_STAFF_NAME, // GA - GAME_COMMAND_RAISE_LAND, // GA - GAME_COMMAND_LOWER_LAND, // GA + GAME_COMMAND_CHANGE_SURFACE_STYLE, // GA + GAME_COMMAND_SET_RIDE_PRICE, // GA + GAME_COMMAND_SET_GUEST_NAME, // GA + GAME_COMMAND_SET_STAFF_NAME, // GA + GAME_COMMAND_RAISE_LAND, // GA + GAME_COMMAND_LOWER_LAND, // GA GAME_COMMAND_EDIT_LAND_SMOOTH, GAME_COMMAND_RAISE_WATER, // GA GAME_COMMAND_LOWER_WATER, // GA diff --git a/src/openrct2/actions/SurfaceSetStyleAction.hpp b/src/openrct2/actions/SurfaceSetStyleAction.hpp index 6bfdd957cc..cf281f1f7b 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.hpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2018 OpenRCT2 developers + * 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 @@ -10,6 +10,7 @@ #pragma once #include "../Context.h" +#include "../OpenRCT2.h" #include "../management/Finance.h" #include "../object/ObjectManager.h" #include "../object/TerrainEdgeObject.h" diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 25d3ec1a6f..82dd757cce 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -877,145 +877,6 @@ void game_command_set_large_scenery_colour( *ebx = 0; } -/** - * - * rct2: 0x00663CCD - */ -static money32 map_change_surface_style( - int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint8_t surfaceStyle, uint8_t edgeStyle, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - - x0 = std::max(x0, 32); - y0 = std::max(y0, 32); - x1 = std::min(x1, (int32_t)gMapSizeMaxXY); - y1 = std::min(y1, (int32_t)gMapSizeMaxXY); - - int32_t xMid, yMid; - - xMid = (x0 + x1) / 2 + 16; - yMid = (y0 + y1) / 2 + 16; - - int32_t heightMid = tile_element_height(xMid, yMid); - - gCommandPosition.x = xMid; - gCommandPosition.y = yMid; - gCommandPosition.z = heightMid; - - // Do nothing during pause - if (game_is_paused() && !gCheatsBuildInPauseMode) - { - return 0; - } - - // Do nothing if not in editor, sandbox mode or landscaping is forbidden - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode - && (gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)) - { - return 0; - } - - money32 surfaceCost = 0; - money32 edgeCost = 0; - for (int32_t x = x0; x <= x1; x += 32) - { - for (int32_t y = y0; y <= y1; y += 32) - { - if (x > 0x1FFF) - continue; - if (y > 0x1FFF) - continue; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) - { - if (!map_is_location_in_park({ x, y })) - continue; - } - - auto surfaceElement = map_get_surface_element_at({ x, y })->AsSurface(); - if (surfaceElement == nullptr) - { - continue; - } - - if (surfaceStyle != 0xFF) - { - uint8_t cur_terrain = surfaceElement->GetSurfaceStyle(); - - if (surfaceStyle != cur_terrain) - { - // Prevent network-originated value of surfaceStyle from causing - // invalid access. - uint8_t style = surfaceStyle & 0x1F; - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( - objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, style)); - if (surfaceObj != nullptr) - { - surfaceCost += surfaceObj->Price; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetSurfaceStyle(surfaceStyle); - - map_invalidate_tile_full(x, y); - footpath_remove_litter(x, y, tile_element_height(x, y)); - } - } - } - - if (edgeStyle != 0xFF) - { - uint8_t currentEdge = surfaceElement->GetEdgeStyle(); - - if (edgeStyle != currentEdge) - { - edgeCost += 100; - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetEdgeStyle(edgeStyle); - map_invalidate_tile_full(x, y); - } - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (surfaceElement->CanGrassGrow() && (surfaceElement->GetGrassLength() & 7) != GRASS_LENGTH_CLEAR_0) - { - surfaceElement->SetGrassLength(GRASS_LENGTH_CLEAR_0); - map_invalidate_tile_full(x, y); - } - } - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY && gGameCommandNestLevel == 1) - { - LocationXYZ16 coord; - coord.x = ((x0 + x1) / 2) + 16; - coord.y = ((y0 + y1) / 2) + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - return (gParkFlags & PARK_FLAGS_NO_MONEY) ? 0 : surfaceCost + edgeCost; -} - -/** - * - * rct2: 0x00663CCD - */ -void game_command_change_surface_style( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - *ebx = map_change_surface_style( - (int16_t)(*eax & 0xFFFF), (int16_t)(*ecx & 0xFFFF), (int16_t)(*edi & 0xFFFF), (int16_t)(*ebp & 0xFFFF), *edx & 0xFF, - (*edx & 0xFF00) >> 8, *ebx & 0xFF); -} - // 0x00981A1E // Table of pre-calculated surface slopes (32) when raising the land tile for a given selection (5) // 0x1F = new slope diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index b62a305f95..7c7a395a05 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -202,8 +202,6 @@ void game_command_set_large_scenery_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_change_surface_style( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_smooth_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); From e97428acc0c0df7c32ecf07aa5c3f9c4bd296480 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 17 Mar 2019 07:26:39 +0000 Subject: [PATCH 057/506] Make requested changes --- src/openrct2/actions/StaffFireAction.hpp | 8 ++++---- .../actions/StaffSetPatrolAreaAction.hpp | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/openrct2/actions/StaffFireAction.hpp b/src/openrct2/actions/StaffFireAction.hpp index 30369e3c00..49e1f70f05 100644 --- a/src/openrct2/actions/StaffFireAction.hpp +++ b/src/openrct2/actions/StaffFireAction.hpp @@ -17,7 +17,7 @@ DEFINE_GAME_ACTION(StaffFireAction, GAME_COMMAND_FIRE_STAFF_MEMBER, GameActionResult) { private: - uint16_t _spriteId; + uint16_t _spriteId{ SPRITE_INDEX_NULL }; public: StaffFireAction() @@ -43,14 +43,14 @@ public: { if (_spriteId >= MAX_SPRITES) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } auto peep = GET_PEEP(_spriteId); if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } @@ -62,7 +62,7 @@ public: auto peep = GET_PEEP(_spriteId); if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } window_close_by_class(WC_FIRE_PROMPT); diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp index 04339908ff..355494da4f 100644 --- a/src/openrct2/actions/StaffSetPatrolAreaAction.hpp +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.hpp @@ -18,7 +18,7 @@ DEFINE_GAME_ACTION(StaffSetPatrolAreaAction, GAME_COMMAND_SET_STAFF_PATROL, GameActionResult) { private: - uint16_t _spriteId; + uint16_t _spriteId{ SPRITE_INDEX_NULL }; CoordsXY _loc; public: @@ -46,14 +46,14 @@ public: { if (_spriteId >= MAX_SPRITES) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } auto peep = GET_PEEP(_spriteId); if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } @@ -65,7 +65,7 @@ public: auto peep = GET_PEEP(_spriteId); if (peep == nullptr || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) { - log_error("Invalid spriteId."); + log_error("Invalid spriteId. spriteId = %u", _spriteId); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } @@ -73,14 +73,18 @@ public: staff_toggle_patrol_area(peep->staff_id, _loc.x, _loc.y); - int32_t ispatrolling = 0; + bool isPatrolling = false; for (int32_t i = 0; i < 128; i++) { - ispatrolling |= gStaffPatrolAreas[patrolOffset + i]; + if (gStaffPatrolAreas[patrolOffset + i]) + { + isPatrolling = true; + break; + } } gStaffModes[peep->staff_id] &= ~(1 << 1); - if (ispatrolling) + if (isPatrolling) { gStaffModes[peep->staff_id] |= (1 << 1); } From 97ba6eec088c4debf99b173abbb4564d5a626b1b Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sun, 17 Mar 2019 12:52:32 +0100 Subject: [PATCH 058/506] Move common actions from debug menu into cheats menu (#8892) This aims to make it less necessary for users to enable debugging tools. --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/TopToolbar.cpp | 169 ++++++++++++++----------- 2 files changed, 98 insertions(+), 72 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 472b25afee..0224ee2f82 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Fix: [#5579] Network desync immediately after connecting. - Fix: [#8873] Potential crash when placing footpaths. +- Change: [#8688] Move common actions from debug menu into cheats menu. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index e26b4507ba..adf06c0ae4 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -136,11 +136,7 @@ enum TOP_TOOLBAR_VIEW_MENU_DDIDX { enum TOP_TOOLBAR_DEBUG_DDIDX { DDIDX_CONSOLE = 0, - DDIDX_TILE_INSPECTOR = 1, - DDIDX_OBJECT_SELECTION = 2, - DDIDX_INVENTIONS_LIST = 3, - DDIDX_SCENARIO_OPTIONS = 4, - DDIDX_DEBUG_PAINT = 5, + DDIDX_DEBUG_PAINT = 1, TOP_TOOLBAR_DEBUG_COUNT }; @@ -152,9 +148,16 @@ enum TOP_TOOLBAR_NETWORK_DDIDX { enum { DDIDX_CHEATS, - DDIDX_ENABLE_SANDBOX_MODE = 2, - DDIDX_DISABLE_CLEARANCE_CHECKS, - DDIDX_DISABLE_SUPPORT_LIMITS + DDIDX_TILE_INSPECTOR = 1, + DDIDX_OBJECT_SELECTION = 2, + DDIDX_INVENTIONS_LIST = 3, + DDIDX_SCENARIO_OPTIONS = 4, + // 5 is a separator + DDIDX_ENABLE_SANDBOX_MODE = 6, + DDIDX_DISABLE_CLEARANCE_CHECKS = 7, + DDIDX_DISABLE_SUPPORT_LIMITS = 8, + + TOP_TOOLBAR_CHEATS_COUNT }; enum { @@ -293,6 +296,8 @@ static void top_toolbar_init_fastforward_menu(rct_window* window, rct_widget* wi static void top_toolbar_fastforward_menu_dropdown(int16_t dropdownIndex); static void top_toolbar_init_rotate_menu(rct_window* window, rct_widget* widget); static void top_toolbar_rotate_menu_dropdown(int16_t dropdownIndex); +static void top_toolbar_init_cheats_menu(rct_window* window, rct_widget* widget); +static void top_toolbar_cheats_menu_dropdown(int16_t dropdownIndex); static void top_toolbar_init_debug_menu(rct_window* window, rct_widget* widget); static void top_toolbar_debug_menu_dropdown(int16_t dropdownIndex); static void top_toolbar_init_network_menu(rct_window* window, rct_widget* widget); @@ -496,30 +501,7 @@ static void window_top_toolbar_mousedown(rct_window* w, rct_widgetindex widgetIn #endif break; case WIDX_CHEATS: - gDropdownItemsFormat[0] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[1] = STR_EMPTY; - gDropdownItemsFormat[2] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[3] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[4] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[0] = STR_CHEAT_TITLE; - gDropdownItemsArgs[2] = STR_ENABLE_SANDBOX_MODE; - gDropdownItemsArgs[3] = STR_DISABLE_CLEARANCE_CHECKS; - gDropdownItemsArgs[4] = STR_DISABLE_SUPPORT_LIMITS; - window_dropdown_show_text( - w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0, 5); - if (gCheatsSandboxMode) - { - dropdown_set_checked(DDIDX_ENABLE_SANDBOX_MODE, true); - } - if (gCheatsDisableClearanceChecks) - { - dropdown_set_checked(DDIDX_DISABLE_CLEARANCE_CHECKS, true); - } - if (gCheatsDisableSupportLimits) - { - dropdown_set_checked(DDIDX_DISABLE_SUPPORT_LIMITS, true); - } - gDropdownDefaultIndex = DDIDX_CHEATS; + top_toolbar_init_cheats_menu(w, widget); break; case WIDX_VIEW_MENU: top_toolbar_init_view_menu(w, widget); @@ -648,26 +630,7 @@ static void window_top_toolbar_dropdown(rct_window* w, rct_widgetindex widgetInd } break; case WIDX_CHEATS: - switch (dropdownIndex) - { - case DDIDX_CHEATS: - context_open_window(WC_CHEATS); - break; - case DDIDX_ENABLE_SANDBOX_MODE: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, !gCheatsSandboxMode, GAME_COMMAND_CHEAT, 0, 0); - break; - case DDIDX_DISABLE_CLEARANCE_CHECKS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, !gCheatsDisableClearanceChecks, - GAME_COMMAND_CHEAT, 0, 0); - break; - case DDIDX_DISABLE_SUPPORT_LIMITS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, !gCheatsDisableSupportLimits, - GAME_COMMAND_CHEAT, 0, 0); - break; - } + top_toolbar_cheats_menu_dropdown(dropdownIndex); break; case WIDX_VIEW_MENU: top_toolbar_view_menu_dropdown(dropdownIndex); @@ -3261,24 +3224,37 @@ static void top_toolbar_rotate_menu_dropdown(int16_t dropdownIndex) } } -static void top_toolbar_init_debug_menu(rct_window* w, rct_widget* widget) +static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) { - gDropdownItemsFormat[DDIDX_CONSOLE] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_CONSOLE] = STR_DEBUG_DROPDOWN_CONSOLE; + gDropdownItemsFormat[DDIDX_CHEATS] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_CHEATS] = STR_CHEAT_TITLE; + gDropdownItemsFormat[DDIDX_TILE_INSPECTOR] = STR_TOGGLE_OPTION; gDropdownItemsArgs[DDIDX_TILE_INSPECTOR] = STR_DEBUG_DROPDOWN_TILE_INSPECTOR; + gDropdownItemsFormat[DDIDX_OBJECT_SELECTION] = STR_TOGGLE_OPTION; gDropdownItemsArgs[DDIDX_OBJECT_SELECTION] = STR_DEBUG_DROPDOWN_OBJECT_SELECTION; + gDropdownItemsFormat[DDIDX_INVENTIONS_LIST] = STR_TOGGLE_OPTION; gDropdownItemsArgs[DDIDX_INVENTIONS_LIST] = STR_DEBUG_DROPDOWN_INVENTIONS_LIST; + gDropdownItemsFormat[DDIDX_SCENARIO_OPTIONS] = STR_TOGGLE_OPTION; gDropdownItemsArgs[DDIDX_SCENARIO_OPTIONS] = STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS; - gDropdownItemsFormat[DDIDX_DEBUG_PAINT] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_DEBUG_PAINT] = STR_DEBUG_DROPDOWN_DEBUG_PAINT; + + gDropdownItemsFormat[5] = STR_EMPTY; + + gDropdownItemsFormat[DDIDX_ENABLE_SANDBOX_MODE] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_ENABLE_SANDBOX_MODE] = STR_ENABLE_SANDBOX_MODE; + + gDropdownItemsFormat[DDIDX_DISABLE_CLEARANCE_CHECKS] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_DISABLE_CLEARANCE_CHECKS] = STR_DISABLE_CLEARANCE_CHECKS; + + gDropdownItemsFormat[DDIDX_DISABLE_SUPPORT_LIMITS] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_DISABLE_SUPPORT_LIMITS] = STR_DISABLE_SUPPORT_LIMITS; window_dropdown_show_text( - w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, - DROPDOWN_FLAG_STAY_OPEN, TOP_TOOLBAR_DEBUG_COUNT); + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0, + TOP_TOOLBAR_CHEATS_COUNT); // Disable items that are not yet available in multiplayer if (network_get_mode() != NETWORK_MODE_NONE) @@ -3287,6 +3263,68 @@ static void top_toolbar_init_debug_menu(rct_window* w, rct_widget* widget) dropdown_set_disabled(DDIDX_INVENTIONS_LIST, true); } + if (gCheatsSandboxMode) + { + dropdown_set_checked(DDIDX_ENABLE_SANDBOX_MODE, true); + } + if (gCheatsDisableClearanceChecks) + { + dropdown_set_checked(DDIDX_DISABLE_CLEARANCE_CHECKS, true); + } + if (gCheatsDisableSupportLimits) + { + dropdown_set_checked(DDIDX_DISABLE_SUPPORT_LIMITS, true); + } + + gDropdownDefaultIndex = DDIDX_CHEATS; +} + +static void top_toolbar_cheats_menu_dropdown(int16_t dropdownIndex) +{ + switch (dropdownIndex) + { + case DDIDX_CHEATS: + context_open_window(WC_CHEATS); + break; + case DDIDX_TILE_INSPECTOR: + context_open_window(WC_TILE_INSPECTOR); + break; + case DDIDX_OBJECT_SELECTION: + window_close_all(); + context_open_window(WC_EDITOR_OBJECT_SELECTION); + break; + case DDIDX_INVENTIONS_LIST: + context_open_window(WC_EDITOR_INVENTION_LIST); + break; + case DDIDX_SCENARIO_OPTIONS: + context_open_window(WC_EDITOR_SCENARIO_OPTIONS); + break; + case DDIDX_ENABLE_SANDBOX_MODE: + game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, !gCheatsSandboxMode, GAME_COMMAND_CHEAT, 0, 0); + break; + case DDIDX_DISABLE_CLEARANCE_CHECKS: + game_do_command( + 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, !gCheatsDisableClearanceChecks, GAME_COMMAND_CHEAT, 0, + 0); + break; + case DDIDX_DISABLE_SUPPORT_LIMITS: + game_do_command( + 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, !gCheatsDisableSupportLimits, GAME_COMMAND_CHEAT, 0, 0); + break; + } +} + +static void top_toolbar_init_debug_menu(rct_window* w, rct_widget* widget) +{ + gDropdownItemsFormat[DDIDX_CONSOLE] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_CONSOLE] = STR_DEBUG_DROPDOWN_CONSOLE; + gDropdownItemsFormat[DDIDX_DEBUG_PAINT] = STR_TOGGLE_OPTION; + gDropdownItemsArgs[DDIDX_DEBUG_PAINT] = STR_DEBUG_DROPDOWN_DEBUG_PAINT; + + window_dropdown_show_text( + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, + DROPDOWN_FLAG_STAY_OPEN, TOP_TOOLBAR_DEBUG_COUNT); + dropdown_set_checked(DDIDX_DEBUG_PAINT, window_find_by_class(WC_DEBUG_PAINT) != nullptr); } @@ -3316,19 +3354,6 @@ static void top_toolbar_debug_menu_dropdown(int16_t dropdownIndex) console.Open(); break; } - case DDIDX_TILE_INSPECTOR: - context_open_window(WC_TILE_INSPECTOR); - break; - case DDIDX_OBJECT_SELECTION: - window_close_all(); - context_open_window(WC_EDITOR_OBJECT_SELECTION); - break; - case DDIDX_INVENTIONS_LIST: - context_open_window(WC_EDITOR_INVENTION_LIST); - break; - case DDIDX_SCENARIO_OPTIONS: - context_open_window(WC_EDITOR_SCENARIO_OPTIONS); - break; case DDIDX_DEBUG_PAINT: if (window_find_by_class(WC_DEBUG_PAINT) == nullptr) { From 8bf693983ab6d68e27443aef9846dddaef01f182 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 17 Mar 2019 16:55:17 +0100 Subject: [PATCH 059/506] Fix #7884: Unfinished preserved rides can be demolished with quick demolish --- distribution/changelog.txt | 1 + src/openrct2/actions/RideDemolishAction.hpp | 3 ++- src/openrct2/network/Network.cpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 0224ee2f82..a774821a00 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ - Fix: [#5579] Network desync immediately after connecting. +- Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Change: [#8688] Move common actions from debug menu into cheats menu. diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 59f391454c..845d6ff2b7 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -61,7 +61,8 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DEMOLISH_RIDE, STR_NONE); } - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE && _modifyType == RIDE_MODIFY_DEMOLISH) + if (ride->lifecycle_flags & (RIDE_LIFECYCLE_INDESTRUCTIBLE | RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) + && _modifyType == RIDE_MODIFY_DEMOLISH) { return std::make_unique( GA_ERROR::NO_CLEARANCE, STR_CANT_DEMOLISH_RIDE, diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 0782868f05..8557885657 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 "3" +#define NETWORK_STREAM_VERSION "4" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 57283a4e2b164f85398d62c674b6d80ff725e62c Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 16 Mar 2019 22:25:56 +0100 Subject: [PATCH 060/506] Fix #8900: Implement GuestSetFlagsAction. --- src/openrct2-ui/windows/Guest.cpp | 10 ++- src/openrct2/Game.h | 1 + .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/GuestSetFlagsAction.hpp | 70 +++++++++++++++++++ src/openrct2/network/NetworkAction.cpp | 1 + src/openrct2/network/Twitch.cpp | 30 ++++++-- 6 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 src/openrct2/actions/GuestSetFlagsAction.hpp diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index a1d0139936..0913983a95 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -636,8 +637,13 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex) window_scroll_to_viewport(w); break; case WIDX_TRACK: - get_sprite(w->number)->peep.peep_flags ^= PEEP_FLAGS_TRACKING; - break; + { + uint32_t flags = peep->peep_flags ^ PEEP_FLAGS_TRACKING; + + auto guestSetFlagsAction = GuestSetFlagsAction(w->number, flags); + GameActions::Execute(&guestSetFlagsAction); + } + break; } } diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 7a495fb1ab..f4ef202186 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -96,6 +96,7 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_COSTUME, // GA GAME_COMMAND_PLACE_FOOTPATH_SCENERY, // GA GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA + GAME_COMMAND_GUEST_SET_FLAGS, // GA GAME_COMMAND_COUNT, }; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 065612940d..656ff7c000 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -16,6 +16,7 @@ #include "FootpathSceneryPlaceAction.hpp" #include "FootpathSceneryRemoveAction.hpp" #include "GameAction.h" +#include "GuestSetFlagsAction.hpp" #include "GuestSetNameAction.hpp" #include "LandLowerAction.hpp" #include "LandRaiseAction.hpp" @@ -113,5 +114,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/GuestSetFlagsAction.hpp b/src/openrct2/actions/GuestSetFlagsAction.hpp new file mode 100644 index 0000000000..56a1b86fb9 --- /dev/null +++ b/src/openrct2/actions/GuestSetFlagsAction.hpp @@ -0,0 +1,70 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../world/Sprite.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(GuestSetFlagsAction, GAME_COMMAND_GUEST_SET_FLAGS, GameActionResult) +{ +private: + uint16_t _peepId = SPRITE_INDEX_NULL; + uint32_t _newFlags = 0; + +public: + GuestSetFlagsAction() + { + } + + GuestSetFlagsAction(uint16_t peepId, uint32_t flags) + : _peepId(peepId) + , _newFlags(flags) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_peepId) << DS_TAG(_newFlags); + } + + GameActionResult::Ptr Query() const override + { + Peep* peep = GET_PEEP(_peepId); + if (peep == nullptr) + { + log_error("Used invalid sprite index for peep: %u", (uint32_t)_peepId); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_THIS); + } + return std::make_unique(); + } + + GameActionResult::Ptr Execute() const override + { + Peep* peep = GET_PEEP(_peepId); + if (peep == nullptr) + { + log_error("Used invalid sprite index for peep: %u", (uint32_t)_peepId); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_THIS); + } + + peep->peep_flags = _newFlags; + + return std::make_unique(); + } +}; diff --git a/src/openrct2/network/NetworkAction.cpp b/src/openrct2/network/NetworkAction.cpp index bb1d338994..531be704eb 100644 --- a/src/openrct2/network/NetworkAction.cpp +++ b/src/openrct2/network/NetworkAction.cpp @@ -171,6 +171,7 @@ const std::array NetworkActions::Action GAME_COMMAND_SET_GUEST_NAME, GAME_COMMAND_PICKUP_GUEST, GAME_COMMAND_BALLOON_PRESS, + GAME_COMMAND_GUEST_SET_FLAGS, }, }, NetworkAction{ diff --git a/src/openrct2/network/Twitch.cpp b/src/openrct2/network/Twitch.cpp index 7718d2df75..0d812807c4 100644 --- a/src/openrct2/network/Twitch.cpp +++ b/src/openrct2/network/Twitch.cpp @@ -24,6 +24,7 @@ void twitch_update() # include "../Context.h" # include "../Game.h" # include "../OpenRCT2.h" +# include "../actions/GuestSetFlagsAction.hpp" # include "../config/Config.h" # include "../core/Json.hpp" # include "../core/String.hpp" @@ -442,30 +443,41 @@ namespace Twitch if (member == nullptr) { // Member no longer peep name worthy - peep->peep_flags &= ~(PEEP_FLAGS_TRACKING | PEEP_FLAGS_TWITCH); + uint32_t flags = peep->peep_flags & ~(PEEP_FLAGS_TRACKING | PEEP_FLAGS_TWITCH); + + auto guestSetFlagsAction = GuestSetFlagsAction(peep->sprite_index, flags); + GameActions::Execute(&guestSetFlagsAction); // TODO set peep name back to number / real name } else { + uint32_t flags = peep->peep_flags; if (member->ShouldTrack) { - peep->peep_flags |= (PEEP_FLAGS_TRACKING); + flags |= (PEEP_FLAGS_TRACKING); } else if (!member->ShouldTrack) { - peep->peep_flags &= ~(PEEP_FLAGS_TRACKING); + flags &= ~(PEEP_FLAGS_TRACKING); + } + if (flags != peep->peep_flags) + { + auto guestSetFlagsAction = GuestSetFlagsAction(peep->sprite_index, flags); + GameActions::Execute(&guestSetFlagsAction); } } } else if (member != nullptr && !(peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)) { // Peep with same name already exists but not twitch - peep->peep_flags |= PEEP_FLAGS_TWITCH; + uint32_t flags = peep->peep_flags | PEEP_FLAGS_TWITCH; if (member->ShouldTrack) { - peep->peep_flags |= PEEP_FLAGS_TRACKING; + flags |= PEEP_FLAGS_TRACKING; } + auto guestSetFlagsAction = GuestSetFlagsAction(peep->sprite_index, flags); + GameActions::Execute(&guestSetFlagsAction); } } } @@ -498,11 +510,15 @@ namespace Twitch if (newStringId != 0) { peep->name_string_idx = newStringId; - peep->peep_flags |= PEEP_FLAGS_TWITCH; + + uint32_t flags = peep->peep_flags | PEEP_FLAGS_TWITCH; if (member->ShouldTrack) { - peep->peep_flags |= PEEP_FLAGS_TRACKING; + flags |= PEEP_FLAGS_TRACKING; } + + auto guestSetFlagsAction = GuestSetFlagsAction(peep->sprite_index, flags); + GameActions::Execute(&guestSetFlagsAction); } } else From a9e9993ff5c8846308a509ee8db07d9eb2928793 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 17 Mar 2019 22:18:56 +0000 Subject: [PATCH 061/506] Fix #8910. Staff patrol areas sharing id's. (#8912) --- src/openrct2/actions/StaffHireNewAction.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index e74d7d2b2a..78b98255d2 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -256,7 +256,7 @@ private: peep_update_name_sort(newPeep); - newPeep->staff_id = newStaffId; + newPeep->staff_id = staffIndex; gStaffModes[staffIndex] = STAFF_MODE_WALK; From ce1d0756b468d24c6ab603b49debd622cbb582ea Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 17 Mar 2019 22:15:40 +0100 Subject: [PATCH 062/506] [ci skip] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index a774821a00..2c68abe061 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -4,6 +4,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Change: [#8688] Move common actions from debug menu into cheats menu. +- Fix: [#8900] Synchronize peep tracking to prevent desyncs. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ From a8ebd76b2d18e3817866103faf42f59d0f3bf155 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 18 Mar 2019 19:40:17 +0100 Subject: [PATCH 063/506] Update [ci skip] --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 2c68abe061..a78b1703f8 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,9 +1,9 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. -- Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#8900] Synchronize peep tracking to prevent desyncs. 0.2.2 (2019-03-13) From 5b600e6caa33b10d1bd66b3f112b2e1ad27e3ac9 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 18 Mar 2019 19:42:07 +0100 Subject: [PATCH 064/506] Mention the bug, not the fix [ci skip] --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index a78b1703f8..9c4cf75fec 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -4,7 +4,7 @@ - Fix: [#5579] Network desync immediately after connecting. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. -- Fix: [#8900] Synchronize peep tracking to prevent desyncs. +- Fix: [#8900] Peep tracking is not synchronized. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ From aa2f0a46d02338524c1d78854ac23cc3dd38549f Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 18 Mar 2019 20:01:30 +0000 Subject: [PATCH 065/506] 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 8557885657..e48d011737 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 "4" +#define NETWORK_STREAM_VERSION "5" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From fb36d2b1f9cd3cb1ea5fad800c3e2e2be4214f14 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 18 Mar 2019 21:38:48 +0000 Subject: [PATCH 066/506] Set price of all rides from the console --- src/openrct2/interface/InteractiveConsole.cpp | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 579500f49f..c51732039f 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -16,6 +16,7 @@ #include "../ReplayManager.h" #include "../Version.h" #include "../actions/ClimateSetAction.hpp" +#include "../actions/RideSetPriceAction.hpp" #include "../actions/RideSetSetting.hpp" #include "../actions/StaffSetCostumeAction.hpp" #include "../config/Config.h" @@ -169,6 +170,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) console.WriteFormatLine("rides set excitement "); console.WriteFormatLine("rides set intensity "); console.WriteFormatLine("rides set nausea "); + console.WriteFormatLine("rides set price [type] "); } return 0; } @@ -358,6 +360,67 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } } } + else if (argv[1] == "price") + { + bool int_valid[2] = { false }; + if (argv[2] == "all") + { + auto arg1 = console_parse_int(argv[3], &int_valid[0]); + if (argv.size() <= 4) + { + auto price = arg1; + if (int_valid[0]) + { + uint16_t rideId{}; + Ride* ride; + FOR_ALL_RIDES (rideId, ride) + { + auto rideSetPrice = RideSetPriceAction(rideId, price, true); + GameActions::Execute(&rideSetPrice); + } + } + else + { + console.WriteFormatLine("This command expects one or two integer arguments"); + } + } + else + { + auto rideType = arg1; + auto price = console_parse_int(argv[4], &int_valid[1]); + + if (int_valid[0] && int_valid[1]) + { + uint16_t rideId{}; + Ride* ride; + FOR_ALL_RIDES (rideId, ride) + { + if (ride->type == rideType) + { + auto rideSetPrice = RideSetPriceAction(rideId, price, true); + GameActions::Execute(&rideSetPrice); + } + } + } + else + { + console.WriteFormatLine("This command expects one or two integer arguments"); + } + } + } + else + { + int32_t rideId = console_parse_int(argv[2], &int_valid[0]); + money16 price = console_parse_int(argv[3], &int_valid[1]); + + if (!int_valid[0] || !int_valid[1]) + { + console.WriteFormatLine("This command expects the string all or two integer arguments"); + } + auto rideSetPrice = RideSetPriceAction(rideId, price, true); + GameActions::Execute(&rideSetPrice); + } + } } } else From 576976627e307f7c05b1ab7703ee65e4b2aff547 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 18 Mar 2019 21:45:32 +0000 Subject: [PATCH 067/506] Use displayable character instead of pipe --- src/openrct2/interface/InteractiveConsole.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index c51732039f..fa0ab0761f 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -170,7 +170,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) console.WriteFormatLine("rides set excitement "); console.WriteFormatLine("rides set intensity "); console.WriteFormatLine("rides set nausea "); - console.WriteFormatLine("rides set price [type] "); + console.WriteFormatLine("rides set price [type] "); } return 0; } From d5fa7185ca6d68075745aad9febf0e99463acce5 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 18 Mar 2019 21:50:29 +0000 Subject: [PATCH 068/506] Prevent a crash when bad data passed --- src/openrct2/interface/InteractiveConsole.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index fa0ab0761f..2070f84dae 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -417,8 +417,11 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) { console.WriteFormatLine("This command expects the string all or two integer arguments"); } - auto rideSetPrice = RideSetPriceAction(rideId, price, true); - GameActions::Execute(&rideSetPrice); + else + { + auto rideSetPrice = RideSetPriceAction(rideId, price, true); + GameActions::Execute(&rideSetPrice); + } } } } From 68aa5122fac691daeea83a0b695397be6acddb7e Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 18 Mar 2019 22:56:14 +0100 Subject: [PATCH 069/506] Fix #6006: Objects higher than 6 metres are considered trees --- distribution/changelog.txt | 1 + src/openrct2/actions/LandSetHeightAction.hpp | 7 ++++--- src/openrct2/actions/SmallSceneryRemoveAction.hpp | 2 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/object/SmallSceneryObject.cpp | 6 ++++++ src/openrct2/world/SmallScenery.cpp | 4 ++-- src/openrct2/world/SmallScenery.h | 2 ++ 7 files changed, 17 insertions(+), 7 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9c4cf75fec..dfdbf2b9af 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. +- Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8900] Peep tracking is not synchronized. diff --git a/src/openrct2/actions/LandSetHeightAction.hpp b/src/openrct2/actions/LandSetHeightAction.hpp index 535cde1322..ab8eab6f79 100644 --- a/src/openrct2/actions/LandSetHeightAction.hpp +++ b/src/openrct2/actions/LandSetHeightAction.hpp @@ -19,6 +19,7 @@ #include "../windows/Intent.h" #include "../world/Park.h" #include "../world/Scenery.h" +#include "../world/SmallScenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" #include "GameAction.h" @@ -80,7 +81,7 @@ public: if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) { // Check for obstructing large trees - TileElement* tileElement = CheckTallTreeObstructions(); + TileElement* tileElement = CheckTreeObstructions(); if (tileElement != nullptr) { map_obstruction_set_error_text(tileElement); @@ -195,7 +196,7 @@ private: return STR_NONE; } - TileElement* CheckTallTreeObstructions() const + TileElement* CheckTreeObstructions() const { TileElement* tileElement = map_get_first_element_at(_coords.x / 32, _coords.y / 32); do @@ -207,7 +208,7 @@ private: if (_height + 4 < tileElement->base_height) continue; rct_scenery_entry* sceneryEntry = tileElement->AsSmallScenery()->GetEntry(); - if (sceneryEntry->small_scenery.height > 64) + if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_IS_TREE)) { return tileElement; } diff --git a/src/openrct2/actions/SmallSceneryRemoveAction.hpp b/src/openrct2/actions/SmallSceneryRemoveAction.hpp index c4cd06c141..60344bf39a 100644 --- a/src/openrct2/actions/SmallSceneryRemoveAction.hpp +++ b/src/openrct2/actions/SmallSceneryRemoveAction.hpp @@ -82,7 +82,7 @@ public: // Check if allowed to remove item if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) { - if (entry->small_scenery.height > 64) + if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_IS_TREE)) { res->Error = GA_ERROR::NO_CLEARANCE; res->ErrorTitle = STR_CANT_REMOVE_THIS; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index e48d011737..9d5e4b85d4 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 "5" +#define NETWORK_STREAM_VERSION "6" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/object/SmallSceneryObject.cpp b/src/openrct2/object/SmallSceneryObject.cpp index 7d6e12eb40..754d65295a 100644 --- a/src/openrct2/object/SmallSceneryObject.cpp +++ b/src/openrct2/object/SmallSceneryObject.cpp @@ -46,6 +46,11 @@ void SmallSceneryObject::ReadLegacy(IReadObjectContext* context, IStream* stream { _frameOffsets = ReadFrameOffsets(stream); } + // This crude method was used by RCT2. JSON objects have a flag for this property. + if (_legacyType.small_scenery.height > 64) + { + _legacyType.small_scenery.flags |= SMALL_SCENERY_FLAG_IS_TREE; + } GetImageTable().Read(context, stream); @@ -270,6 +275,7 @@ void SmallSceneryObject::ReadJson(IReadObjectContext* context, const json_t* roo { "allowSupportsAbove", SMALL_SCENERY_FLAG_BUILD_DIRECTLY_ONTOP }, { "supportsHavePrimaryColour", SMALL_SCENERY_FLAG_PAINT_SUPPORTS }, { "SMALL_SCENERY_FLAG27", SMALL_SCENERY_FLAG27 }, + { "isTree", SMALL_SCENERY_FLAG_IS_TREE }, }); // Determine shape flags from a shape string diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index 06e4649c55..2958c533ba 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -94,7 +94,7 @@ int32_t map_place_scenery_clear_func(TileElement** tile_element, int32_t x, int3 if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) { - if (scenery->small_scenery.height > 64) + if (scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_IS_TREE)) return 1; } @@ -128,7 +128,7 @@ int32_t map_place_non_scenery_clear_func(TileElement** tile_element, int32_t x, if (gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) { - if (scenery->small_scenery.height > 64) + if (scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_IS_TREE)) return 1; } diff --git a/src/openrct2/world/SmallScenery.h b/src/openrct2/world/SmallScenery.h index 078df1c096..870269d67d 100644 --- a/src/openrct2/world/SmallScenery.h +++ b/src/openrct2/world/SmallScenery.h @@ -44,6 +44,8 @@ enum SMALL_SCENERY_FLAGS SMALL_SCENERY_FLAG_THREE_QUARTERS = (1 << 25), // 0x2000000 SMALL_SCENERY_FLAG_PAINT_SUPPORTS = (1 << 26), // 0x4000000; used for scenery items which are support structures SMALL_SCENERY_FLAG27 = (1 << 27), // 0x8000000 + + SMALL_SCENERY_FLAG_IS_TREE = (1 << 28), // Added by OpenRCT2 }; enum From 4f8548dfea089de84d3d4c85243a10dede0f53ab Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 17 Mar 2019 12:49:55 +0100 Subject: [PATCH 070/506] Allow different default colours per stall --- src/openrct2/object/RideObject.cpp | 3 ++- src/openrct2/ride/Ride.cpp | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 8cae6b6efa..01873360ee 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -550,6 +550,8 @@ void RideObject::ReadJson(IReadObjectContext* context, const json_t* root) _legacyType.shop_item = SHOP_ITEM_NONE; _legacyType.shop_item_secondary = SHOP_ITEM_NONE; + _presetColours = ReadJsonCarColours(json_object_get(properties, "carColours")); + if (IsRideTypeShopOrFacility(_legacyType.ride_type[0])) { // Standard car info for a shop @@ -623,7 +625,6 @@ void RideObject::ReadJson(IReadObjectContext* context, const json_t* root) } auto availableTrackPieces = ObjectJsonHelpers::GetJsonStringArray(json_object_get(properties, "availableTrackPieces")); - _presetColours = ReadJsonCarColours(json_object_get(properties, "carColours")); } _legacyType.flags |= ObjectJsonHelpers::GetFlags( diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9cca7acd08..695ca31e38 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -216,6 +216,7 @@ static void ride_shop_connected(Ride* ride); static void ride_spiral_slide_update(Ride* ride); static void ride_update(Ride* ride); void loc_6DDF9C(Ride* ride, TileElement* tileElement); +static bool ride_is_ride(Ride* ride); Ride* get_ride(int32_t index) { @@ -5898,7 +5899,17 @@ void ride_set_colour_preset(Ride* ride, uint8_t index) { const track_colour_preset_list* colourPresets = &RideColourPresets[ride->type]; TrackColour colours = { COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK }; - if (index < colourPresets->count) + // Stalls save their default colour in the vehicle settings (since they share a common ride type) + if (!ride_is_ride(ride)) + { + auto rideEntry = get_ride_entry(ride->subtype); + if (rideEntry != nullptr && rideEntry->vehicle_preset_list->count > 0) + { + auto list = rideEntry->vehicle_preset_list->list[0]; + colours = { list.main, list.additional_1, list.additional_2 }; + } + } + else if (index < colourPresets->count) { colours = colourPresets->list[index]; } From 59c74ead94c2e969a19b90bf0d3a607dfa9c1aea Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 19 Mar 2019 21:19:50 +0100 Subject: [PATCH 071/506] Add fallback for legacy objects --- src/openrct2/object/RideObject.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 01873360ee..3c18484d57 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -85,6 +85,13 @@ void RideObject::ReadLegacy(IReadObjectContext* context, IStream* stream) _presetColours.list[i] = stream->ReadValue(); } + if (IsRideTypeShopOrFacility(_legacyType.ride_type[0])) + { + // This used to be hard-coded. JSON objects set this themselves. + _presetColours.count = 1; + _presetColours.list[0] = { COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED }; + } + // Read peep loading positions for (int32_t i = 0; i < RCT2_MAX_VEHICLES_PER_RIDE_ENTRY; i++) { From 14c2925ae515bb9d0b283adaae12fa4c28aeb9b6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 19 Mar 2019 22:11:18 +0100 Subject: [PATCH 072/506] Add import code to make Ice Cream Stalls light blue --- src/openrct2/rct2/S6Importer.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index a742b783bc..5e7e8d377d 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -707,6 +707,19 @@ public: dst->track_colour[i].additional = src->track_colour_additional[i]; dst->track_colour[i].supports = src->track_colour_supports[i]; } + if (dst->type == RIDE_TYPE_FOOD_STALL) + { + auto entry = object_entry_get_entry(OBJECT_TYPE_RIDE, dst->subtype); + if (entry != nullptr) + { + char name[DAT_NAME_LENGTH + 1]; + object_entry_get_name_fixed(name, sizeof(name), entry); + if (strncmp(name, "ICECR1 ", DAT_NAME_LENGTH) == 0) + { + dst->track_colour[0].main = COLOUR_LIGHT_BLUE; + } + } + } dst->music = src->music; dst->entrance_style = src->entrance_style; From 8b1330ec57ffd304063ed7bf69b7442c1251a41f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 19 Mar 2019 22:13:02 +0100 Subject: [PATCH 073/506] Add comment [ci skip] --- src/openrct2/rct2/S6Importer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 5e7e8d377d..7da7a67c56 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -707,6 +707,7 @@ public: dst->track_colour[i].additional = src->track_colour_additional[i]; dst->track_colour[i].supports = src->track_colour_supports[i]; } + // This stall was not colourable in RCT2. if (dst->type == RIDE_TYPE_FOOD_STALL) { auto entry = object_entry_get_entry(OBJECT_TYPE_RIDE, dst->subtype); From 79318997bc44b4213f4f08bd20d760df3c4e78d6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 19 Mar 2019 22:21:06 +0100 Subject: [PATCH 074/506] Remove old code for MEDIENTR --- src/openrct2/object/EntranceObject.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/openrct2/object/EntranceObject.cpp b/src/openrct2/object/EntranceObject.cpp index 11bbfb5fd4..592caac883 100644 --- a/src/openrct2/object/EntranceObject.cpp +++ b/src/openrct2/object/EntranceObject.cpp @@ -23,14 +23,6 @@ void EntranceObject::ReadLegacy(IReadObjectContext* context, IStream* stream) GetStringTable().Read(context, stream, OBJ_STRING_ID_NAME); GetImageTable().Read(context, stream); - - // Fix issue #1705: The Medieval entrance from Time Twister has a straight banner, - // but scrolls its text as if it a curved one. - if (String::Equals(GetIdentifier(), "MEDIENTR")) - { - _legacyType.scrolling_mode = 32; - _legacyType.text_height += 1; - } } void EntranceObject::Load() From aa21f0fb1d2b0d7d78edcc39194a30be8583d878 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 19 Mar 2019 22:55:28 +0100 Subject: [PATCH 075/506] Prepare for food/drink stall recolouration --- src/openrct2/object/RideObject.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 3c18484d57..211c84b7d5 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -90,6 +90,12 @@ void RideObject::ReadLegacy(IReadObjectContext* context, IStream* stream) // This used to be hard-coded. JSON objects set this themselves. _presetColours.count = 1; _presetColours.list[0] = { COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED }; + + if (_legacyType.ride_type[0] == RIDE_TYPE_FOOD_STALL || _legacyType.ride_type[0] == RIDE_TYPE_DRINK_STALL) + { + // In RCT2, no food or drink stall could be recoloured. + _legacyType.flags |= RIDE_ENTRY_FLAG_DISABLE_COLOUR_TAB; + } } // Read peep loading positions From 2fec60fb77fb8a49901058fdaa8c287db4b1ab96 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 20 Mar 2019 04:00:28 +0000 Subject: [PATCH 076/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index c2fd5052e2..3f70a44e1a 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -2627,9 +2627,9 @@ STR_5125 :모두 파괴 가능 STR_5126 :무작위 타이틀 음악 STR_5127 :{SMALLFONT}{BLACK}땅을 올리거나 내리지 않고 지형을 편집합니다 STR_5128 :선택 도구 크기 -STR_5129 :{COMMA16}에서 {COMMA16} 사이의 값을 입력하세요 +STR_5129 :{COMMA16}∼{COMMA16} 사이의 값을 입력하세요 STR_5130 :지도 크기 -STR_5131 :지도 크기를 {COMMA16}에서 {COMMA16} 사이의 값으로 입력하세요 +STR_5131 :{COMMA16}∼{COMMA16} 사이의 지도 크기 값을 입력하세요 STR_5132 :모든 놀이기구 수리 STR_5133 :{SMALLFONT}{BLACK}땅 구입 도구 크기 줄이기 STR_5134 :{SMALLFONT}{BLACK}땅 구입 도구 크기 늘이기 @@ -2681,9 +2681,9 @@ STR_5180 :{SMALLFONT}{BLACK}공원 치트를 보여줍니다 STR_5181 :{SMALLFONT}{BLACK}놀이기구 치트를 보여줍니다 STR_5182 :{INT32} STR_5183 :기본 땅 높이 -STR_5184 :기본 땅 높이를 {COMMA16} 사이의 {COMMA16} 사이의 값으로 입력하세요 +STR_5184 :{COMMA16}∼{COMMA16} 사이의 기본 땅 높이 값을 입력하세요 STR_5185 :물 높이 -STR_5186 :물 높이를 {COMMA16}에서 {COMMA16} 사이의 값으로 입력하세요 +STR_5186 :{COMMA16}∼{COMMA16} 사이의 물 높이 값을 입력하세요 STR_5187 :재정 STR_5188 :새 광고 STR_5189 :연구 From 80c57f3804f78fefc6630a6db398575ca64be04f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 20 Mar 2019 13:02:32 +0100 Subject: [PATCH 077/506] Bump objects version to 1.0.10 --- CMakeLists.txt | 4 ++-- OpenRCT2.xcodeproj/project.pbxproj | 2 +- openrct2.proj | 4 ++-- shell.nix | 4 ++-- src/openrct2-android/app/build.gradle | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ad80fb1b4..1da9947a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,8 @@ set(CMAKE_MACOSX_RPATH 1) set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip") set(TITLE_SEQUENCE_SHA1 "1136ef92bfb05cd1cba9831ba6dc4a653d87a246") -set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.9/objects.zip") -set(OBJECTS_SHA1 "be0bcb454505e4f7c56d21d6804f81faf8a0a652") +set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip") +set(OBJECTS_SHA1 "0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 71dc46d782..855c5b8de9 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -3555,7 +3555,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"1.0.9\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; + shellScript = "version=\"1.0.10\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; }; C68B2D471EC790710020651C /* Download Libraries */ = { isa = PBXShellScriptBuildPhase; diff --git a/openrct2.proj b/openrct2.proj index af9d95b558..ed32fda0fd 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -70,8 +70,8 @@ 058b9df80244c03f1633cb06e9f70471a29ebb8e https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip 1136ef92bfb05cd1cba9831ba6dc4a653d87a246 - https://github.com/OpenRCT2/objects/releases/download/v1.0.9/objects.zip - be0bcb454505e4f7c56d21d6804f81faf8a0a652 + https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip + 0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f diff --git a/shell.nix b/shell.nix index 8350bae7c9..28bd1b8844 100644 --- a/shell.nix +++ b/shell.nix @@ -15,8 +15,8 @@ let objects-src = pkgs.fetchFromGitHub { owner = "OpenRCT2"; repo = "objects"; - rev = "v1.0.9"; - sha256 = "442b7da11b2b884559148ab9e7fdf781f50dd50feb69bfa569a78e52205a5709"; + rev = "v1.0.10"; + sha256 = "4f261964f1c01a04b7600d3d082fb4d3d9ec0d543c4eb66a819eb2ad01417aa0"; }; title-sequences-src = pkgs.fetchFromGitHub { diff --git a/src/openrct2-android/app/build.gradle b/src/openrct2-android/app/build.gradle index 30dc262a4d..8085ee78ff 100644 --- a/src/openrct2-android/app/build.gradle +++ b/src/openrct2-android/app/build.gradle @@ -98,7 +98,7 @@ android.applicationVariants.all { variant -> into "$variant.mergeAssets.outputDir/data/title" } download { - src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.9/objects.zip' + src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip' dest new File(buildDir, 'objects.zip') } copy { From 511dd44f6b099008a968ff0940bbd4667ca8b377 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 20 Mar 2019 16:57:22 +0100 Subject: [PATCH 078/506] Bump 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 9d5e4b85d4..7253472937 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 "6" +#define NETWORK_STREAM_VERSION "7" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 320c88df9914ea7fb8bda498bf9baf1bb3363606 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 20 Mar 2019 18:48:01 +0000 Subject: [PATCH 079/506] Make requested changes --- distribution/changelog.txt | 1 + src/openrct2/interface/InteractiveConsole.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9c4cf75fec..012f26fe08 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Feature: [#8919] Allow setting ride price from console. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 2070f84dae..8471897f1a 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -170,7 +170,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) console.WriteFormatLine("rides set excitement "); console.WriteFormatLine("rides set intensity "); console.WriteFormatLine("rides set nausea "); - console.WriteFormatLine("rides set price [type] "); + console.WriteFormatLine("rides set price "); } return 0; } From aeaa45c05b13bbfb7e79ff4a33374a0a0d1bf940 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 20 Mar 2019 20:03:28 +0100 Subject: [PATCH 080/506] Fix #8927: Make cheats menu partially accessible in scenario editor. --- src/openrct2-ui/windows/TopToolbar.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 1d3538cdd3..f21471b4a5 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -721,7 +721,6 @@ static void window_top_toolbar_invalidate(rct_window* w) window_top_toolbar_widgets[WIDX_GUESTS].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_RESEARCH].type = WWT_EMPTY; - window_top_toolbar_widgets[WIDX_CHEATS].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_NEWS].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_NETWORK].type = WWT_EMPTY; @@ -3268,6 +3267,15 @@ static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) dropdown_set_disabled(DDIDX_INVENTIONS_LIST, true); } + if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + { + dropdown_set_disabled(DDIDX_CHEATS, true); + dropdown_set_disabled(DDIDX_OBJECT_SELECTION, true); + dropdown_set_disabled(DDIDX_INVENTIONS_LIST, true); + dropdown_set_disabled(DDIDX_SCENARIO_OPTIONS, true); + dropdown_set_disabled(DDIDX_ENABLE_SANDBOX_MODE, true); + } + if (gCheatsSandboxMode) { dropdown_set_checked(DDIDX_ENABLE_SANDBOX_MODE, true); @@ -3281,7 +3289,10 @@ static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) dropdown_set_checked(DDIDX_DISABLE_SUPPORT_LIMITS, true); } - gDropdownDefaultIndex = DDIDX_CHEATS; + if (!dropdown_is_disabled(DDIDX_CHEATS)) + gDropdownDefaultIndex = DDIDX_CHEATS; + else + gDropdownDefaultIndex = DDIDX_TILE_INSPECTOR; } static void top_toolbar_cheats_menu_dropdown(int16_t dropdownIndex) From 1c570c8eecf056d9101a2bded8766ccacf94c09d Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 20 Mar 2019 20:05:25 +0100 Subject: [PATCH 081/506] Move some ride functions to struct methods --- src/openrct2-ui/windows/Ride.cpp | 10 +- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2/Cheats.cpp | 2 +- src/openrct2/actions/RideDemolishAction.hpp | 2 +- src/openrct2/actions/RideSetSetting.hpp | 2 +- .../actions/RideSetVehiclesAction.hpp | 2 +- src/openrct2/actions/TrackPlaceAction.hpp | 2 +- src/openrct2/actions/TrackRemoveAction.hpp | 2 +- src/openrct2/management/Finance.cpp | 2 +- src/openrct2/ride/Ride.cpp | 114 +++++++++--------- src/openrct2/ride/Ride.h | 20 +-- src/openrct2/ride/Track.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 6 +- src/openrct2/ride/Vehicle.cpp | 6 +- 14 files changed, 86 insertions(+), 88 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 684ff73ff7..a69ac2a909 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2871,20 +2871,20 @@ static void window_ride_vehicle_mousedown(rct_window* w, rct_widgetindex widgetI break; case WIDX_VEHICLE_TRAINS_INCREASE: if (ride->num_vehicles < 32) - ride_set_num_vehicles(ride, ride->num_vehicles + 1); + ride->SetNumVehicles(ride->num_vehicles + 1); break; case WIDX_VEHICLE_TRAINS_DECREASE: if (ride->num_vehicles > 1) - ride_set_num_vehicles(ride, ride->num_vehicles - 1); + ride->SetNumVehicles(ride->num_vehicles - 1); break; case WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE: if (ride->num_cars_per_train < 255) - ride_set_num_cars_per_vehicle(ride, ride->num_cars_per_train + 1); + ride->SetNumCarsPerVehicle(ride->num_cars_per_train + 1); break; case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE: rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); if (ride->num_cars_per_train > rideEntry->zero_cars + 1) - ride_set_num_cars_per_vehicle(ride, ride->num_cars_per_train - 1); + ride->SetNumCarsPerVehicle(ride->num_cars_per_train - 1); break; } } @@ -2907,7 +2907,7 @@ static void window_ride_vehicle_dropdown(rct_window* w, rct_widgetindex widgetIn if (ride != nullptr) { auto newRideType = VehicleDropdownData[dropdownIndex].subtype_id; - ride_set_ride_entry(ride, newRideType); + ride->SetRideEntry(newRideType); } } break; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 0e7ffa05d1..0ae1630025 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -625,7 +625,7 @@ static void window_ride_construction_close(rct_window* w) } } - ride_set_to_default_inspection_interval(ride); + ride->SetToDefaultInspectionInterval(); auto intent = Intent(WC_RIDE); intent.putExtra(INTENT_EXTRA_RIDE_ID, ride->id); context_open_intent(&intent); diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index f1d08d99dc..ba69293988 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -173,7 +173,7 @@ static void cheat_renew_rides() FOR_ALL_RIDES (i, ride) { - ride_renew(ride); + ride->Renew(); } window_invalidate_by_class(WC_RIDE); } diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 845d6ff2b7..e74fef9162 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -350,7 +350,7 @@ private: res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; res->Cost = GetRefurbishPrice(ride); - ride_renew(ride); + ride->Renew(); ride->lifecycle_flags &= ~RIDE_LIFECYCLE_EVER_BEEN_OPENED; ride->last_crash_type = RIDE_CRASH_TYPE_NONE; diff --git a/src/openrct2/actions/RideSetSetting.hpp b/src/openrct2/actions/RideSetSetting.hpp index 6478bde798..6efead8af8 100644 --- a/src/openrct2/actions/RideSetSetting.hpp +++ b/src/openrct2/actions/RideSetSetting.hpp @@ -186,7 +186,7 @@ public: ride_remove_peeps(ride); ride->mode = _value; - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); break; case RideSetSetting::Departure: ride->depart_flags = _value; diff --git a/src/openrct2/actions/RideSetVehiclesAction.hpp b/src/openrct2/actions/RideSetVehiclesAction.hpp index 5af7cb2309..04a8e3b04a 100644 --- a/src/openrct2/actions/RideSetVehiclesAction.hpp +++ b/src/openrct2/actions/RideSetVehiclesAction.hpp @@ -204,7 +204,7 @@ public: } ride->num_circuits = 1; - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); auto res = std::make_unique(); if (ride->overall_view.xy != RCT_XY8_UNDEFINED) diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index 745aea9d98..bd9c83944d 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -682,7 +682,7 @@ public: mapLoc.x, mapLoc.y, baseZ, _origin.direction, _rideIndex, GAME_COMMAND_FLAG_APPLY); } sub_6CB945(ride); - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); } if (rideTypeFlags & RIDE_TYPE_FLAG_TRACK_MUST_BE_ON_WATER) diff --git a/src/openrct2/actions/TrackRemoveAction.hpp b/src/openrct2/actions/TrackRemoveAction.hpp index d78d81cf6c..5ad20a6b4b 100644 --- a/src/openrct2/actions/TrackRemoveAction.hpp +++ b/src/openrct2/actions/TrackRemoveAction.hpp @@ -450,7 +450,7 @@ public: sub_6CB945(ride); if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); } } diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index e03141cce1..d0d541a048 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -192,7 +192,7 @@ void finance_pay_ride_upkeep() { if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED)) { - ride_renew(ride); + ride->Renew(); } if (ride->status != RIDE_STATUS_CLOSED && !(gParkFlags & PARK_FLAGS_NO_MONEY)) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 695ca31e38..0236682626 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -216,7 +216,6 @@ static void ride_shop_connected(Ride* ride); static void ride_spiral_slide_update(Ride* ride); static void ride_update(Ride* ride); void loc_6DDF9C(Ride* ride, TileElement* tileElement); -static bool ride_is_ride(Ride* ride); Ride* get_ride(int32_t index) { @@ -4973,7 +4972,7 @@ static void ride_create_vehicles_find_first_block(Ride* ride, CoordsXYE* outXYEl */ static bool ride_create_vehicles(Ride* ride, CoordsXYE* element, int32_t isApplying) { - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); if (ride->subtype == RIDE_ENTRY_INDEX_NULL) { return true; @@ -5900,7 +5899,7 @@ void ride_set_colour_preset(Ride* ride, uint8_t index) const track_colour_preset_list* colourPresets = &RideColourPresets[ride->type]; TrackColour colours = { COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK }; // Stalls save their default colour in the vehicle settings (since they share a common ride type) - if (!ride_is_ride(ride)) + if (!ride->IsRide()) { auto rideEntry = get_ride_entry(ride->subtype); if (rideEntry != nullptr && rideEntry->vehicle_preset_list->count > 0) @@ -6980,12 +6979,12 @@ static int32_t ride_get_track_length(Ride* ride) * * rct2: 0x006DD57D */ -void ride_update_max_vehicles(Ride* ride) +void Ride::UpdateMaxVehicles() { - if (ride->subtype == RIDE_ENTRY_INDEX_NULL) + if (subtype == RIDE_ENTRY_INDEX_NULL) return; - rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); + rct_ride_entry* rideEntry = get_ride_entry(subtype); if (rideEntry == nullptr) { return; @@ -6997,16 +6996,16 @@ void ride_update_max_vehicles(Ride* ride) if (rideEntry->cars_per_flat_ride == 0xFF) { int32_t trainLength; - ride->num_cars_per_train = std::max(rideEntry->min_cars_in_train, ride->num_cars_per_train); - ride->min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4); + num_cars_per_train = std::max(rideEntry->min_cars_in_train, num_cars_per_train); + min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4); // Calculate maximum train length based on smallest station length - int32_t stationLength = ride_get_smallest_station_length(ride); + int32_t stationLength = ride_get_smallest_station_length(this); if (stationLength == -1) return; stationLength = (stationLength * 0x44180) - 0x16B2A; - int32_t maxMass = RideData5[ride->type].max_mass << 8; + int32_t maxMass = RideData5[type].max_mass << 8; int32_t maxCarsPerTrain = 1; for (int32_t numCars = rideEntry->max_cars_in_train; numCars > 0; numCars--) { @@ -7014,7 +7013,7 @@ void ride_update_max_vehicles(Ride* ride) int32_t totalMass = 0; for (int32_t i = 0; i < numCars; i++) { - vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, numCars, i)]; + vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(subtype, numCars, i)]; trainLength += vehicleEntry->spacing; totalMass += vehicleEntry->car_mass; } @@ -7025,19 +7024,19 @@ void ride_update_max_vehicles(Ride* ride) break; } } - int32_t newCarsPerTrain = std::max(ride->proposed_num_cars_per_train, rideEntry->min_cars_in_train); + int32_t newCarsPerTrain = std::max(proposed_num_cars_per_train, rideEntry->min_cars_in_train); maxCarsPerTrain = std::max(maxCarsPerTrain, (int32_t)rideEntry->min_cars_in_train); if (!gCheatsDisableTrainLengthLimit) { newCarsPerTrain = std::min(maxCarsPerTrain, newCarsPerTrain); } - ride->min_max_cars_per_train = maxCarsPerTrain | (rideEntry->min_cars_in_train << 4); + min_max_cars_per_train = maxCarsPerTrain | (rideEntry->min_cars_in_train << 4); - switch (ride->mode) + switch (mode) { case RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED: case RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED: - maxNumTrains = std::clamp(ride->num_stations + ride->num_block_brakes - 1, 1, 31); + maxNumTrains = std::clamp(num_stations + num_block_brakes - 1, 1, 31); break; case RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE: case RIDE_MODE_POWERED_LAUNCH_PASSTROUGH: @@ -7051,7 +7050,7 @@ void ride_update_max_vehicles(Ride* ride) trainLength = 0; for (int32_t i = 0; i < newCarsPerTrain; i++) { - vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, newCarsPerTrain, i)]; + vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(subtype, newCarsPerTrain, i)]; trainLength += vehicleEntry->spacing; } @@ -7066,31 +7065,30 @@ void ride_update_max_vehicles(Ride* ride) totalLength += trainLength; } while (totalLength <= stationLength); - if ((ride->mode != RIDE_MODE_STATION_TO_STATION && ride->mode != RIDE_MODE_CONTINUOUS_CIRCUIT) - || !(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_MORE_VEHICLES_THAN_STATION_FITS)) + if ((mode != RIDE_MODE_STATION_TO_STATION && mode != RIDE_MODE_CONTINUOUS_CIRCUIT) + || !(RideData4[type].flags & RIDE_TYPE_FLAG4_ALLOW_MORE_VEHICLES_THAN_STATION_FITS)) { maxNumTrains = std::min(maxNumTrains, 31); } else { - vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, newCarsPerTrain, 0)]; - int32_t speed = vehicleEntry->powered_max_speed; + vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(subtype, newCarsPerTrain, 0)]; + int32_t poweredMaxSpeed = vehicleEntry->powered_max_speed; int32_t totalSpacing = 0; for (int32_t i = 0; i < newCarsPerTrain; i++) { - vehicleEntry = &rideEntry - ->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, newCarsPerTrain, i)]; + vehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(subtype, newCarsPerTrain, i)]; totalSpacing += vehicleEntry->spacing; } totalSpacing >>= 13; - int32_t trackLength = ride_get_track_length(ride) / 4; - if (speed > 10) + int32_t trackLength = ride_get_track_length(this) / 4; + if (poweredMaxSpeed > 10) trackLength = (trackLength * 3) / 4; - if (speed > 25) + if (poweredMaxSpeed > 25) trackLength = (trackLength * 3) / 4; - if (speed > 40) + if (poweredMaxSpeed > 40) trackLength = (trackLength * 3) / 4; maxNumTrains = 0; @@ -7103,14 +7101,14 @@ void ride_update_max_vehicles(Ride* ride) } break; } - ride->max_trains = maxNumTrains; + max_trains = maxNumTrains; - numCarsPerTrain = std::min(ride->proposed_num_cars_per_train, (uint8_t)newCarsPerTrain); + numCarsPerTrain = std::min(proposed_num_cars_per_train, (uint8_t)newCarsPerTrain); } else { - ride->max_trains = rideEntry->cars_per_flat_ride; - ride->min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4); + max_trains = rideEntry->cars_per_flat_ride; + min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4); numCarsPerTrain = rideEntry->max_cars_in_train; maxNumTrains = rideEntry->cars_per_flat_ride; } @@ -7119,33 +7117,33 @@ void ride_update_max_vehicles(Ride* ride) { maxNumTrains = 31; } - numVehicles = std::min(ride->proposed_num_vehicles, (uint8_t)maxNumTrains); + numVehicles = std::min(proposed_num_vehicles, (uint8_t)maxNumTrains); // Refresh new current num vehicles / num cars per vehicle - if (numVehicles != ride->num_vehicles || numCarsPerTrain != ride->num_cars_per_train) + if (numVehicles != num_vehicles || numCarsPerTrain != num_cars_per_train) { - ride->num_cars_per_train = numCarsPerTrain; - ride->num_vehicles = numVehicles; - window_invalidate_by_number(WC_RIDE, ride->id); + num_cars_per_train = numCarsPerTrain; + num_vehicles = numVehicles; + window_invalidate_by_number(WC_RIDE, id); } } -void ride_set_ride_entry(Ride* ride, int32_t rideEntry) +void Ride::SetRideEntry(int32_t rideEntry) { auto colour = ride_get_unused_preset_vehicle_colour(rideEntry); - auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::RideEntry, rideEntry, colour); + auto rideSetVehicleAction = RideSetVehicleAction(id, RideSetVehicleType::RideEntry, rideEntry, colour); GameActions::Execute(&rideSetVehicleAction); } -void ride_set_num_vehicles(Ride* ride, int32_t numVehicles) +void Ride::SetNumVehicles(int32_t numVehicles) { - auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, numVehicles); + auto rideSetVehicleAction = RideSetVehicleAction(id, RideSetVehicleType::NumTrains, numVehicles); GameActions::Execute(&rideSetVehicleAction); } -void ride_set_num_cars_per_vehicle(Ride* ride, int32_t numCarsPerVehicle) +void Ride::SetNumCarsPerVehicle(int32_t numCarsPerVehicle) { - auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::NumCarsPerTrain, numCarsPerVehicle); + auto rideSetVehicleAction = RideSetVehicleAction(id, RideSetVehicleType::NumCarsPerTrain, numCarsPerVehicle); GameActions::Execute(&rideSetVehicleAction); } @@ -7377,14 +7375,14 @@ void sub_6CB945(Ride* ride) } } -void ride_set_to_default_inspection_interval(Ride* ride) +void Ride::SetToDefaultInspectionInterval() { uint8_t defaultInspectionInterval = gConfigGeneral.default_inspection_interval; - if (ride->inspection_interval != defaultInspectionInterval) + if (inspection_interval != defaultInspectionInterval) { if (defaultInspectionInterval <= RIDE_INSPECTION_NEVER) { - set_operating_setting(ride->id, RideSetSetting::InspectionInterval, defaultInspectionInterval); + set_operating_setting(id, RideSetSetting::InspectionInterval, defaultInspectionInterval); } } } @@ -7393,9 +7391,9 @@ void ride_set_to_default_inspection_interval(Ride* ride) * * rct2: 0x006B752C */ -void ride_crash(Ride* ride, uint8_t vehicleIndex) +void Ride::Crash(uint8_t vehicleIndex) { - rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[vehicleIndex]); + rct_vehicle* vehicle = GET_VEHICLE(vehicles[vehicleIndex]); if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)) { @@ -7411,11 +7409,11 @@ void ride_crash(Ride* ride, uint8_t vehicleIndex) } } - set_format_arg(0, rct_string_id, ride->name); - set_format_arg(2, uint32_t, ride->name_arguments); + set_format_arg(0, rct_string_id, name); + set_format_arg(2, uint32_t, name_arguments); if (gConfigNotifications.ride_crashed) { - news_item_add_to_queue(NEWS_ITEM_RIDE, STR_RIDE_HAS_CRASHED, ride->id); + news_item_add_to_queue(NEWS_ITEM_RIDE, STR_RIDE_HAS_CRASHED, id); } } @@ -7508,22 +7506,22 @@ rct_vehicle* ride_get_broken_vehicle(Ride* ride) * * rct2: 0x006D235B */ -void ride_delete(Ride* ride) +void Ride::Delete() { - user_string_free(ride->name); - ride->type = RIDE_TYPE_NULL; + user_string_free(name); + type = RIDE_TYPE_NULL; } -void ride_renew(Ride* ride) +void Ride::Renew() { // Set build date to current date (so the ride is brand new) - ride->build_date = gDateMonthsElapsed; - ride->reliability = RIDE_INITIAL_RELIABILITY; + build_date = gDateMonthsElapsed; + reliability = RIDE_INITIAL_RELIABILITY; } -static bool ride_is_ride(Ride* ride) +bool Ride::IsRide() const { - switch (ride->type) + switch (type) { case RIDE_TYPE_FOOD_STALL: case RIDE_TYPE_1D: @@ -7545,7 +7543,7 @@ money16 ride_get_price(Ride* ride) { if (gParkFlags & PARK_FLAGS_NO_MONEY) return 0; - if (ride_is_ride(ride)) + if (ride->IsRide()) { if (!park_ride_prices_unlocked()) { diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 2836ee648d..52da75a93a 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -354,6 +354,16 @@ struct Ride RideStation stations[MAX_STATIONS]; bool CanBreakDown() const; + bool IsRide() const; + void Renew(); + void Delete(); + void Crash(uint8_t vehicleIndex); + void SetToDefaultInspectionInterval(); + void SetRideEntry(int32_t rideEntry); + + void SetNumVehicles(int32_t numVehicles); + void SetNumCarsPerVehicle(int32_t numCarsPerVehicle); + void UpdateMaxVehicles(); }; #pragma pack(push, 1) @@ -1129,14 +1139,9 @@ void ride_fix_breakdown(Ride* ride, int32_t reliabilityIncreaseFactor); void ride_entry_get_train_layout(int32_t rideEntryIndex, int32_t numCarsPerTrain, uint8_t* trainLayout); uint8_t ride_entry_get_vehicle_at_position(int32_t rideEntryIndex, int32_t numCarsPerTrain, int32_t position); -void ride_update_max_vehicles(Ride* ride); void ride_update_vehicle_colours(Ride* ride); uint64_t ride_entry_get_supported_track_pieces(const rct_ride_entry* rideEntry); -void ride_set_ride_entry(Ride* ride, int32_t rideEntry); -void ride_set_num_vehicles(Ride* ride, int32_t numVehicles); -void ride_set_num_cars_per_vehicle(Ride* ride, int32_t numCarsPerVehicle); - enum class RideSetSetting : uint8_t; money32 set_operating_setting(ride_id_t rideId, RideSetSetting setting, uint8_t value); money32 set_operating_setting_nested(ride_id_t rideId, RideSetSetting setting, uint8_t value, uint8_t flags); @@ -1147,10 +1152,7 @@ void game_command_set_ride_vehicles( void game_command_place_ride_entrance_or_exit( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void ride_set_to_default_inspection_interval(Ride* ride); - void sub_6CB945(Ride* ride); -void ride_crash(Ride* ride, uint8_t vehicleIndex); void sub_6C94D8(); @@ -1167,8 +1169,6 @@ rct_vehicle* ride_get_broken_vehicle(Ride* ride); void window_ride_construction_do_station_check(); void window_ride_construction_do_entrance_exit_check(); -void ride_delete(Ride* ride); -void ride_renew(Ride* ride); money16 ride_get_price(Ride* ride); TileElement* get_station_platform(int32_t x, int32_t y, int32_t z, int32_t z_tolerance); diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index 74ea224b81..c0fa4d328c 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -1178,7 +1178,7 @@ static money32 track_remove( sub_6CB945(ride); if (!(flags & GAME_COMMAND_FLAG_GHOST)) { - ride_update_max_vehicles(ride); + ride->UpdateMaxVehicles(); } } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 74b2ea2ae2..ba3d69aa1f 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1662,7 +1662,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in if (_trackDesignPlaceOperation == PTD_OPERATION_CLEAR_OUTLINES) { sub_6CB945(ride); - ride_delete(ride); + ride->Delete(); } return true; } @@ -1995,7 +1995,7 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags num_circuits = 1; } set_operating_setting_nested(ride->id, RideSetSetting::NumCircuits, num_circuits, flags); - ride_set_to_default_inspection_interval(ride); + ride->SetToDefaultInspectionInterval(); ride->lifecycle_flags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN; ride->colour_scheme_type = td6->version_and_colour_scheme & 3; @@ -2300,7 +2300,7 @@ void track_design_draw_preview(rct_track_td6* td6, uint8_t* pixels) dpi.bits += TRACK_PREVIEW_IMAGE_SIZE; } - ride_delete(ride); + ride->Delete(); track_design_preview_restore_map(mapBackup); } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 18637c61e9..00a449b979 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3532,7 +3532,7 @@ static void vehicle_update_collision_setup(rct_vehicle* vehicle) return; } - ride_crash(ride, trainIndex); + ride->Crash(trainIndex); if (ride->status != RIDE_STATUS_CLOSED) { @@ -5270,7 +5270,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) return; } - ride_crash(ride, trainIndex); + ride->Crash(trainIndex); if (ride->status != RIDE_STATUS_CLOSED) { @@ -5324,7 +5324,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) return; } - ride_crash(ride, trainIndex); + ride->Crash(trainIndex); if (ride->status != RIDE_STATUS_CLOSED) { From f4602d0a34d9334b3f42e8243364827bce685ef3 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 20 Mar 2019 20:58:08 +0100 Subject: [PATCH 082/506] Use SCREEN_FLAGS_EDITOR when appropriate. --- src/openrct2-ui/input/KeyboardShortcut.cpp | 12 ++++++------ src/openrct2-ui/windows/TopToolbar.cpp | 4 ++-- src/openrct2/GameState.cpp | 2 +- src/openrct2/interface/Window.cpp | 2 +- src/openrct2/peep/Peep.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/openrct2-ui/input/KeyboardShortcut.cpp b/src/openrct2-ui/input/KeyboardShortcut.cpp index e2e3818c01..faebe827b9 100644 --- a/src/openrct2-ui/input/KeyboardShortcut.cpp +++ b/src/openrct2-ui/input/KeyboardShortcut.cpp @@ -445,7 +445,7 @@ static void shortcut_show_research_information() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { context_open_window_view(WV_RIDE_RESEARCH); } @@ -456,7 +456,7 @@ static void shortcut_show_rides_list() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { context_open_window(WC_RIDE_LIST); } @@ -467,7 +467,7 @@ static void shortcut_show_park_information() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { context_open_window(WC_PARK_INFORMATION); } @@ -478,7 +478,7 @@ static void shortcut_show_guest_list() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { context_open_window(WC_GUEST_LIST); } @@ -489,7 +489,7 @@ static void shortcut_show_staff_list() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { context_open_window(WC_STAFF_LIST); } @@ -500,7 +500,7 @@ static void shortcut_show_recent_messages() if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) return; - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) context_open_window(WC_RECENT_NEWS); } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index f21471b4a5..178485cb36 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -712,7 +712,7 @@ static void window_top_toolbar_invalidate(rct_window* w) window_top_toolbar_widgets[WIDX_CHAT].type = WWT_EMPTY; } - if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + if (gScreenFlags & SCREEN_FLAGS_EDITOR) { window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_EMPTY; window_top_toolbar_widgets[WIDX_RIDES].type = WWT_EMPTY; @@ -3267,7 +3267,7 @@ static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) dropdown_set_disabled(DDIDX_INVENTIONS_LIST, true); } - if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + if (gScreenFlags & SCREEN_FLAGS_EDITOR) { dropdown_set_disabled(DDIDX_CHEATS, true); dropdown_set_disabled(DDIDX_OBJECT_SELECTION, true); diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index ef8c596324..a48456911d 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -262,7 +262,7 @@ void GameState::UpdateLogic() sprite_misc_update_all(); ride_update_all(); - if (!(gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { _park->Update(_date); } diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 35a8676e30..b294806ba8 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -1662,7 +1662,7 @@ void window_relocate_windows(int32_t width, int32_t height) */ void window_resize_gui(int32_t width, int32_t height) { - if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + if (gScreenFlags & SCREEN_FLAGS_EDITOR) { window_resize_gui_scenario_editor(width, height); return; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 3bb84e0d80..498c4e5c01 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -435,7 +435,7 @@ void peep_update_all() uint16_t spriteIndex; Peep* peep; - if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + if (gScreenFlags & SCREEN_FLAGS_EDITOR) return; spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; From 3d0925b0da1119a52204b57151221c2ee5a1459b Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:08:21 +0100 Subject: [PATCH 083/506] Add actions to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 110 ++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 855c5b8de9..83c9978d5e 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -44,6 +44,33 @@ 2AAFD7FE220DD374002461A4 /* PauseToggleAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AAFD7FD220DD374002461A4 /* PauseToggleAction.hpp */; }; 2AAFD800220DD3D2002461A4 /* LandSetHeightAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AAFD7FF220DD3D2002461A4 /* LandSetHeightAction.hpp */; }; 2ACBAB172226850A0034FB91 /* RideSetSetting.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ACBAB162226850A0034FB91 /* RideSetSetting.hpp */; }; + 2ADE2F062244187B002598AF /* SurfaceSetStyleAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEB22441878002598AF /* SurfaceSetStyleAction.hpp */; }; + 2ADE2F072244187B002598AF /* MazeSetTrackAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEC22441878002598AF /* MazeSetTrackAction.hpp */; }; + 2ADE2F082244187B002598AF /* ClearAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EED22441878002598AF /* ClearAction.hpp */; }; + 2ADE2F092244187B002598AF /* SignSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEE22441878002598AF /* SignSetNameAction.hpp */; }; + 2ADE2F0A2244187B002598AF /* ParkSetResearchFundingAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEF22441878002598AF /* ParkSetResearchFundingAction.hpp */; }; + 2ADE2F0B2244187B002598AF /* RideSetColourScheme.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF022441878002598AF /* RideSetColourScheme.hpp */; }; + 2ADE2F0C2244187B002598AF /* SmallSceneryRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF122441878002598AF /* SmallSceneryRemoveAction.hpp */; }; + 2ADE2F0D2244187B002598AF /* LargeSceneryRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF222441879002598AF /* LargeSceneryRemoveAction.hpp */; }; + 2ADE2F0E2244187B002598AF /* StaffHireNewAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF322441879002598AF /* StaffHireNewAction.hpp */; }; + 2ADE2F0F2244187B002598AF /* PlacePeepSpawnAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF422441879002598AF /* PlacePeepSpawnAction.hpp */; }; + 2ADE2F102244187B002598AF /* TrackSetBrakeSpeedAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF522441879002598AF /* TrackSetBrakeSpeedAction.hpp */; }; + 2ADE2F112244187B002598AF /* GuestSetFlagsAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF622441879002598AF /* GuestSetFlagsAction.hpp */; }; + 2ADE2F122244187B002598AF /* ParkSetLoanAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF722441879002598AF /* ParkSetLoanAction.hpp */; }; + 2ADE2F132244187B002598AF /* GuestSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF822441879002598AF /* GuestSetNameAction.hpp */; }; + 2ADE2F142244187B002598AF /* FootpathRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EF922441879002598AF /* FootpathRemoveAction.hpp */; }; + 2ADE2F152244187B002598AF /* StaffSetPatrolAreaAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFA22441879002598AF /* StaffSetPatrolAreaAction.hpp */; }; + 2ADE2F162244187B002598AF /* ParkSetParameterAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFB22441879002598AF /* ParkSetParameterAction.hpp */; }; + 2ADE2F172244187B002598AF /* RideDemolishAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFC2244187A002598AF /* RideDemolishAction.hpp */; }; + 2ADE2F182244187B002598AF /* StaffSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFD2244187A002598AF /* StaffSetNameAction.hpp */; }; + 2ADE2F192244187B002598AF /* ParkMarketingAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFE2244187A002598AF /* ParkMarketingAction.hpp */; }; + 2ADE2F1A2244187B002598AF /* ClimateSetAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EFF2244187A002598AF /* ClimateSetAction.hpp */; }; + 2ADE2F1B2244187B002598AF /* WallRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F002244187A002598AF /* WallRemoveAction.hpp */; }; + 2ADE2F1C2244187B002598AF /* ParkSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F012244187A002598AF /* ParkSetNameAction.hpp */; }; + 2ADE2F1D2244187B002598AF /* StaffSetColourAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F022244187A002598AF /* StaffSetColourAction.hpp */; }; + 2ADE2F1E2244187B002598AF /* RideSetName.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F032244187A002598AF /* RideSetName.hpp */; }; + 2ADE2F1F2244187B002598AF /* BannerSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */; }; + 2ADE2F202244187B002598AF /* StaffFireAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F052244187B002598AF /* StaffFireAction.hpp */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -655,6 +682,33 @@ 2AAFD7FD220DD374002461A4 /* PauseToggleAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PauseToggleAction.hpp; sourceTree = ""; }; 2AAFD7FF220DD3D2002461A4 /* LandSetHeightAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandSetHeightAction.hpp; sourceTree = ""; }; 2ACBAB162226850A0034FB91 /* RideSetSetting.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetSetting.hpp; sourceTree = ""; }; + 2ADE2EEB22441878002598AF /* SurfaceSetStyleAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SurfaceSetStyleAction.hpp; sourceTree = ""; }; + 2ADE2EEC22441878002598AF /* MazeSetTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MazeSetTrackAction.hpp; sourceTree = ""; }; + 2ADE2EED22441878002598AF /* ClearAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClearAction.hpp; sourceTree = ""; }; + 2ADE2EEE22441878002598AF /* SignSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SignSetNameAction.hpp; sourceTree = ""; }; + 2ADE2EEF22441878002598AF /* ParkSetResearchFundingAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkSetResearchFundingAction.hpp; sourceTree = ""; }; + 2ADE2EF022441878002598AF /* RideSetColourScheme.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetColourScheme.hpp; sourceTree = ""; }; + 2ADE2EF122441878002598AF /* SmallSceneryRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SmallSceneryRemoveAction.hpp; sourceTree = ""; }; + 2ADE2EF222441879002598AF /* LargeSceneryRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LargeSceneryRemoveAction.hpp; sourceTree = ""; }; + 2ADE2EF322441879002598AF /* StaffHireNewAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffHireNewAction.hpp; sourceTree = ""; }; + 2ADE2EF422441879002598AF /* PlacePeepSpawnAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PlacePeepSpawnAction.hpp; sourceTree = ""; }; + 2ADE2EF522441879002598AF /* TrackSetBrakeSpeedAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrackSetBrakeSpeedAction.hpp; sourceTree = ""; }; + 2ADE2EF622441879002598AF /* GuestSetFlagsAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GuestSetFlagsAction.hpp; sourceTree = ""; }; + 2ADE2EF722441879002598AF /* ParkSetLoanAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkSetLoanAction.hpp; sourceTree = ""; }; + 2ADE2EF822441879002598AF /* GuestSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GuestSetNameAction.hpp; sourceTree = ""; }; + 2ADE2EF922441879002598AF /* FootpathRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathRemoveAction.hpp; sourceTree = ""; }; + 2ADE2EFA22441879002598AF /* StaffSetPatrolAreaAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffSetPatrolAreaAction.hpp; sourceTree = ""; }; + 2ADE2EFB22441879002598AF /* ParkSetParameterAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkSetParameterAction.hpp; sourceTree = ""; }; + 2ADE2EFC2244187A002598AF /* RideDemolishAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideDemolishAction.hpp; sourceTree = ""; }; + 2ADE2EFD2244187A002598AF /* StaffSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffSetNameAction.hpp; sourceTree = ""; }; + 2ADE2EFE2244187A002598AF /* ParkMarketingAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkMarketingAction.hpp; sourceTree = ""; }; + 2ADE2EFF2244187A002598AF /* ClimateSetAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClimateSetAction.hpp; sourceTree = ""; }; + 2ADE2F002244187A002598AF /* WallRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WallRemoveAction.hpp; sourceTree = ""; }; + 2ADE2F012244187A002598AF /* ParkSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkSetNameAction.hpp; sourceTree = ""; }; + 2ADE2F022244187A002598AF /* StaffSetColourAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffSetColourAction.hpp; sourceTree = ""; }; + 2ADE2F032244187A002598AF /* RideSetName.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetName.hpp; sourceTree = ""; }; + 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BannerSetNameAction.hpp; sourceTree = ""; }; + 2ADE2F052244187B002598AF /* StaffFireAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffFireAction.hpp; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -1303,11 +1357,11 @@ C6E96E331E0408A80076A04F /* zip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = ""; }; C6E96E341E0408A80076A04F /* zipconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zipconf.h; sourceTree = ""; }; C6E96E351E0408B40076A04F /* libzip.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libzip.dylib; sourceTree = ""; }; - C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceFromTrackAction.hpp; sourceTree = ""; }; C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandRaiseAction.hpp; sourceTree = ""; }; C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandLowerAction.hpp; sourceTree = ""; }; C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterLowerAction.hpp; sourceTree = ""; }; C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterRaiseAction.hpp; sourceTree = ""; }; + C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceFromTrackAction.hpp; sourceTree = ""; }; D41B73EE1C2101890080A7B9 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/macos/Assets.xcassets; sourceTree = SOURCE_ROOT; }; @@ -2039,6 +2093,33 @@ C6352B871F477032006CCEE3 /* actions */ = { isa = PBXGroup; children = ( + 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */, + 2ADE2EED22441878002598AF /* ClearAction.hpp */, + 2ADE2EFF2244187A002598AF /* ClimateSetAction.hpp */, + 2ADE2EF922441879002598AF /* FootpathRemoveAction.hpp */, + 2ADE2EF622441879002598AF /* GuestSetFlagsAction.hpp */, + 2ADE2EF822441879002598AF /* GuestSetNameAction.hpp */, + 2ADE2EF222441879002598AF /* LargeSceneryRemoveAction.hpp */, + 2ADE2EEC22441878002598AF /* MazeSetTrackAction.hpp */, + 2ADE2EFE2244187A002598AF /* ParkMarketingAction.hpp */, + 2ADE2EF722441879002598AF /* ParkSetLoanAction.hpp */, + 2ADE2F012244187A002598AF /* ParkSetNameAction.hpp */, + 2ADE2EFB22441879002598AF /* ParkSetParameterAction.hpp */, + 2ADE2EEF22441878002598AF /* ParkSetResearchFundingAction.hpp */, + 2ADE2EF422441879002598AF /* PlacePeepSpawnAction.hpp */, + 2ADE2EFC2244187A002598AF /* RideDemolishAction.hpp */, + 2ADE2EF022441878002598AF /* RideSetColourScheme.hpp */, + 2ADE2F032244187A002598AF /* RideSetName.hpp */, + 2ADE2EEE22441878002598AF /* SignSetNameAction.hpp */, + 2ADE2EF122441878002598AF /* SmallSceneryRemoveAction.hpp */, + 2ADE2F052244187B002598AF /* StaffFireAction.hpp */, + 2ADE2EF322441879002598AF /* StaffHireNewAction.hpp */, + 2ADE2F022244187A002598AF /* StaffSetColourAction.hpp */, + 2ADE2EFD2244187A002598AF /* StaffSetNameAction.hpp */, + 2ADE2EFA22441879002598AF /* StaffSetPatrolAreaAction.hpp */, + 2ADE2EEB22441878002598AF /* SurfaceSetStyleAction.hpp */, + 2ADE2EF522441879002598AF /* TrackSetBrakeSpeedAction.hpp */, + 2ADE2F002244187A002598AF /* WallRemoveAction.hpp */, C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */, C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */, C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */, @@ -3358,48 +3439,75 @@ buildActionMask = 2147483647; files = ( 2A43D2C12225B91A00E8F73B /* RideEntranceExitRemoveAction.hpp in Headers */, + 2ADE2F172244187B002598AF /* RideDemolishAction.hpp in Headers */, C67B28172002D67A00109C93 /* Viewport.h in Headers */, 939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */, 9308DA04209908090079EE96 /* TileElement.h in Headers */, + 2ADE2F062244187B002598AF /* SurfaceSetStyleAction.hpp in Headers */, C67B28152002D67A00109C93 /* Widget.h in Headers */, + 2ADE2F1A2244187B002598AF /* ClimateSetAction.hpp in Headers */, + 2ADE2F1B2244187B002598AF /* WallRemoveAction.hpp in Headers */, + 2ADE2F202244187B002598AF /* StaffFireAction.hpp in Headers */, C6352B951F477032006CCEE3 /* RideCreateAction.hpp in Headers */, + 2ADE2F092244187B002598AF /* SignSetNameAction.hpp in Headers */, C6352B851F477022006CCEE3 /* DataSerialiserTraits.h in Headers */, + 2ADE2F082244187B002598AF /* ClearAction.hpp in Headers */, 939A359F20C12FDE00630B3F /* Paint.Surface.h in Headers */, 2A61CAF62229E5720095AD67 /* FootpathSceneryRemoveAction.hpp in Headers */, + 2ADE2F0F2244187B002598AF /* PlacePeepSpawnAction.hpp in Headers */, C67B28192002D7F200109C93 /* Window_internal.h in Headers */, C6352B971F477032006CCEE3 /* SetParkEntranceFeeAction.hpp in Headers */, 2AA050332209A8E300D3A922 /* StaffSetOrdersAction.hpp in Headers */, + 2ADE2F1E2244187B002598AF /* RideSetName.hpp in Headers */, 2AAFD7FA220DD2DC002461A4 /* TrackPlaceAction.hpp in Headers */, + 2ADE2F1D2244187B002598AF /* StaffSetColourAction.hpp in Headers */, 2A61CAF92229E59F0095AD67 /* WaterSetHeightAction.hpp in Headers */, 933F2CBB20935668001B33FD /* LocalisationService.h in Headers */, 2A5C1368221E9F9000F8C245 /* TrackRemoveAction.hpp in Headers */, 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */, + 2ADE2F162244187B002598AF /* ParkSetParameterAction.hpp in Headers */, C6352B861F477022006CCEE3 /* Endianness.h in Headers */, 93CBA4CC20A7504500867D56 /* ImageImporter.h in Headers */, + 2ADE2F0B2244187B002598AF /* RideSetColourScheme.hpp in Headers */, 2AAFD7FE220DD374002461A4 /* PauseToggleAction.hpp in Headers */, + 2ADE2F192244187B002598AF /* ParkMarketingAction.hpp in Headers */, + 2ADE2F0A2244187B002598AF /* ParkSetResearchFundingAction.hpp in Headers */, + 2ADE2F142244187B002598AF /* FootpathRemoveAction.hpp in Headers */, + 2ADE2F1F2244187B002598AF /* BannerSetNameAction.hpp in Headers */, C6352B941F477032006CCEE3 /* PlaceParkEntranceAction.hpp in Headers */, C6352B911F477032006CCEE3 /* GameAction.h in Headers */, 2A43D2BA2225B8D900E8F73B /* RideSetVehiclesAction.hpp in Headers */, 2A43D2C02225B91A00E8F73B /* RideSetVehiclesAction.hpp in Headers */, + 2ADE2F1C2244187B002598AF /* ParkSetNameAction.hpp in Headers */, 2AA050322209A8E300D3A922 /* StaffSetCostumeAction.hpp in Headers */, 2A61CAF72229E5720095AD67 /* FootpathPlaceAction.hpp in Headers */, 2A43D2C22225B91A00E8F73B /* LoadOrQuitAction.hpp in Headers */, C62D838B1FD36D6F008C04F1 /* EditorObjectSelectionSession.h in Headers */, + 2ADE2F152244187B002598AF /* StaffSetPatrolAreaAction.hpp in Headers */, 2A43D2BC2225B8D900E8F73B /* LoadOrQuitAction.hpp in Headers */, + 2ADE2F0E2244187B002598AF /* StaffHireNewAction.hpp in Headers */, + 2ADE2F112244187B002598AF /* GuestSetFlagsAction.hpp in Headers */, 9344BEF920C1E6180047D165 /* Crypt.h in Headers */, 939A35A220C12FFD00630B3F /* InteractiveConsole.h in Headers */, 2ACBAB172226850A0034FB91 /* RideSetSetting.hpp in Headers */, + 2ADE2F0C2244187B002598AF /* SmallSceneryRemoveAction.hpp in Headers */, + 2ADE2F0D2244187B002598AF /* LargeSceneryRemoveAction.hpp in Headers */, 93CBA4C320A7502E00867D56 /* Imaging.h in Headers */, + 2ADE2F182244187B002598AF /* StaffSetNameAction.hpp in Headers */, 2A61CAF52229E5720095AD67 /* FootpathSceneryPlaceAction.hpp in Headers */, + 2ADE2F122244187B002598AF /* ParkSetLoanAction.hpp in Headers */, 9308DA05209908090079EE96 /* Surface.h in Headers */, 93DE9753209C3C1000FB1CC8 /* GameState.h in Headers */, + 2ADE2F132244187B002598AF /* GuestSetNameAction.hpp in Headers */, C6352B841F477022006CCEE3 /* DataSerialiser.h in Headers */, 939A35A020C12FDE00630B3F /* Paint.TileElement.h in Headers */, 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */, 2AAFD7FC220DD336002461A4 /* RideSetPriceAction.hpp in Headers */, C67B28162002D67A00109C93 /* Window.h in Headers */, + 2ADE2F102244187B002598AF /* TrackSetBrakeSpeedAction.hpp in Headers */, C6352B961F477032006CCEE3 /* RideSetStatus.hpp in Headers */, 2A43D2BB2225B8D900E8F73B /* SmallSceneryPlaceAction.hpp in Headers */, + 2ADE2F072244187B002598AF /* MazeSetTrackAction.hpp in Headers */, 2AAFD800220DD3D2002461A4 /* LandSetHeightAction.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; From 7a66f4ede6a1837db3574f4c4de5fb1c8d4f0145 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:08:41 +0100 Subject: [PATCH 084/506] Add core headers to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 83c9978d5e..645ae03328 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -71,6 +71,12 @@ 2ADE2F1E2244187B002598AF /* RideSetName.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F032244187A002598AF /* RideSetName.hpp */; }; 2ADE2F1F2244187B002598AF /* BannerSetNameAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */; }; 2ADE2F202244187B002598AF /* StaffFireAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F052244187B002598AF /* StaffFireAction.hpp */; }; + 2ADE2F27224418B2002598AF /* Random.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F21224418B1002598AF /* Random.hpp */; }; + 2ADE2F28224418B2002598AF /* DataSerialiserTag.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F22224418B1002598AF /* DataSerialiserTag.h */; }; + 2ADE2F29224418B2002598AF /* Numerics.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F23224418B1002598AF /* Numerics.hpp */; }; + 2ADE2F2A224418B2002598AF /* Meta.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F24224418B2002598AF /* Meta.hpp */; }; + 2ADE2F2B224418B2002598AF /* JobPool.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F25224418B2002598AF /* JobPool.hpp */; }; + 2ADE2F2C224418B2002598AF /* FileIndex.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F26224418B2002598AF /* FileIndex.hpp */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -709,6 +715,12 @@ 2ADE2F032244187A002598AF /* RideSetName.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetName.hpp; sourceTree = ""; }; 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BannerSetNameAction.hpp; sourceTree = ""; }; 2ADE2F052244187B002598AF /* StaffFireAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaffFireAction.hpp; sourceTree = ""; }; + 2ADE2F21224418B1002598AF /* Random.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Random.hpp; sourceTree = ""; }; + 2ADE2F22224418B1002598AF /* DataSerialiserTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSerialiserTag.h; sourceTree = ""; }; + 2ADE2F23224418B1002598AF /* Numerics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Numerics.hpp; sourceTree = ""; }; + 2ADE2F24224418B2002598AF /* Meta.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Meta.hpp; sourceTree = ""; }; + 2ADE2F25224418B2002598AF /* JobPool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = JobPool.hpp; sourceTree = ""; }; + 2ADE2F26224418B2002598AF /* FileIndex.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileIndex.hpp; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -2599,6 +2611,12 @@ F76C83781EC4E7CC00FA49E2 /* core */ = { isa = PBXGroup; children = ( + 2ADE2F22224418B1002598AF /* DataSerialiserTag.h */, + 2ADE2F26224418B2002598AF /* FileIndex.hpp */, + 2ADE2F25224418B2002598AF /* JobPool.hpp */, + 2ADE2F24224418B2002598AF /* Meta.hpp */, + 2ADE2F23224418B1002598AF /* Numerics.hpp */, + 2ADE2F21224418B1002598AF /* Random.hpp */, 2A5354EA22099C7200A5440F /* CircularBuffer.h */, F76C83791EC4E7CC00FA49E2 /* Collections.hpp */, F76C837A1EC4E7CC00FA49E2 /* Console.cpp */, @@ -3457,6 +3475,7 @@ 2ADE2F0F2244187B002598AF /* PlacePeepSpawnAction.hpp in Headers */, C67B28192002D7F200109C93 /* Window_internal.h in Headers */, C6352B971F477032006CCEE3 /* SetParkEntranceFeeAction.hpp in Headers */, + 2ADE2F28224418B2002598AF /* DataSerialiserTag.h in Headers */, 2AA050332209A8E300D3A922 /* StaffSetOrdersAction.hpp in Headers */, 2ADE2F1E2244187B002598AF /* RideSetName.hpp in Headers */, 2AAFD7FA220DD2DC002461A4 /* TrackPlaceAction.hpp in Headers */, @@ -3467,8 +3486,10 @@ 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */, 2ADE2F162244187B002598AF /* ParkSetParameterAction.hpp in Headers */, C6352B861F477022006CCEE3 /* Endianness.h in Headers */, + 2ADE2F2C224418B2002598AF /* FileIndex.hpp in Headers */, 93CBA4CC20A7504500867D56 /* ImageImporter.h in Headers */, 2ADE2F0B2244187B002598AF /* RideSetColourScheme.hpp in Headers */, + 2ADE2F29224418B2002598AF /* Numerics.hpp in Headers */, 2AAFD7FE220DD374002461A4 /* PauseToggleAction.hpp in Headers */, 2ADE2F192244187B002598AF /* ParkMarketingAction.hpp in Headers */, 2ADE2F0A2244187B002598AF /* ParkSetResearchFundingAction.hpp in Headers */, @@ -3487,18 +3508,21 @@ 2A43D2BC2225B8D900E8F73B /* LoadOrQuitAction.hpp in Headers */, 2ADE2F0E2244187B002598AF /* StaffHireNewAction.hpp in Headers */, 2ADE2F112244187B002598AF /* GuestSetFlagsAction.hpp in Headers */, + 2ADE2F27224418B2002598AF /* Random.hpp in Headers */, 9344BEF920C1E6180047D165 /* Crypt.h in Headers */, 939A35A220C12FFD00630B3F /* InteractiveConsole.h in Headers */, 2ACBAB172226850A0034FB91 /* RideSetSetting.hpp in Headers */, 2ADE2F0C2244187B002598AF /* SmallSceneryRemoveAction.hpp in Headers */, 2ADE2F0D2244187B002598AF /* LargeSceneryRemoveAction.hpp in Headers */, 93CBA4C320A7502E00867D56 /* Imaging.h in Headers */, + 2ADE2F2B224418B2002598AF /* JobPool.hpp in Headers */, 2ADE2F182244187B002598AF /* StaffSetNameAction.hpp in Headers */, 2A61CAF52229E5720095AD67 /* FootpathSceneryPlaceAction.hpp in Headers */, 2ADE2F122244187B002598AF /* ParkSetLoanAction.hpp in Headers */, 9308DA05209908090079EE96 /* Surface.h in Headers */, 93DE9753209C3C1000FB1CC8 /* GameState.h in Headers */, 2ADE2F132244187B002598AF /* GuestSetNameAction.hpp in Headers */, + 2ADE2F2A224418B2002598AF /* Meta.hpp in Headers */, C6352B841F477022006CCEE3 /* DataSerialiser.h in Headers */, 939A35A020C12FDE00630B3F /* Paint.TileElement.h in Headers */, 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */, From e2d1a190fd56602fd0c47a5f2fa29f7e4a1f8b0c Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:09:40 +0100 Subject: [PATCH 085/506] Add localisation headers to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 645ae03328..af289b0473 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -77,6 +77,7 @@ 2ADE2F2A224418B2002598AF /* Meta.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F24224418B2002598AF /* Meta.hpp */; }; 2ADE2F2B224418B2002598AF /* JobPool.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F25224418B2002598AF /* JobPool.hpp */; }; 2ADE2F2C224418B2002598AF /* FileIndex.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F26224418B2002598AF /* FileIndex.hpp */; }; + 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2D224418E7002598AF /* ConversionTables.h */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -721,6 +722,7 @@ 2ADE2F24224418B2002598AF /* Meta.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Meta.hpp; sourceTree = ""; }; 2ADE2F25224418B2002598AF /* JobPool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = JobPool.hpp; sourceTree = ""; }; 2ADE2F26224418B2002598AF /* FileIndex.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileIndex.hpp; sourceTree = ""; }; + 2ADE2F2D224418E7002598AF /* ConversionTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionTables.h; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -2726,6 +2728,7 @@ F76C83D71EC4E7CC00FA49E2 /* localisation */ = { isa = PBXGroup; children = ( + 2ADE2F2D224418E7002598AF /* ConversionTables.h */, 4C7B53C61FFF94F900A52E21 /* ConversionTables.cpp */, 4C7B53AA1FFF935B00A52E21 /* Convert.cpp */, 4C7B53AB1FFF935B00A52E21 /* Currency.cpp */, @@ -3481,6 +3484,7 @@ 2AAFD7FA220DD2DC002461A4 /* TrackPlaceAction.hpp in Headers */, 2ADE2F1D2244187B002598AF /* StaffSetColourAction.hpp in Headers */, 2A61CAF92229E59F0095AD67 /* WaterSetHeightAction.hpp in Headers */, + 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */, 933F2CBB20935668001B33FD /* LocalisationService.h in Headers */, 2A5C1368221E9F9000F8C245 /* TrackRemoveAction.hpp in Headers */, 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */, From bdd0a76500c6167535c9d5bdd581405692f06dee Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:10:07 +0100 Subject: [PATCH 086/506] Add network/discord to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index af289b0473..9e536cb2d8 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -78,6 +78,8 @@ 2ADE2F2B224418B2002598AF /* JobPool.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F25224418B2002598AF /* JobPool.hpp */; }; 2ADE2F2C224418B2002598AF /* FileIndex.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F26224418B2002598AF /* FileIndex.hpp */; }; 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2D224418E7002598AF /* ConversionTables.h */; }; + 2ADE2F3122441905002598AF /* DiscordService.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2F22441905002598AF /* DiscordService.h */; }; + 2ADE2F3222441905002598AF /* DiscordService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADE2F3022441905002598AF /* DiscordService.cpp */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -723,6 +725,8 @@ 2ADE2F25224418B2002598AF /* JobPool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = JobPool.hpp; sourceTree = ""; }; 2ADE2F26224418B2002598AF /* FileIndex.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileIndex.hpp; sourceTree = ""; }; 2ADE2F2D224418E7002598AF /* ConversionTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionTables.h; sourceTree = ""; }; + 2ADE2F2F22441905002598AF /* DiscordService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscordService.h; sourceTree = ""; }; + 2ADE2F3022441905002598AF /* DiscordService.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiscordService.cpp; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -2774,6 +2778,8 @@ F76C83F51EC4E7CC00FA49E2 /* network */ = { isa = PBXGroup; children = ( + 2ADE2F3022441905002598AF /* DiscordService.cpp */, + 2ADE2F2F22441905002598AF /* DiscordService.h */, F76C83F61EC4E7CC00FA49E2 /* Http.cpp */, F76C83F71EC4E7CC00FA49E2 /* http.h */, F76C83F81EC4E7CC00FA49E2 /* Network.cpp */, @@ -3461,6 +3467,7 @@ files = ( 2A43D2C12225B91A00E8F73B /* RideEntranceExitRemoveAction.hpp in Headers */, 2ADE2F172244187B002598AF /* RideDemolishAction.hpp in Headers */, + 2ADE2F3122441905002598AF /* DiscordService.h in Headers */, C67B28172002D67A00109C93 /* Viewport.h in Headers */, 939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */, 9308DA04209908090079EE96 /* TileElement.h in Headers */, @@ -4217,6 +4224,7 @@ C688790E20289B9B0084B384 /* CrookedHouse.cpp in Sources */, C68878F520289B9B0084B384 /* InvertedImpulseCoaster.cpp in Sources */, C688793020289B9B0084B384 /* LogFlume.cpp in Sources */, + 2ADE2F3222441905002598AF /* DiscordService.cpp in Sources */, C688786620289A430084B384 /* Intent.cpp in Sources */, C68878E520289B9B0084B384 /* Platform.Android.cpp in Sources */, C68878EA20289B9B0084B384 /* Shared.cpp in Sources */, From 040b2de0752856746ae6b14351a48d16c17bd98c Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:10:42 +0100 Subject: [PATCH 087/506] Add paint/virtualfloor to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 9e536cb2d8..47057d6f95 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2D224418E7002598AF /* ConversionTables.h */; }; 2ADE2F3122441905002598AF /* DiscordService.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2F22441905002598AF /* DiscordService.h */; }; 2ADE2F3222441905002598AF /* DiscordService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADE2F3022441905002598AF /* DiscordService.cpp */; }; + 2ADE2F342244191E002598AF /* VirtualFloor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F332244191E002598AF /* VirtualFloor.h */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -727,6 +728,7 @@ 2ADE2F2D224418E7002598AF /* ConversionTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionTables.h; sourceTree = ""; }; 2ADE2F2F22441905002598AF /* DiscordService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscordService.h; sourceTree = ""; }; 2ADE2F3022441905002598AF /* DiscordService.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiscordService.cpp; sourceTree = ""; }; + 2ADE2F332244191E002598AF /* VirtualFloor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualFloor.h; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -2868,6 +2870,7 @@ F76C843A1EC4E7CC00FA49E2 /* paint */ = { isa = PBXGroup; children = ( + 2ADE2F332244191E002598AF /* VirtualFloor.h */, F76C84491EC4E7CC00FA49E2 /* sprite */, F76C843B1EC4E7CC00FA49E2 /* tile_element */, 4C6A66AE1FE278C900694CB6 /* Paint.cpp */, @@ -3542,6 +3545,7 @@ 2ADE2F102244187B002598AF /* TrackSetBrakeSpeedAction.hpp in Headers */, C6352B961F477032006CCEE3 /* RideSetStatus.hpp in Headers */, 2A43D2BB2225B8D900E8F73B /* SmallSceneryPlaceAction.hpp in Headers */, + 2ADE2F342244191E002598AF /* VirtualFloor.h in Headers */, 2ADE2F072244187B002598AF /* MazeSetTrackAction.hpp in Headers */, 2AAFD800220DD3D2002461A4 /* LandSetHeightAction.hpp in Headers */, ); From d85e280666b80d9409b80abd4689e234f5121629 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:11:39 +0100 Subject: [PATCH 088/506] Add ride/ridetypes to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 47057d6f95..27b5f32a4f 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ 2ADE2F3122441905002598AF /* DiscordService.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F2F22441905002598AF /* DiscordService.h */; }; 2ADE2F3222441905002598AF /* DiscordService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADE2F3022441905002598AF /* DiscordService.cpp */; }; 2ADE2F342244191E002598AF /* VirtualFloor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F332244191E002598AF /* VirtualFloor.h */; }; + 2ADE2F3622441960002598AF /* RideTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F352244195F002598AF /* RideTypes.h */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -729,6 +730,7 @@ 2ADE2F2F22441905002598AF /* DiscordService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscordService.h; sourceTree = ""; }; 2ADE2F3022441905002598AF /* DiscordService.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiscordService.cpp; sourceTree = ""; }; 2ADE2F332244191E002598AF /* VirtualFloor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualFloor.h; sourceTree = ""; }; + 2ADE2F352244195F002598AF /* RideTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RideTypes.h; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -2992,6 +2994,7 @@ F76C84831EC4E7CC00FA49E2 /* ride */ = { isa = PBXGroup; children = ( + 2ADE2F352244195F002598AF /* RideTypes.h */, F76C84861EC4E7CC00FA49E2 /* coaster */, F76C84A91EC4E7CC00FA49E2 /* gentle */, F76C84C01EC4E7CC00FA49E2 /* shops */, @@ -3531,6 +3534,7 @@ 93CBA4C320A7502E00867D56 /* Imaging.h in Headers */, 2ADE2F2B224418B2002598AF /* JobPool.hpp in Headers */, 2ADE2F182244187B002598AF /* StaffSetNameAction.hpp in Headers */, + 2ADE2F3622441960002598AF /* RideTypes.h in Headers */, 2A61CAF52229E5720095AD67 /* FootpathSceneryPlaceAction.hpp in Headers */, 2ADE2F122244187B002598AF /* ParkSetLoanAction.hpp in Headers */, 9308DA05209908090079EE96 /* Surface.h in Headers */, From 467d69981bd0ebff0c3b793991ebdc220ceb295b Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Thu, 21 Mar 2019 20:12:21 +0100 Subject: [PATCH 089/506] Add world/spritebase to xcode --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 27b5f32a4f..995e173a7c 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 2ADE2F3222441905002598AF /* DiscordService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADE2F3022441905002598AF /* DiscordService.cpp */; }; 2ADE2F342244191E002598AF /* VirtualFloor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F332244191E002598AF /* VirtualFloor.h */; }; 2ADE2F3622441960002598AF /* RideTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F352244195F002598AF /* RideTypes.h */; }; + 2ADE2F382244198B002598AF /* SpriteBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2F372244198A002598AF /* SpriteBase.h */; }; 2AF7893D220B253E0072754A /* RideSetAppearanceAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */; }; 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C29DEB2218C6AE500E8707F /* RCT12.cpp */; }; 4C358E5221C445F700ADE6BC /* ReplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */; }; @@ -731,6 +732,7 @@ 2ADE2F3022441905002598AF /* DiscordService.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiscordService.cpp; sourceTree = ""; }; 2ADE2F332244191E002598AF /* VirtualFloor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualFloor.h; sourceTree = ""; }; 2ADE2F352244195F002598AF /* RideTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RideTypes.h; sourceTree = ""; }; + 2ADE2F372244198A002598AF /* SpriteBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteBase.h; sourceTree = ""; }; 2AF7893C220B253E0072754A /* RideSetAppearanceAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetAppearanceAction.hpp; sourceTree = ""; }; 4C04D69F2056AA9600F82EBA /* linenoise.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = linenoise.hpp; sourceTree = ""; }; 4C1A53EC205FD19F000F8EF5 /* SceneryObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneryObject.cpp; sourceTree = ""; }; @@ -3219,6 +3221,7 @@ F76C855B1EC4E7CD00FA49E2 /* world */ = { isa = PBXGroup; children = ( + 2ADE2F372244198A002598AF /* SpriteBase.h */, 4C7B541D2007646A00A52E21 /* Balloon.cpp */, 4C7B541E2007646A00A52E21 /* Banner.cpp */, 4C7B541F2007646A00A52E21 /* Banner.h */, @@ -3507,6 +3510,7 @@ 93CBA4CC20A7504500867D56 /* ImageImporter.h in Headers */, 2ADE2F0B2244187B002598AF /* RideSetColourScheme.hpp in Headers */, 2ADE2F29224418B2002598AF /* Numerics.hpp in Headers */, + 2ADE2F382244198B002598AF /* SpriteBase.h in Headers */, 2AAFD7FE220DD374002461A4 /* PauseToggleAction.hpp in Headers */, 2ADE2F192244187B002598AF /* ParkMarketingAction.hpp in Headers */, 2ADE2F0A2244187B002598AF /* ParkSetResearchFundingAction.hpp in Headers */, From 5d5373b63cd63b3dad2d881410f50511ba5352dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 21 Mar 2019 13:11:06 -0700 Subject: [PATCH 090/506] Allow use of numpad enter for console and chat --- distribution/changelog.txt | 1 + src/openrct2-ui/input/Input.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index d6ffe552b2..3336349eb5 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8900] Peep tracking is not synchronized. +- Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2-ui/input/Input.cpp b/src/openrct2-ui/input/Input.cpp index ca612907ef..8a88d2c557 100644 --- a/src/openrct2-ui/input/Input.cpp +++ b/src/openrct2-ui/input/Input.cpp @@ -36,6 +36,7 @@ static void input_handle_console(int32_t key) input = CONSOLE_INPUT_LINE_CLEAR; break; case SDL_SCANCODE_RETURN: + case SDL_SCANCODE_KP_ENTER: input = CONSOLE_INPUT_LINE_EXECUTE; break; case SDL_SCANCODE_UP: @@ -67,6 +68,7 @@ static void input_handle_chat(int32_t key) input = CHAT_INPUT_CLOSE; break; case SDL_SCANCODE_RETURN: + case SDL_SCANCODE_KP_ENTER: input = CHAT_INPUT_SEND; break; } From ad3cc19a1d316684bf02081366e624306fc5a727 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 21 Mar 2019 23:15:04 +0100 Subject: [PATCH 091/506] Update Xcode libraries to use SDL 2.0.9 (#8929) --- OpenRCT2.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 995e173a7c..aaa87c1515 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -3724,7 +3724,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"17\"\nzipname=\"openrct2-libs-macos.zip\"\nliburl=\"https://github.com/OpenRCT2/Dependencies/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/libxc\" || ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\nmkdir \"${SRCROOT}/libxc\"\n\ncurl -L -o \"${SRCROOT}/libxc/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/libxc\" \"${SRCROOT}/libxc/$zipname\"\nrm \"${SRCROOT}/libxc/$zipname\"\n\necho $version > \"${SRCROOT}/libversion\"\nfi"; + shellScript = "version=\"19\"\nzipname=\"openrct2-libs-v19-x64-macos-dylibs.zip\"\nliburl=\"https://github.com/OpenRCT2/Dependencies/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/libxc\" || ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\nmkdir \"${SRCROOT}/libxc\"\n\ncurl -L -o \"${SRCROOT}/libxc/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/libxc\" \"${SRCROOT}/libxc/$zipname\"\nrm \"${SRCROOT}/libxc/$zipname\"\n\necho $version > \"${SRCROOT}/libversion\"\nfi\n"; }; D42C09D21C254F4E00309751 /* Build g2.dat */ = { isa = PBXShellScriptBuildPhase; From 7be312c4c6eb8cbaaf716776b54c835dd3e309a4 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 Mar 2019 09:25:16 +0100 Subject: [PATCH 092/506] Implement rate limiting times for game actions. --- src/openrct2/actions/GameAction.h | 9 +++ src/openrct2/network/Network.cpp | 89 ++++++++++++++++------------ src/openrct2/network/NetworkPlayer.h | 3 +- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index 2210d3fdff..89cc8aa0db 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -188,6 +188,15 @@ public: return const_cast(*this).Serialise(stream); } + /** + * Override this to specify the wait time in milliseconds the player is required to wait before + * being able to execute it again. + */ + virtual uint32_t GetCooldownTime() const + { + return 0; + } + /** * Query the result of the game action without changing the game state. */ diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 7253472937..7f5f7d00ca 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -203,6 +203,7 @@ public: std::string ServerProviderWebsite; private: + void DecayCooldown(NetworkPlayer* player); void CloseConnection(); bool ProcessConnection(NetworkConnection& connection); @@ -314,6 +315,8 @@ private: uint8_t default_group = 0; uint32_t _commandId; uint32_t _actionId; + uint32_t _lastUpdateTime = 0; + uint32_t _currentDeltaTime = 0; std::string _chatLogPath; std::string _chatLogFilenameFormat = "%Y%m%d-%H%M%S.txt"; std::string _serverLogPath; @@ -451,6 +454,21 @@ void Network::Close() } } +void Network::DecayCooldown(NetworkPlayer* player) +{ + if (player == nullptr) + return; // No valid connection yet. + + for (auto it = std::begin(player->CooldownTime); it != std::end(player->CooldownTime);) + { + it->second -= _currentDeltaTime; + if (it->second <= 0) + it = player->CooldownTime.erase(it); + else + it++; + } +} + void Network::CloseConnection() { if (mode == NETWORK_MODE_CLIENT) @@ -671,6 +689,11 @@ void Network::Update() { _closeLock = true; + // Update is not necessarily called per game tick, maintain our own delta time + uint32_t ticks = platform_get_ticks(); + _currentDeltaTime = std::max(ticks - _lastUpdateTime, 1); + _lastUpdateTime = ticks; + switch (GetMode()) { case NETWORK_MODE_SERVER: @@ -716,6 +739,7 @@ void Network::UpdateServer() } else { + DecayCooldown((*it)->Player); it++; } } @@ -2737,58 +2761,29 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa uint32_t tick; uint32_t actionType; - if (!connection.Player) + NetworkPlayer* player = connection.Player; + if (player == nullptr) { return; } packet >> tick >> actionType; - // tick count is different by time last_action_time is set, keep same value + // Don't let clients send pause or quit + if (actionType == GAME_COMMAND_TOGGLE_PAUSE || actionType == GAME_COMMAND_LOAD_OR_QUIT) + { + return; + } + // Check if player's group permission allows command to run - uint32_t ticks = platform_get_ticks(); NetworkGroup* group = GetGroupByID(connection.Player->Group); - if (!group || !group->CanPerformCommand(actionType)) + if (group == nullptr || group->CanPerformCommand(actionType) == false) { Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_PERMISSION_DENIED); return; } - // In case someone modifies the code / memory to enable cluster build, - // require a small delay in between placing scenery to provide some security, as - // cluster mode is a for loop that runs the place_scenery code multiple times. - if (actionType == GAME_COMMAND_PLACE_SCENERY) - { - if (ticks - connection.Player->LastPlaceSceneryTime < ACTION_COOLDOWN_TIME_PLACE_SCENERY && - // Incase platform_get_ticks() wraps after ~49 days, ignore larger logged times. - ticks > connection.Player->LastPlaceSceneryTime) - { - if (!(group->CanPerformCommand(MISC_COMMAND_TOGGLE_SCENERY_CLUSTER))) - { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); - return; - } - } - } - // This is to prevent abuse of demolishing rides. Anyone that is not the server - // host will have to wait a small amount of time in between deleting rides. - else if (actionType == GAME_COMMAND_DEMOLISH_RIDE) - { - if (ticks - connection.Player->LastDemolishRideTime < ACTION_COOLDOWN_TIME_DEMOLISH_RIDE && - // Incase platform_get_ticks()() wraps after ~49 days, ignore larger logged times. - ticks > connection.Player->LastDemolishRideTime) - { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); - return; - } - } - // Don't let clients send pause or quit - else if (actionType == GAME_COMMAND_TOGGLE_PAUSE || actionType == GAME_COMMAND_LOAD_OR_QUIT) - { - return; - } - - // Run game command, and if it is successful send to clients + // Create and enqueue the action. GameAction::Ptr ga = GameActions::Create(actionType); if (ga == nullptr) { @@ -2798,6 +2793,22 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa return; } + auto cooldownIt = player->CooldownTime.find(actionType); + if (cooldownIt != std::end(player->CooldownTime)) + { + if (cooldownIt->second > 0) + { + Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); + return; + } + } + + uint32_t cooldownTime = ga->GetCooldownTime(); + if (cooldownTime > 0) + { + player->CooldownTime[actionType] = cooldownTime; + } + DataSerialiser stream(false); size_t size = packet.Size - packet.BytesRead; stream.GetStream().WriteArray(packet.Read(size), size); diff --git a/src/openrct2/network/NetworkPlayer.h b/src/openrct2/network/NetworkPlayer.h index cf762ad76e..6b128258ac 100644 --- a/src/openrct2/network/NetworkPlayer.h +++ b/src/openrct2/network/NetworkPlayer.h @@ -15,6 +15,7 @@ #include "../world/Sprite.h" #include +#include class NetworkPacket; @@ -36,7 +37,7 @@ public: std::string KeyHash; uint32_t LastDemolishRideTime = 0; uint32_t LastPlaceSceneryTime = 0; - + std::unordered_map CooldownTime; NetworkPlayer() = default; void SetName(const std::string& name); From cfe2fb939e34b1b25c6f9158116f8dacc8d55b1c Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 Mar 2019 10:13:39 +0100 Subject: [PATCH 093/506] Add cooldown time to RideDemolishAction --- src/openrct2/actions/RideDemolishAction.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index e74fef9162..28f67d1876 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -45,6 +45,11 @@ public: { } + uint32_t GetCooldownTime() const override + { + return 1000; + } + void Serialise(DataSerialiser & stream) override { GameAction::Serialise(stream); From 097ed015d867bcc28e8889732b32ebc13b7d45b4 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 Mar 2019 10:13:50 +0100 Subject: [PATCH 094/506] Add cooldown time for SmallSceneryPlaceAction --- src/openrct2/actions/SmallSceneryPlaceAction.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index 7cc9052de1..f20db46d2d 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -49,6 +49,11 @@ public: { } + uint32_t GetCooldownTime() const override + { + return 20; + } + uint16_t GetActionFlags() const override { return GameAction::GetActionFlags(); From c0cd1aaef3c1eb679875ddafbcb75026487cc5db Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 Mar 2019 11:01:00 +0100 Subject: [PATCH 095/506] Exclude host from rate limiting. --- src/openrct2/network/Network.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 7f5f7d00ca..f22ba345d1 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -2793,20 +2793,24 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa return; } - auto cooldownIt = player->CooldownTime.find(actionType); - if (cooldownIt != std::end(player->CooldownTime)) + // Player who is hosting is not affected by cooldowns. + if ((player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) == 0) { - if (cooldownIt->second > 0) + auto cooldownIt = player->CooldownTime.find(actionType); + if (cooldownIt != std::end(player->CooldownTime)) { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); - return; + if (cooldownIt->second > 0) + { + Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); + return; + } } - } - uint32_t cooldownTime = ga->GetCooldownTime(); - if (cooldownTime > 0) - { - player->CooldownTime[actionType] = cooldownTime; + uint32_t cooldownTime = ga->GetCooldownTime(); + if (cooldownTime > 0) + { + player->CooldownTime[actionType] = cooldownTime; + } } DataSerialiser stream(false); From 6143326b669a4ef27202c03203acea69e638df91 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 23 Mar 2019 09:31:39 +0000 Subject: [PATCH 096/506] Fix #8941: Price sync is not able to check --- src/openrct2-ui/windows/Ride.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index a69ac2a909..26a4af7ec9 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -6159,14 +6159,14 @@ static void update_same_price_throughout_flags(uint32_t shop_item) newFlags = gSamePriceThroughoutPark; newFlags ^= (1ULL << SHOP_ITEM_PHOTO) | (1ULL << SHOP_ITEM_PHOTO2) | (1ULL << SHOP_ITEM_PHOTO3) | (1ULL << SHOP_ITEM_PHOTO4); - auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, shop_item); + auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, newFlags); GameActions::Execute(&parkSetParameter); } else { newFlags = gSamePriceThroughoutPark; newFlags ^= (1ULL << shop_item); - auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, shop_item); + auto parkSetParameter = ParkSetParameterAction(ParkParameter::SamePriceInPark, newFlags); GameActions::Execute(&parkSetParameter); } } From 9cbc308c403335aa92f9288ca18220a487545cd6 Mon Sep 17 00:00:00 2001 From: Nazey Date: Sun, 24 Mar 2019 15:48:37 -0400 Subject: [PATCH 097/506] Remove gTrackGroundFlags by returning it within GameActionResult (#8930) Fix #8726 --- contributors.md | 5 + src/openrct2-ui/windows/RideConstruction.cpp | 11 +- src/openrct2/actions/TrackPlaceAction.hpp | 160 +++++++++---------- src/openrct2/ride/Track.cpp | 2 - src/openrct2/ride/Track.h | 2 - src/openrct2/windows/_legacy.cpp | 5 +- 6 files changed, 88 insertions(+), 97 deletions(-) diff --git a/contributors.md b/contributors.md index 837d679d88..3d0a468e0c 100644 --- a/contributors.md +++ b/contributors.md @@ -116,6 +116,11 @@ The following people are not part of the development team, but have been contrib * Øystein Dale (oystedal) * Christian Schubert (Osmodium) * James Lord (RCTMASTA) +* Brian Massino (Nazey) +* Lauren Watson (lwatson2016) +* Jason Myre (jmyre1999) +* Nicole Wright (nicolewright) +* Josh Tucker (joshtucker132) ## Toolchain * (Balletie) - macOS diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 0ae1630025..c7b10b604c 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1654,8 +1654,8 @@ static void window_ride_construction_dropdown(rct_window* w, rct_widgetindex wid _currentTrackCurve = trackPiece | 0x100; window_ride_construction_update_active_elements(); } -static void RideConstructPlacedForwardGameActionCallback(const GameAction* ga, const GameActionResult* result); -static void RideConstructPlacedBackwardGameActionCallback(const GameAction* ga, const GameActionResult* result); +static void RideConstructPlacedForwardGameActionCallback(const GameAction* ga, const TrackPlaceActionResult* result); +static void RideConstructPlacedBackwardGameActionCallback(const GameAction* ga, const TrackPlaceActionResult* result); static void CloseConstructWindowOnCompletion(Ride* ride); static void CloseConstructWindowOnCompletion(Ride* ride) @@ -1677,7 +1677,7 @@ static void CloseConstructWindowOnCompletion(Ride* ride) } } -static void RideConstructPlacedForwardGameActionCallback(const GameAction* ga, const GameActionResult* result) +static void RideConstructPlacedForwardGameActionCallback(const GameAction* ga, const TrackPlaceActionResult* result) { if (result->Error != GA_ERROR::OK) { @@ -1724,7 +1724,7 @@ static void RideConstructPlacedForwardGameActionCallback(const GameAction* ga, c CloseConstructWindowOnCompletion(ride); } -static void RideConstructPlacedBackwardGameActionCallback(const GameAction* ga, const GameActionResult* result) +static void RideConstructPlacedBackwardGameActionCallback(const GameAction* ga, const TrackPlaceActionResult* result) { if (result->Error != GA_ERROR::OK) { @@ -1791,7 +1791,6 @@ static void window_ride_construction_construct(rct_window* w) auto trackPlaceAction = TrackPlaceAction( rideIndex, trackType, { x, y, z, static_cast(trackDirection) }, (properties)&0xFF, (properties >> 8) & 0x0F, (properties >> 12) & 0x0F, liftHillAndAlternativeState); - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { trackPlaceAction.SetCallback(RideConstructPlacedBackwardGameActionCallback); @@ -1815,7 +1814,7 @@ static void window_ride_construction_construct(rct_window* w) _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK_PLACE_ACTION_QUEUED; } - if (gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) + if (dynamic_cast(res.get())->GroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) { viewport_set_visibility(1); } diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index bd9c83944d..f413a3170f 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -19,7 +19,30 @@ #include "../world/Surface.h" #include "GameAction.h" -DEFINE_GAME_ACTION(TrackPlaceAction, GAME_COMMAND_PLACE_TRACK, GameActionResult) +class TrackPlaceActionResult final : public GameActionResult +{ +public: + TrackPlaceActionResult() + : GameActionResult(GA_ERROR::OK, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE) + { + } + TrackPlaceActionResult(GA_ERROR error) + : GameActionResult(error, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE) + { + } + TrackPlaceActionResult(GA_ERROR error, rct_string_id message) + : GameActionResult(error, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, message) + { + } + TrackPlaceActionResult(GA_ERROR error, rct_string_id message, uint8_t* args) + : GameActionResult(error, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, message, args) + { + } + + uint8_t GroundFlags{ 0 }; +}; + +DEFINE_GAME_ACTION(TrackPlaceAction, GAME_COMMAND_PLACE_TRACK, TrackPlaceActionResult) { private: NetworkRideId_t _rideIndex; @@ -68,53 +91,47 @@ public: if (ride == nullptr) { log_warning("Invalid ride for track placement, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } if (ride->type == RIDE_TYPE_NULL) { log_warning("Invalid ride type, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { log_warning("Invalid ride subtype for track placement, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } if (!direction_valid(_origin.direction)) { log_warning("Invalid direction for track placement, direction = %d", _origin.direction); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - auto res = std::make_unique(); + auto res = std::make_unique(); res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; res->Position.x = _origin.x + 16; res->Position.y = _origin.y + 16; res->Position.z = _origin.z; - gTrackGroundFlags = 0; + res->GroundFlags = 0; uint32_t rideTypeFlags = RideProperties[ride->type].flags; if ((ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) && _trackType == TRACK_ELEM_END_STATION) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NOT_ALLOWED_TO_MODIFY_STATION); + return std::make_unique(GA_ERROR::DISALLOWED, STR_NOT_ALLOWED_TO_MODIFY_STATION); } if (!(GetActionFlags() & GA_FLAGS::ALLOW_WHILE_PAUSED)) { if (game_is_paused() && !gCheatsBuildInPauseMode) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED); } } @@ -124,18 +141,15 @@ public: { if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_ONLY_ONE_ON_RIDE_PHOTO_PER_RIDE); + return std::make_unique(GA_ERROR::DISALLOWED, STR_ONLY_ONE_ON_RIDE_PHOTO_PER_RIDE); } } else if (_trackType == TRACK_ELEM_CABLE_LIFT_HILL) { if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT_HILL_COMPONENT_USED) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_ONLY_ONE_CABLE_LIFT_HILL_PER_RIDE); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_ONLY_ONE_CABLE_LIFT_HILL_PER_RIDE); } } // Backwards steep lift hills are allowed, even on roller coasters that do not support forwards steep lift hills. @@ -145,8 +159,7 @@ public: { if (TrackFlags[_trackType] & TRACK_ELEM_FLAG_IS_STEEP_UP) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_STEEP_FOR_LIFT_HILL); + return std::make_unique(GA_ERROR::DISALLOWED, STR_TOO_STEEP_FOR_LIFT_HILL); } } } @@ -166,8 +179,7 @@ public: if (!map_is_location_owned(tileCoords.x, tileCoords.y, tileCoords.z) && !gCheatsSandboxMode) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + return std::make_unique(GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); } numElements++; } @@ -175,24 +187,21 @@ public: if (!map_check_free_elements_and_reorganise(numElements)) { log_warning("Not enough free map elments to place track."); - return std::make_unique( - GA_ERROR::NO_FREE_ELEMENTS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, STR_TILE_ELEMENT_LIMIT_REACHED); } const uint16_t* trackFlags = (rideTypeFlags & RIDE_TYPE_FLAG_FLAT_RIDE) ? FlatTrackFlags : TrackFlags; if (trackFlags[_trackType] & TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT) { if ((_origin.z & 0x0F) != 8) { - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CONSTRUCTION_ERR_UNKNOWN); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CONSTRUCTION_ERR_UNKNOWN); } } else { if ((_origin.z & 0x0F) != 0) { - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CONSTRUCTION_ERR_UNKNOWN); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CONSTRUCTION_ERR_UNKNOWN); } } @@ -211,8 +220,7 @@ public: if (mapLoc.z < 16) { - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_LOW); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_LOW); } int32_t baseZ = mapLoc.z / 8; @@ -231,8 +239,7 @@ public: if (clearanceZ >= 255) { - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_HIGH); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_HIGH); } uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT) @@ -242,29 +249,26 @@ public: mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile, GetFlags(), &cost, crossingMode)) { - return std::make_unique( - GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText, - gCommonFormatArgs); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } uint8_t mapGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); - if (gTrackGroundFlags != 0 && (gTrackGroundFlags & mapGroundFlags) == 0) + if (res->GroundFlags != 0 && (res->GroundFlags & mapGroundFlags) == 0) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); } - gTrackGroundFlags = mapGroundFlags; + res->GroundFlags = mapGroundFlags; if (rideTypeFlags & RIDE_TYPE_FLAG_FLAT_RIDE) { if (FlatTrackFlags[_trackType] & TRACK_ELEM_FLAG_ONLY_ABOVE_GROUND) { - if (gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) + if (res->GroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } } } @@ -272,11 +276,10 @@ public: { if (TrackFlags[_trackType] & TRACK_ELEM_FLAG_ONLY_ABOVE_GROUND) { - if (gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) + if (res->GroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } } } @@ -287,9 +290,8 @@ public: { if (!(gMapGroundFlags & ELEMENT_IS_UNDERWATER)) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CAN_ONLY_BUILD_THIS_UNDERWATER); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_UNDERWATER); } } } @@ -299,17 +301,15 @@ public: { // No element has this flag if (gMapGroundFlags & ELEMENT_IS_UNDERWATER) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CAN_ONLY_BUILD_THIS_UNDERWATER); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_UNDERWATER); } } } if (gMapGroundFlags & ELEMENT_IS_UNDERWATER && !gCheatsDisableClearanceChecks) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_RIDE_CANT_BUILD_THIS_UNDERWATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_RIDE_CANT_BUILD_THIS_UNDERWATER); } if ((rideTypeFlags & RIDE_TYPE_FLAG_TRACK_MUST_BE_ON_WATER) && !byte_9D8150) @@ -319,14 +319,12 @@ public: uint8_t waterHeight = tileElement->AsSurface()->GetWaterHeight() * 2; if (waterHeight == 0) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_WATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_WATER); } if (waterHeight != baseZ) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_WATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_WATER); } waterHeight -= 2; if (waterHeight == tileElement->base_height) @@ -335,9 +333,7 @@ public: if (slope == TILE_ELEMENT_SLOPE_W_CORNER_DN || slope == TILE_ELEMENT_SLOPE_S_CORNER_DN || slope == TILE_ELEMENT_SLOPE_E_CORNER_DN || slope == TILE_ELEMENT_SLOPE_N_CORNER_DN) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CAN_ONLY_BUILD_THIS_ON_WATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_WATER); } } } @@ -355,8 +351,7 @@ public: { if (!track_add_station_element(mapLoc.x, mapLoc.y, baseZ, _origin.direction, _rideIndex, 0)) { - return std::make_unique( - GA_ERROR::UNKNOWN, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText); + return std::make_unique(GA_ERROR::UNKNOWN, gGameCommandErrorText); } } @@ -386,8 +381,7 @@ public: ride_height /= 2; if (ride_height > maxHeight && !byte_9D8150) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_HIGH_FOR_SUPPORTS); + return std::make_unique(GA_ERROR::DISALLOWED, STR_TOO_HIGH_FOR_SUPPORTS); } } } @@ -415,25 +409,23 @@ public: if (ride == nullptr) { log_warning("Invalid ride for track placement, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { log_warning("Invalid ride subtype for track placement, rideIndex = %d", (int32_t)_rideIndex); - return std::make_unique( - GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } - auto res = std::make_unique(); + auto res = std::make_unique(); res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; res->Position.x = _origin.x + 16; res->Position.y = _origin.y + 16; res->Position.z = _origin.z; - gTrackGroundFlags = 0; + res->GroundFlags = 0; uint32_t rideTypeFlags = RideProperties[ride->type].flags; @@ -483,9 +475,8 @@ public: mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile, GetFlags() | GAME_COMMAND_FLAG_APPLY, &cost, crossingMode)) { - return std::make_unique( - GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText, - gCommonFormatArgs); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gCheatsDisableClearanceChecks) @@ -511,14 +502,13 @@ public: } uint8_t mapGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); - if (gTrackGroundFlags != 0 && (gTrackGroundFlags & mapGroundFlags) == 0) + if (res->GroundFlags != 0 && (res->GroundFlags & mapGroundFlags) == 0) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, - STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); } - gTrackGroundFlags = mapGroundFlags; + res->GroundFlags = mapGroundFlags; // 6c5648 12 push tileElement = map_get_surface_element_at({ mapLoc.x, mapLoc.y }); diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index c0fa4d328c..f0eac99893 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -35,8 +35,6 @@ #include "TrackData.h" #include "TrackDesign.h" -uint8_t gTrackGroundFlags; - /** rct2: 0x00997C9D */ // clang-format off const rct_trackdefinition TrackDefinitions[256] = diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 6dbf16b74a..52bdc49be0 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -521,8 +521,6 @@ struct track_circuit_iterator extern const rct_trackdefinition FlatRideTrackDefinitions[256]; extern const rct_trackdefinition TrackDefinitions[256]; -extern uint8_t gTrackGroundFlags; - int32_t track_is_connected_by_shape(TileElement* a, TileElement* b); const rct_preview_track* get_track_def_from_ride(Ride* ride, int32_t trackType); diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index 1011c1d360..459ca7a1e5 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -115,7 +115,7 @@ money32 place_provisional_track_piece( _unkF440C5.z = z; _unkF440C5.direction = trackDirection; _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; - viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); + viewport_set_visibility(3); if (_currentTrackSlopeEnd != 0) viewport_set_visibility(2); @@ -160,7 +160,8 @@ money32 place_provisional_track_piece( _unkF440C5.z = z; _unkF440C5.direction = trackDirection; _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; - viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); + viewport_set_visibility( + (dynamic_cast(res.get())->GroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); if (_currentTrackSlopeEnd != 0) viewport_set_visibility(2); From 791c3059f6792ee2ea7998c5cffa29888e22fb1a Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 24 Mar 2019 20:41:14 +0000 Subject: [PATCH 098/506] Add ParkEntranceRemove GameAction --- OpenRCT2.xcodeproj/project.pbxproj | 4 + .../interface/ViewportInteraction.cpp | 5 +- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 6 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/ParkEntranceRemoveAction.hpp | 108 ++++++++++++++++++ src/openrct2/network/Network.cpp | 2 +- src/openrct2/world/Entrance.cpp | 72 +----------- src/openrct2/world/Entrance.h | 3 - src/openrct2/world/Map.cpp | 5 +- 10 files changed, 130 insertions(+), 79 deletions(-) create mode 100644 src/openrct2/actions/ParkEntranceRemoveAction.hpp diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index aaa87c1515..085105a046 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ 2AAFD7FE220DD374002461A4 /* PauseToggleAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AAFD7FD220DD374002461A4 /* PauseToggleAction.hpp */; }; 2AAFD800220DD3D2002461A4 /* LandSetHeightAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2AAFD7FF220DD3D2002461A4 /* LandSetHeightAction.hpp */; }; 2ACBAB172226850A0034FB91 /* RideSetSetting.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ACBAB162226850A0034FB91 /* RideSetSetting.hpp */; }; + 2ADE2EEA2244183D002598AF /* ParkEntranceRemoveAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EE92244183D002598AF /* ParkEntranceRemoveAction.hpp */; }; 2ADE2F062244187B002598AF /* SurfaceSetStyleAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEB22441878002598AF /* SurfaceSetStyleAction.hpp */; }; 2ADE2F072244187B002598AF /* MazeSetTrackAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EEC22441878002598AF /* MazeSetTrackAction.hpp */; }; 2ADE2F082244187B002598AF /* ClearAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2ADE2EED22441878002598AF /* ClearAction.hpp */; }; @@ -694,6 +695,7 @@ 2AAFD7FD220DD374002461A4 /* PauseToggleAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PauseToggleAction.hpp; sourceTree = ""; }; 2AAFD7FF220DD3D2002461A4 /* LandSetHeightAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandSetHeightAction.hpp; sourceTree = ""; }; 2ACBAB162226850A0034FB91 /* RideSetSetting.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RideSetSetting.hpp; sourceTree = ""; }; + 2ADE2EE92244183D002598AF /* ParkEntranceRemoveAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ParkEntranceRemoveAction.hpp; sourceTree = ""; }; 2ADE2EEB22441878002598AF /* SurfaceSetStyleAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SurfaceSetStyleAction.hpp; sourceTree = ""; }; 2ADE2EEC22441878002598AF /* MazeSetTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MazeSetTrackAction.hpp; sourceTree = ""; }; 2ADE2EED22441878002598AF /* ClearAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClearAction.hpp; sourceTree = ""; }; @@ -2117,6 +2119,7 @@ C6352B871F477032006CCEE3 /* actions */ = { isa = PBXGroup; children = ( + 2ADE2EE92244183D002598AF /* ParkEntranceRemoveAction.hpp */, 2ADE2F042244187A002598AF /* BannerSetNameAction.hpp */, 2ADE2EED22441878002598AF /* ClearAction.hpp */, 2ADE2EFF2244187A002598AF /* ClimateSetAction.hpp */, @@ -3503,6 +3506,7 @@ 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */, 933F2CBB20935668001B33FD /* LocalisationService.h in Headers */, 2A5C1368221E9F9000F8C245 /* TrackRemoveAction.hpp in Headers */, + 2ADE2EEA2244183D002598AF /* ParkEntranceRemoveAction.hpp in Headers */, 2A61CAFB2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp in Headers */, 2ADE2F162244187B002598AF /* ParkSetParameterAction.hpp in Headers */, C6352B861F477022006CCEE3 /* Endianness.h in Headers */, diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 3379a78cd1..fd92214c8a 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -530,8 +531,8 @@ void viewport_interaction_remove_park_entrance(TileElement* tileElement, int32_t y -= CoordsDirectionDelta[rotation].y; break; } - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command(x, GAME_COMMAND_FLAG_APPLY, y, tileElement->base_height / 2, GAME_COMMAND_REMOVE_PARK_ENTRANCE, 0, 0); + auto parkEntranceRemoveAction = ParkEntranceRemoveAction({ x, y, tileElement->base_height * 8 }); + GameActions::Execute(&parkEntranceRemoveAction); } /** diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 297a71b568..3a0da405de 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1280,7 +1280,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, game_command_buy_land_rights, game_command_place_park_entrance, - game_command_remove_park_entrance, + nullptr, game_command_set_maze_track, game_command_set_park_entrance_fee, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 72486b85e8..f62bf9e9d1 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -55,9 +55,9 @@ enum GAME_COMMAND GAME_COMMAND_SET_PARK_NAME, // GA GAME_COMMAND_SET_PARK_OPEN, // GA GAME_COMMAND_BUY_LAND_RIGHTS, - GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA - GAME_COMMAND_REMOVE_PARK_ENTRANCE, - GAME_COMMAND_SET_MAZE_TRACK, + GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA + GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA + GAME_COMMAND_SET_MAZE_TRACK, // GA GAME_COMMAND_SET_PARK_ENTRANCE_FEE, // GA GAME_COMMAND_SET_STAFF_COLOUR, // GA GAME_COMMAND_PLACE_WALL, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 424af171fb..170ec89a32 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -24,6 +24,7 @@ #include "LargeSceneryRemoveAction.hpp" #include "LoadOrQuitAction.hpp" #include "MazeSetTrackAction.hpp" +#include "ParkEntranceRemoveAction.hpp" #include "ParkMarketingAction.hpp" #include "ParkSetLoanAction.hpp" #include "ParkSetNameAction.hpp" @@ -78,6 +79,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/ParkEntranceRemoveAction.hpp b/src/openrct2/actions/ParkEntranceRemoveAction.hpp new file mode 100644 index 0000000000..f0c5d1ae65 --- /dev/null +++ b/src/openrct2/actions/ParkEntranceRemoveAction.hpp @@ -0,0 +1,108 @@ +/***************************************************************************** + * 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 "../OpenRCT2.h" +#include "../management/Finance.h" +#include "../world/Entrance.h" +#include "../world/Park.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(ParkEntranceRemoveAction, GAME_COMMAND_REMOVE_PARK_ENTRANCE, GameActionResult) +{ +private: + CoordsXYZ _loc; + +public: + ParkEntranceRemoveAction() = default; + + ParkEntranceRemoveAction(CoordsXYZ loc) + : _loc(loc) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::EDITOR_ONLY; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc); + } + + GameActionResult::Ptr Query() const override + { + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) + { + return MakeResult(GA_ERROR::NOT_IN_EDITOR_MODE, STR_CANT_REMOVE_THIS); + } + + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; + res->Position = _loc; + res->ErrorTitle = STR_CANT_REMOVE_THIS; + + auto entranceIndex = park_entrance_get_index(_loc.x, _loc.y, _loc.z); + if (entranceIndex == -1) + { + log_error("Could not find entrance at x = %d, y = %d, z = %d", _loc.x, _loc.y, _loc.z); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; + res->Position = _loc; + res->ErrorTitle = STR_CANT_REMOVE_THIS; + + auto entranceIndex = park_entrance_get_index(_loc.x, _loc.y, _loc.z); + if (entranceIndex == -1) + { + log_error("Could not find entrance at x = %d, y = %d, z = %d", _loc.x, _loc.y, _loc.z); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + auto direction = (gParkEntrances[entranceIndex].direction - 1) & 3; + + // Centre (sign) + ParkEntranceRemoveSegment(_loc); + + // Left post + ParkEntranceRemoveSegment( + { _loc.x + CoordsDirectionDelta[direction].x, _loc.y + CoordsDirectionDelta[direction].y, _loc.z }); + + // Right post + ParkEntranceRemoveSegment( + { _loc.x - CoordsDirectionDelta[direction].x, _loc.y - CoordsDirectionDelta[direction].y, _loc.z }); + + gParkEntrances.erase(gParkEntrances.begin() + entranceIndex); + return res; + } + +private: + void ParkEntranceRemoveSegment(CoordsXYZ loc) const + { + auto entranceElement = map_get_park_entrance_element_at(loc.x, loc.y, loc.z / 8, true); + if (entranceElement == nullptr) + { + return; + } + + map_invalidate_tile(loc.x, loc.y, entranceElement->base_height * 8, entranceElement->clearance_height * 8); + entranceElement->Remove(); + update_park_fences({ loc.x, loc.y }); + } +}; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index f22ba345d1..8ef8647b02 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 "7" +#define NETWORK_STREAM_VERSION "8" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Entrance.cpp b/src/openrct2/world/Entrance.cpp index bd69c2822c..8bd6f66292 100644 --- a/src/openrct2/world/Entrance.cpp +++ b/src/openrct2/world/Entrance.cpp @@ -12,6 +12,7 @@ #include "../Cheats.h" #include "../Game.h" #include "../OpenRCT2.h" +#include "../actions/ParkEntranceRemoveAction.hpp" #include "../actions/RideEntranceExitPlaceAction.hpp" #include "../actions/RideEntranceExitRemoveAction.hpp" #include "../localisation/StringIds.h" @@ -35,59 +36,6 @@ std::vector gParkEntrances; CoordsXYZD gRideEntranceExitGhostPosition; uint8_t gRideEntranceExitGhostStationIndex; -static void ParkEntranceRemoveSegment(int32_t x, int32_t y, int32_t z) -{ - EntranceElement* tileElement; - - tileElement = map_get_park_entrance_element_at(x, y, z, true); - if (tileElement == nullptr) - { - return; - } - - map_invalidate_tile(x, y, tileElement->base_height * 8, tileElement->clearance_height * 8); - tileElement->Remove(); - update_park_fences({ x, y }); -} - -static money32 ParkEntranceRemove(int16_t x, int16_t y, uint8_t z, uint8_t flags) -{ - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) - { - return MONEY32_UNDEFINED; - } - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z * 16; - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - auto entranceIndex = park_entrance_get_index(x, y, z * 16); - if (entranceIndex == -1) - { - return 0; - } - - auto direction = (gParkEntrances[entranceIndex].direction - 1) & 3; - - // Centre (sign) - ParkEntranceRemoveSegment(x, y, z * 2); - - // Left post - ParkEntranceRemoveSegment(x + CoordsDirectionDelta[direction].x, y + CoordsDirectionDelta[direction].y, z * 2); - - // Right post - ParkEntranceRemoveSegment(x - CoordsDirectionDelta[direction].x, y - CoordsDirectionDelta[direction].y, z * 2); - - gParkEntrances.erase(gParkEntrances.begin() + entranceIndex); - return 0; -} - static money32 RideEntranceExitPlaceGhost( ride_id_t rideIndex, int16_t x, int16_t y, uint8_t direction, uint8_t placeType, uint8_t stationNum) { @@ -99,17 +47,6 @@ static money32 RideEntranceExitPlaceGhost( return res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } -/** - * - * rct2: 0x00666A63 - */ -void game_command_remove_park_entrance( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - *ebx = ParkEntranceRemove(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, *ebx & 0xFF); -} - /** * * rct2: 0x00666F9E @@ -119,9 +56,10 @@ void park_entrance_remove_ghost() if (gParkEntranceGhostExists) { gParkEntranceGhostExists = false; - game_do_command( - gParkEntranceGhostPosition.x, GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_APPLY, - gParkEntranceGhostPosition.y, gParkEntranceGhostPosition.z, GAME_COMMAND_REMOVE_PARK_ENTRANCE, 0, 0); + auto parkEntranceRemoveAction = ParkEntranceRemoveAction( + { gParkEntranceGhostPosition.x, gParkEntranceGhostPosition.y, gParkEntranceGhostPosition.z * 16 }); + parkEntranceRemoveAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); + GameActions::Execute(&parkEntranceRemoveAction); } } diff --git a/src/openrct2/world/Entrance.h b/src/openrct2/world/Entrance.h index 21698a922d..d1f797a795 100644 --- a/src/openrct2/world/Entrance.h +++ b/src/openrct2/world/Entrance.h @@ -26,9 +26,6 @@ struct rct_entrance_type assert_struct_size(rct_entrance_type, 8); #pragma pack(pop) -void game_command_remove_park_entrance( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - struct TileElement; extern bool gParkEntranceGhostExists; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 82dd757cce..94c090c140 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -19,6 +19,7 @@ #include "../actions/LandRaiseAction.hpp" #include "../actions/LandSetHeightAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" +#include "../actions/ParkEntranceRemoveAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" #include "../actions/WaterSetHeightAction.hpp" @@ -2655,8 +2656,8 @@ static void clear_element_at(int32_t x, int32_t y, TileElement** elementPtr) y -= CoordsDirectionDelta[rotation].y; break; } - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command(x, GAME_COMMAND_FLAG_APPLY, y, element->base_height / 2, GAME_COMMAND_REMOVE_PARK_ENTRANCE, 0, 0); + auto parkEntranceRemoveAction = ParkEntranceRemoveAction({ x, y, element->base_height * 8 }); + GameActions::Execute(&parkEntranceRemoveAction); break; } case TILE_ELEMENT_TYPE_WALL: From 184d95c7204f1adce0cb45e78668ee6e8b17c604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 24 Mar 2019 13:53:54 -0700 Subject: [PATCH 099/506] Fix #8947: Detection of AVX2 support --- distribution/changelog.txt | 1 + src/openrct2/util/Util.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 3336349eb5..f1dc18fa8e 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8900] Peep tracking is not synchronized. +- Fix: [#8947] Detection of AVX2 support. - Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 350bfa149d..ec2e3556d0 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -223,10 +223,10 @@ bool sse41_available() bool avx2_available() { #ifdef OPENRCT2_X86 -// For GCC and similar use the builtin function, as cpuid changed its semantics in -// https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 -// which causes it to ignore subleafs, but the new function is unavailable on Ubuntu's -// prehistoric toolchains + // For GCC and similar use the builtin function, as cpuid changed its semantics in + // https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 + // which causes it to ignore subleafs, but the new function is unavailable on + // Ubuntu 18.04's toolchains. # if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10)) return __builtin_cpu_supports("avx2"); # else @@ -234,7 +234,15 @@ bool avx2_available() uint32_t regs[4] = { 0 }; if (cpuid_x86(regs, 7)) { - return (regs[1] & (1 << 5)); + bool avxCPUSupport = (regs[1] & (1 << 5)) != 0; + if (avxCPUSupport) + { + // Need to check if OS also supports the register of xmm/ymm + // This check has to be conditional, otherwise INVALID_INSTRUCTION exception. + uint64_t xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); + avxCPUSupport = (xcrFeatureMask & 0x6) || false; + } + return avxCPUSupport; } # endif #endif From 262a9f29e8fbb4a4dff5471d8611f1ac0491d345 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 24 Mar 2019 22:24:40 +0100 Subject: [PATCH 100/506] Fix formatting --- src/openrct2/util/Util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index ec2e3556d0..5373e7352f 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -225,7 +225,7 @@ bool avx2_available() #ifdef OPENRCT2_X86 // For GCC and similar use the builtin function, as cpuid changed its semantics in // https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 - // which causes it to ignore subleafs, but the new function is unavailable on + // which causes it to ignore subleafs, but the new function is unavailable on // Ubuntu 18.04's toolchains. # if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10)) return __builtin_cpu_supports("avx2"); From c537f87fd58774aed4e30c83ffccc3636528bdd1 Mon Sep 17 00:00:00 2001 From: Ben Hopkins Date: Sun, 24 Mar 2019 16:45:42 -0500 Subject: [PATCH 101/506] Add scenery picker shortcut --- data/language/en-GB.txt | 1 + distribution/changelog.txt | 1 + src/openrct2-ui/input/KeyboardShortcut.cpp | 29 +++++++++++++++++++++ src/openrct2-ui/input/KeyboardShortcuts.cpp | 2 ++ src/openrct2-ui/input/KeyboardShortcuts.h | 1 + src/openrct2-ui/windows/Scenery.cpp | 2 ++ src/openrct2-ui/windows/ShortcutKeys.cpp | 1 + src/openrct2/interface/Window.h | 1 + src/openrct2/localisation/StringIds.h | 2 ++ 9 files changed, 40 insertions(+) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index e11240e1af..d2535e9d30 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3751,6 +3751,7 @@ STR_6300 :{SMALLFONT}{BLACK}Download all missing objects if available online. STR_6301 :{SMALLFONT}{BLACK}Copy the selected object name to the clipboard. STR_6302 :{SMALLFONT}{BLACK}Copy the entire list of missing objects to the clipboard. STR_6303 :Downloading object ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Open scenery picker ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f1dc18fa8e..e692bef16e 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8919] Allow setting ride price from console. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. diff --git a/src/openrct2-ui/input/KeyboardShortcut.cpp b/src/openrct2-ui/input/KeyboardShortcut.cpp index faebe827b9..8da84e3d0d 100644 --- a/src/openrct2-ui/input/KeyboardShortcut.cpp +++ b/src/openrct2-ui/input/KeyboardShortcut.cpp @@ -33,6 +33,7 @@ #include #include #include +#include uint8_t gKeyboardShortcutChangeId; @@ -767,6 +768,33 @@ static void shortcut_advance_to_next_tick() gDoSingleUpdate = true; } +static void shortcut_open_scenery_picker() +{ + if ((gScreenFlags & (SCREEN_FLAGS_TITLE_DEMO | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + || (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR && gS6Info.editor_step != EDITOR_STEP_LANDSCAPE_EDITOR)) + return; + + rct_window* window_scenery = window_find_by_class(WC_SCENERY); + if (window_scenery == nullptr) + { + rct_window* window_toolbar = window_find_by_class(WC_TOP_TOOLBAR); + if (window_toolbar != nullptr) + { + window_invalidate(window_toolbar); + window_event_mouse_up_call(window_toolbar, WC_TOP_TOOLBAR__WIDX_SCENERY); + } + } + + window_scenery = window_find_by_class(WC_SCENERY); + if (window_scenery != nullptr && !widget_is_disabled(window_scenery, WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON) + && window_scenery->widgets[WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON].type != WWT_EMPTY + && !gWindowSceneryEyedropperEnabled) + { + window_event_mouse_up_call(window_scenery, WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON); + return; + } +} + namespace { const shortcut_action shortcut_table[SHORTCUT_COUNT] = { @@ -841,6 +869,7 @@ namespace shortcut_highlight_path_issues_toggle, shortcut_open_tile_inspector, shortcut_advance_to_next_tick, + shortcut_open_scenery_picker, }; } // anonymous namespace diff --git a/src/openrct2-ui/input/KeyboardShortcuts.cpp b/src/openrct2-ui/input/KeyboardShortcuts.cpp index e6e7422ae8..9046baa351 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.cpp +++ b/src/openrct2-ui/input/KeyboardShortcuts.cpp @@ -317,4 +317,6 @@ const uint16_t KeyboardShortcuts::DefaultKeys[SHORTCUT_COUNT] = { SHORTCUT_UNDEFINED, // SHORTCUT_VIEW_CLIPPING SDL_SCANCODE_I, // SHORTCUT_HIGHLIGHT_PATH_ISSUES_TOGGLE SHORTCUT_UNDEFINED, // SHORTCUT_TILE_INSPECTOR + SHORTCUT_UNDEFINED, // SHORTCUT_ADVANCE_TO_NEXT_TICK + SHORTCUT_UNDEFINED, // SHORTCUT_SCENERY_PICKER }; diff --git a/src/openrct2-ui/input/KeyboardShortcuts.h b/src/openrct2-ui/input/KeyboardShortcuts.h index b0418d6dcd..5233dbf71f 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.h +++ b/src/openrct2-ui/input/KeyboardShortcuts.h @@ -95,6 +95,7 @@ enum SHORTCUT_HIGHLIGHT_PATH_ISSUES_TOGGLE, SHORTCUT_TILE_INSPECTOR, SHORTCUT_ADVANCE_TO_NEXT_TICK, + SHORTCUT_SCENERY_PICKER, SHORTCUT_COUNT, diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 595e053c40..04a2a66e35 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -140,6 +140,7 @@ enum WINDOW_SCENERY_LIST_WIDGET_IDX { validate_global_widx(WC_SCENERY, WIDX_SCENERY_TAB_1); validate_global_widx(WC_SCENERY, WIDX_SCENERY_ROTATE_OBJECTS_BUTTON); +validate_global_widx(WC_SCENERY, WIDX_SCENERY_EYEDROPPER_BUTTON); static rct_widget window_scenery_widgets[] = { { WWT_FRAME, 0, 0, 633, 0, 141, 0xFFFFFFFF, STR_NONE }, // 1 0x009DE298 @@ -579,6 +580,7 @@ static void window_scenery_mouseup(rct_window* w, rct_widgetindex widgetIndex) gWindowSceneryPaintEnabled = 0; gWindowSceneryClusterEnabled = 0; gWindowSceneryEyedropperEnabled = !gWindowSceneryEyedropperEnabled; + scenery_remove_ghost_tool_placement(); window_invalidate(w); break; case WIDX_SCENERY_BUILD_CLUSTER_BUTTON: diff --git a/src/openrct2-ui/windows/ShortcutKeys.cpp b/src/openrct2-ui/windows/ShortcutKeys.cpp index d3f53f6c51..95c4ac7720 100644 --- a/src/openrct2-ui/windows/ShortcutKeys.cpp +++ b/src/openrct2-ui/windows/ShortcutKeys.cpp @@ -150,6 +150,7 @@ const rct_string_id ShortcutStringIds[SHORTCUT_COUNT] = { STR_SHORTCUT_HIGHLIGHT_PATH_ISSUES_TOGGLE, STR_SHORTCUT_OPEN_TILE_INSPECTOR, STR_ADVANCE_TO_NEXT_TICK, + STR_SHORTCUT_OPEN_SCENERY_PICKER, }; // clang-format on diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 8ab1c5973b..6835f620cf 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -487,6 +487,7 @@ enum #define WC_RIDE_CONSTRUCTION__WIDX_ROTATE 32 #define WC_SCENERY__WIDX_SCENERY_TAB_1 4 #define WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON 25 +#define WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON 30 #define WC_PEEP__WIDX_PATROL 11 #define WC_PEEP__WIDX_ACTION_LBL 12 #define WC_PEEP__WIDX_PICKUP 13 diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 7f45e809ca..c4695ed7b9 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3933,6 +3933,8 @@ enum STR_COPY_ALL_TIP = 6302, STR_DOWNLOADING_OBJECTS = 6303, + STR_SHORTCUT_OPEN_SCENERY_PICKER = 6304, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; From d41822e0f50596ddc2071e35a93a29418b8c8540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 24 Mar 2019 15:16:57 -0700 Subject: [PATCH 102/506] Network relevant player info on changes --- src/openrct2/network/Network.cpp | 62 +++++++++++++++++++++++++++-- src/openrct2/network/NetworkTypes.h | 1 + 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 8ef8647b02..1d6be0643e 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 "8" +#define NETWORK_STREAM_VERSION "9" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; @@ -125,6 +125,7 @@ public: void Flush(); void ProcessPending(); void ProcessPlayerList(); + void ProcessPlayerInfo(); void ProcessGameCommands(); void EnqueueGameAction(const GameAction* action); std::vector>::iterator GetPlayerIteratorByID(uint8_t id); @@ -173,6 +174,7 @@ public: void Client_Send_GAME_ACTION(const GameAction* action); void Server_Send_GAME_ACTION(const GameAction* action); void Server_Send_TICK(); + void Server_Send_PLAYERINFO(int32_t playerId); void Server_Send_PLAYERLIST(); void Client_Send_PING(); void Server_Send_PING(); @@ -291,7 +293,7 @@ private: }; std::map _serverTickData; - + std::multimap _pendingPlayerInfo; int32_t mode = NETWORK_MODE_NONE; int32_t status = NETWORK_STATUS_NONE; bool _closeLock = false; @@ -340,6 +342,7 @@ private: void Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_TICK(NetworkConnection& connection, NetworkPacket& packet); + void Client_Handle_PLAYERINFO(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_PLAYERLIST(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_PING(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_PING(NetworkConnection& connection, NetworkPacket& packet); @@ -379,6 +382,7 @@ Network::Network() client_command_handlers[NETWORK_COMMAND_GAME_ACTION] = &Network::Client_Handle_GAME_ACTION; client_command_handlers[NETWORK_COMMAND_TICK] = &Network::Client_Handle_TICK; client_command_handlers[NETWORK_COMMAND_PLAYERLIST] = &Network::Client_Handle_PLAYERLIST; + client_command_handlers[NETWORK_COMMAND_PLAYERINFO] = &Network::Client_Handle_PLAYERINFO; client_command_handlers[NETWORK_COMMAND_PING] = &Network::Client_Handle_PING; client_command_handlers[NETWORK_COMMAND_PINGLIST] = &Network::Client_Handle_PINGLIST; client_command_handlers[NETWORK_COMMAND_SETDISCONNECTMSG] = &Network::Client_Handle_SETDISCONNECTMSG; @@ -447,6 +451,7 @@ void Network::Close() player_list.clear(); group_list.clear(); _pendingPlayerList.reset(); + _pendingPlayerInfo.clear(); gfx_invalidate_screen(); @@ -1664,6 +1669,19 @@ void Network::Server_Send_TICK() SendPacketToClients(*packet); } +void Network::Server_Send_PLAYERINFO(int32_t playerId) +{ + std::unique_ptr packet(NetworkPacket::Allocate()); + *packet << (uint32_t)NETWORK_COMMAND_PLAYERINFO << gCurrentTicks; + + auto* player = GetPlayerByID(playerId); + if (player == nullptr) + return; + + player->Write(*packet); + SendPacketToClients(*packet); +} + void Network::Server_Send_PLAYERLIST() { std::unique_ptr packet(NetworkPacket::Allocate()); @@ -1853,6 +1871,7 @@ void Network::ProcessPending() { ProcessGameCommands(); ProcessPlayerList(); + ProcessPlayerInfo(); } void Network::ProcessPlayerList() @@ -1868,9 +1887,12 @@ void Network::ProcessPlayerList() for (auto&& pendingPlayer : _pendingPlayerList.players) { activePlayerIds.push_back(pendingPlayer.Id); - if (!GetPlayerByID(pendingPlayer.Id)) + + auto* player = GetPlayerByID(pendingPlayer.Id); + if (player == nullptr) { - NetworkPlayer* player = AddPlayer("", ""); + // Add new player. + player = AddPlayer("", ""); if (player) { *player = pendingPlayer; @@ -1880,6 +1902,11 @@ void Network::ProcessPlayerList() } } } + else + { + // Update. + *player = pendingPlayer; + } } // Remove any players that are not in newly received list @@ -1899,6 +1926,20 @@ void Network::ProcessPlayerList() _pendingPlayerList.reset(); } +void Network::ProcessPlayerInfo() +{ + auto range = _pendingPlayerInfo.equal_range(gCurrentTicks); + for (auto it = range.first; it != range.second; it++) + { + auto* player = GetPlayerByID(it->second.Id); + if (player != nullptr) + { + *player = it->second; + } + } + _pendingPlayerInfo.erase(gCurrentTicks); +} + void Network::ProcessGameCommands() { while (game_command_queue.begin() != game_command_queue.end()) @@ -1938,6 +1979,7 @@ void Network::ProcessGameCommands() if (result->Error == GA_ERROR::OK) { Server_Send_GAME_ACTION(action); + Server_Send_PLAYERINFO(action->GetPlayer()); } } else @@ -1979,6 +2021,7 @@ void Network::ProcessGameCommands() } Server_Send_GAMECMD(gc.eax, gc.ebx, gc.ecx, gc.edx, gc.esi, gc.edi, gc.ebp, gc.playerid, gc.callback); + Server_Send_PLAYERINFO(gc.playerid); } } } @@ -2913,6 +2956,17 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, _serverTickData.emplace(server_tick, tickData); } +void Network::Client_Handle_PLAYERINFO([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) +{ + uint32_t tick; + packet >> tick; + + NetworkPlayer playerInfo; + playerInfo.Read(packet); + + _pendingPlayerInfo.emplace(tick, playerInfo); +} + void Network::Client_Handle_PLAYERLIST([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) { uint32_t tick; diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index bdd96c5434..c6fb88ce81 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -55,6 +55,7 @@ enum NETWORK_COMMAND NETWORK_COMMAND_GAMECMD, NETWORK_COMMAND_TICK, NETWORK_COMMAND_PLAYERLIST, + NETWORK_COMMAND_PLAYERINFO, NETWORK_COMMAND_PING, NETWORK_COMMAND_PINGLIST, NETWORK_COMMAND_SETDISCONNECTMSG, From cf913d14193eaa9e481222ce6bbfee2352b54cd7 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 25 Mar 2019 15:56:40 +0100 Subject: [PATCH 103/506] Remove two unused functions --- src/openrct2/util/Util.cpp | 14 -------------- src/openrct2/util/Util.h | 2 -- 2 files changed, 16 deletions(-) diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 5373e7352f..0245e4158d 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -304,11 +304,6 @@ int32_t bitcount(uint32_t source) return bitcount_fn(source); } -bool strequals(const char* a, const char* b, int32_t length, bool caseInsensitive) -{ - return caseInsensitive ? _strnicmp(a, b, length) == 0 : strncmp(a, b, length) == 0; -} - /* case insensitive compare */ int32_t strcicmp(char const* a, char const* b) { @@ -482,15 +477,6 @@ char* safe_strcat_path(char* destination, const char* source, size_t size) return safe_strcat(destination, source, size); } -char* safe_strtrimleft(char* destination, const char* source, size_t size) -{ - while (*source == ' ') - { - source++; - } - return safe_strcpy(destination, source, size); -} - #if defined(_WIN32) char* strcasestr(const char* haystack, const char* needle) { diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index d07e13482c..3fc0d2f1f0 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -37,14 +37,12 @@ bool avx2_available(); int32_t bitscanforward(int32_t source); void bitcount_init(); int32_t bitcount(uint32_t source); -bool strequals(const char* a, const char* b, int32_t length, bool caseInsensitive); int32_t strcicmp(char const* a, char const* b); int32_t strlogicalcmp(char const* a, char const* b); utf8* safe_strtrunc(utf8* text, size_t size); char* safe_strcpy(char* destination, const char* source, size_t num); char* safe_strcat(char* destination, const char* source, size_t size); char* safe_strcat_path(char* destination, const char* source, size_t size); -char* safe_strtrimleft(char* destination, const char* source, size_t size); #if defined(_WIN32) char* strcasestr(const char* haystack, const char* needle); #endif From c841ee31e750f2ddb040d349ad4e825740728c04 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 25 Mar 2019 17:21:53 +0100 Subject: [PATCH 104/506] Remove more remains of scenario description from Object Selection window --- data/language/en-GB.txt | 1 - src/openrct2-ui/windows/EditorObjectSelection.cpp | 11 ++++++----- src/openrct2/localisation/StringIds.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index d2535e9d30..0630b1c4cd 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -2414,7 +2414,6 @@ STR_3190 :Path Extras STR_3191 :Scenery Groups STR_3192 :Park Entrance STR_3193 :Water -STR_3194 :Scenario Description STR_3195 :Invention List STR_3196 :{WINDOW_COLOUR_2}Research Group: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Items pre-invented at start of game: diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 6d4a524195..6781550df1 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -99,9 +99,6 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[] = { { STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false }, { STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false }, - // No longer supported: - // { STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION, SPR_TAB_STATS, false }, - // Currently hidden until new save format arrives: // { STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, false }, // { STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, false }, @@ -828,7 +825,7 @@ static void window_editor_object_selection_invalidate(rct_window* w) w->pressed_widgets &= ~(1 << WIDX_ADVANCED); // Set window title and buttons - set_format_arg(0, rct_string_id, ObjectSelectionPages[get_selected_object_type(w)].Caption); + set_format_arg(0, rct_string_id, ObjectSelectionPages[w->selected_tab].Caption); if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { w->widgets[WIDX_TITLE].text = STR_TRACK_DESIGNS_MANAGER_SELECT_RIDE_TYPE; @@ -1533,5 +1530,9 @@ static std::string object_get_description(const void* object) static int32_t get_selected_object_type(rct_window* w) { - return w->selected_tab; + auto tab = w->selected_tab; + if (tab >= OBJECT_TYPE_SCENARIO_TEXT) + return tab + 1; + else + return tab; } diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index c4695ed7b9..9395aa69ee 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -2502,7 +2502,7 @@ enum STR_OBJECT_SELECTION_SCENERY_GROUPS = 3191, STR_OBJECT_SELECTION_PARK_ENTRANCE = 3192, STR_OBJECT_SELECTION_WATER = 3193, - STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION = 3194, + STR_INVENTION_LIST = 3195, STR_INVENTION_RESEARCH_GROUP = 3196, STR_INVENTION_PREINVENTED_ITEMS = 3197, From c09f283c25d9ea25d585d660346b93c19d1ceb79 Mon Sep 17 00:00:00 2001 From: Joshua Tucker Date: Tue, 26 Mar 2019 09:47:42 -0400 Subject: [PATCH 105/506] Fix #8468: Removed code incorrectly increasing tile height --- src/openrct2-ui/windows/TopToolbar.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 178485cb36..6089a17b6d 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1390,12 +1390,8 @@ static void sub_6E1F34( return; } + // If CTRL and SHIFT not pressed gSceneryPlaceZ = 0; - uint16_t water_height = tile_element->AsSurface()->GetWaterHeight(); - if (water_height != 0) - { - gSceneryPlaceZ = water_height * 16; - } // If SHIFT pressed if (gSceneryShiftPressed) From 047fa65a6608600487e162d46b3f6563431ca22c Mon Sep 17 00:00:00 2001 From: Nazey Date: Tue, 26 Mar 2019 12:34:30 -0400 Subject: [PATCH 106/506] Fix #8942: Water level is raised abnormally (#8971) --- src/openrct2/actions/WaterRaiseAction.hpp | 4 ++++ src/openrct2/network/Network.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index d95fefd359..7ee71f7796 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -86,6 +86,10 @@ private: SurfaceElement* surfaceElement = tileElement->AsSurface(); uint8_t height = surfaceElement->GetWaterHeight(); + + if (surfaceElement->base_height > maxHeight) + continue; + if (height != 0) { height *= 2; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 1d6be0643e..ade9764b8b 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 "9" +#define NETWORK_STREAM_VERSION "10" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From dff1ebaf21ae52e27e9915a26fbf535d3ab149ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 26 Mar 2019 23:46:08 +0100 Subject: [PATCH 107/506] Apply better guards for download queueing (#8864) Follow-up to #8821. Use mutex to synchronize access rather than make the bool atomic to avoid TOCTOU issues. --- src/openrct2-ui/windows/ObjectLoadError.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index 3624587123..fa8ea6855a 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -34,6 +34,7 @@ private: std::vector _downloadedEntries; size_t _currentDownloadIndex{}; std::mutex _downloadedEntriesMutex; + std::mutex _queueMutex; bool _nextDownloadQueued{}; // TODO static due to INTENT_EXTRA_CALLBACK not allowing a std::function @@ -61,6 +62,7 @@ public: void Update() { + std::lock_guard guard(_queueMutex); if (_nextDownloadQueued) { _nextDownloadQueued = false; @@ -87,6 +89,7 @@ private: void QueueNextDownload() { + std::lock_guard guard(_queueMutex); _nextDownloadQueued = true; } From 43d4a20b797bf38373aec75e8ae7304925f897f6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 24 Feb 2019 22:31:02 +0100 Subject: [PATCH 108/506] Add N with caron --- resources/g2/font/latin/n-caron-bold.png | Bin 0 -> 171 bytes resources/g2/font/latin/n-caron-small.png | Bin 0 -> 171 bytes resources/g2/font/latin/n-caron-tiny.png | Bin 0 -> 172 bytes resources/g2/font/latin/n-caron-uc-bold.png | Bin 0 -> 193 bytes resources/g2/font/latin/n-caron-uc-small.png | Bin 0 -> 183 bytes resources/g2/font/latin/n-caron-uc-tiny.png | Bin 0 -> 179 bytes resources/g2/sprites.json | 36 +++++++++++++++++++ src/openrct2/drawing/Font.cpp | 2 ++ src/openrct2/sprites.h | 5 ++- 9 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 resources/g2/font/latin/n-caron-bold.png create mode 100644 resources/g2/font/latin/n-caron-small.png create mode 100644 resources/g2/font/latin/n-caron-tiny.png create mode 100644 resources/g2/font/latin/n-caron-uc-bold.png create mode 100644 resources/g2/font/latin/n-caron-uc-small.png create mode 100644 resources/g2/font/latin/n-caron-uc-tiny.png diff --git a/resources/g2/font/latin/n-caron-bold.png b/resources/g2/font/latin/n-caron-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..438634bc254c5895c4f2909b5cf319c1d7152c60 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)L#0(@^7p<8Gq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?LJV?mi&u1ysY}>FVdQ I&MBb@04`xFpa1{> literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/n-caron-small.png b/resources/g2/font/latin/n-caron-small.png new file mode 100644 index 0000000000000000000000000000000000000000..97630bad3d0d516a9ed752d86b4dad253978c801 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ##0(@~B^+M>q<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?Iev=AsH>FMGa!f`$MLPElfa|akymKz$Jv0-pM#=~H7jdjn`j5sr(A_h-a KKbLh*2~7akGA#`N literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/n-caron-uc-bold.png b/resources/g2/font/latin/n-caron-uc-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2f8b59763fb1c55062036a850266bfe7bb6e4b GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRY#0(@anEQ7CDV_kI5Z6@Q^bUsq{~0=rjsLg* z{Tl-mXDkWw3ubV5b|VeMN%D4gVd!9$^#F1>3p^r=fu;z9FeAgPITAoY_7YEDSN6wD z5~4z;?T4+t1BLWFT^vI=t|uo1B_uqUbNIl5(4z+o-o9jPTj||s@s;85mJ7^0mzOhb f)MB~)!I*(T;XR+J|CHEGK%ESpu6{1-oD!M_E)L#0(@^7p<8Gq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?c#9>E@pFSS-H9`d*;{yc7`m7_ VC!7wo@&&4A@O1TaS?83{1OP>BF2n!; literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/n-caron-uc-tiny.png b/resources/g2/font/latin/n-caron-uc-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..5d61b21ac304b89f93ba96d00aa007d4cb37b0c7 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJx#0(^tuSi=Bq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW? codepointOffsetMap = { { UnicodeChar::l_stroke, CSChar::l_stroke - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::n_acute_uc, CSChar::n_acute_uc - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::n_acute, CSChar::n_acute - CS_SPRITE_FONT_OFFSET }, + { UnicodeChar::n_caron_uc, SPR_G2_N_CARON_UPPER - SPR_CHAR_START }, + { UnicodeChar::n_caron, SPR_G2_N_CARON_LOWER - SPR_CHAR_START }, { UnicodeChar::o_double_acute_uc, SPR_G2_O_DOUBLE_ACUTE_UPPER - SPR_CHAR_START }, { UnicodeChar::o_double_acute, SPR_G2_O_DOUBLE_ACUTE_LOWER - SPR_CHAR_START }, { UnicodeChar::s_acute_uc, CSChar::s_acute_uc - CS_SPRITE_FONT_OFFSET }, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 392638a413..cad340541b 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -917,8 +917,11 @@ enum SPR_G2_D_CARON_LOWER = SPR_G2_CHAR_BEGIN + 71, SPR_G2_E_CARON_UPPER = SPR_G2_CHAR_BEGIN + 72, SPR_G2_E_CARON_LOWER = SPR_G2_CHAR_BEGIN + 73, + + SPR_G2_N_CARON_UPPER = SPR_G2_CHAR_BEGIN + 74, + SPR_G2_N_CARON_LOWER = SPR_G2_CHAR_BEGIN + 75, - SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 74, + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 76, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From fd1f763b83f91a172da60cb172231d71b642335c Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 24 Mar 2019 21:57:56 +0100 Subject: [PATCH 109/506] Add R with caron --- resources/g2/font/latin/r-caron-bold.png | Bin 0 -> 172 bytes resources/g2/font/latin/r-caron-small.png | Bin 0 -> 171 bytes resources/g2/font/latin/r-caron-tiny.png | Bin 0 -> 171 bytes resources/g2/font/latin/r-caron-uc-bold.png | Bin 0 -> 184 bytes resources/g2/font/latin/r-caron-uc-small.png | Bin 0 -> 182 bytes resources/g2/font/latin/r-caron-uc-tiny.png | Bin 0 -> 172 bytes resources/g2/sprites.json | 36 +++++++++++++++++++ src/openrct2/drawing/Font.cpp | 2 ++ src/openrct2/sprites.h | 5 +-- 9 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 resources/g2/font/latin/r-caron-bold.png create mode 100644 resources/g2/font/latin/r-caron-small.png create mode 100644 resources/g2/font/latin/r-caron-tiny.png create mode 100644 resources/g2/font/latin/r-caron-uc-bold.png create mode 100644 resources/g2/font/latin/r-caron-uc-small.png create mode 100644 resources/g2/font/latin/r-caron-uc-tiny.png diff --git a/resources/g2/font/latin/r-caron-bold.png b/resources/g2/font/latin/r-caron-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..65dbf1c4f8f16cb30ace0a37b79d99609098dc2a GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ##0(@~B^+M>q<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?&Xw25&~=wFepAZHaO$x#Kyzm{g_p5`Mdlupc)2GS3j3^ HP6oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?;_iv_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zB}9}}6T0)30fkgOT^vI=t|vc;Iq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?J+R>D0fViLiE)gF*D$rMWS2;5y2-}Qkdw`^ U`Q%mouR!Gtp00i_>zopr0OYJP7XSbN literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/r-caron-uc-tiny.png b/resources/g2/font/latin/r-caron-uc-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..48c6632cf4b46f5b7bda518c02cbd58bb2c25b5f GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c#0(^T=HFcbq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW? codepointOffsetMap = { { UnicodeChar::n_caron, SPR_G2_N_CARON_LOWER - SPR_CHAR_START }, { UnicodeChar::o_double_acute_uc, SPR_G2_O_DOUBLE_ACUTE_UPPER - SPR_CHAR_START }, { UnicodeChar::o_double_acute, SPR_G2_O_DOUBLE_ACUTE_LOWER - SPR_CHAR_START }, + { UnicodeChar::r_caron_uc, SPR_G2_R_CARON_UPPER - SPR_CHAR_START }, + { UnicodeChar::r_caron, SPR_G2_R_CARON_LOWER - SPR_CHAR_START }, { UnicodeChar::s_acute_uc, CSChar::s_acute_uc - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::s_acute, CSChar::s_acute - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::s_cedilla_uc, SPR_G2_S_CEDILLA_UPPER - SPR_CHAR_START }, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index cad340541b..98af5976f7 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -917,11 +917,12 @@ enum SPR_G2_D_CARON_LOWER = SPR_G2_CHAR_BEGIN + 71, SPR_G2_E_CARON_UPPER = SPR_G2_CHAR_BEGIN + 72, SPR_G2_E_CARON_LOWER = SPR_G2_CHAR_BEGIN + 73, - SPR_G2_N_CARON_UPPER = SPR_G2_CHAR_BEGIN + 74, SPR_G2_N_CARON_LOWER = SPR_G2_CHAR_BEGIN + 75, + SPR_G2_R_CARON_UPPER = SPR_G2_CHAR_BEGIN + 76, + SPR_G2_R_CARON_LOWER = SPR_G2_CHAR_BEGIN + 77, - SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 76, + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 78, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From ef5472c5665857dca69bb6632030d5f827a44756 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 25 Mar 2019 16:15:33 +0100 Subject: [PATCH 110/506] Add S with caron --- resources/g2/font/latin/s-caron-bold.png | Bin 0 -> 183 bytes resources/g2/font/latin/s-caron-small.png | Bin 0 -> 178 bytes resources/g2/font/latin/s-caron-tiny.png | Bin 0 -> 179 bytes resources/g2/font/latin/s-caron-uc-bold.png | Bin 0 -> 187 bytes resources/g2/font/latin/s-caron-uc-small.png | Bin 0 -> 182 bytes resources/g2/font/latin/s-caron-uc-tiny.png | Bin 0 -> 173 bytes resources/g2/sprites.json | 36 +++++++++++++++++++ src/openrct2/drawing/Font.cpp | 2 ++ src/openrct2/sprites.h | 6 ++-- 9 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 resources/g2/font/latin/s-caron-bold.png create mode 100644 resources/g2/font/latin/s-caron-small.png create mode 100644 resources/g2/font/latin/s-caron-tiny.png create mode 100644 resources/g2/font/latin/s-caron-uc-bold.png create mode 100644 resources/g2/font/latin/s-caron-uc-small.png create mode 100644 resources/g2/font/latin/s-caron-uc-tiny.png diff --git a/resources/g2/font/latin/s-caron-bold.png b/resources/g2/font/latin/s-caron-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..14600a8dce2e550d369071446db76f492ae0c83a GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)L#0(@^7p<8Gq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?)AK;}44$rjF6*2UngF%aG1UM7 literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/s-caron-small.png b/resources/g2/font/latin/s-caron-small.png new file mode 100644 index 0000000000000000000000000000000000000000..073d4d9c0f32c37cc0565230cf3039b6a3b48c3d GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ##0(@~B^+M>q<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?FVdQ&MBb@0OYDJod5s; literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/s-caron-tiny.png b/resources/g2/font/latin/s-caron-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..b6b358aeac5fb0df95fc5abf7a7fbc6a4054f8e3 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c#0(^T=HFcbq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?fx8LV)c7gWg8R&kTo4*x01m7!)=#7oG~9 RYz>P)FIWHo literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/s-caron-uc-bold.png b/resources/g2/font/latin/s-caron-uc-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..e46b2b1bb26fb740189a89ee2dc74515a742dcba GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^96-#?#0(_uzp88lQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHYyc+9sWD1`26-x;Tb#Tu)AjI&eVp@PVyOj;3=GZ%MVS6jW%tR?@ceAy06!#2b4C ZhT5kb>$;A1-2&=i@O1TaS?83{1OVn6HLm~w literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/s-caron-uc-small.png b/resources/g2/font/latin/s-caron-uc-small.png new file mode 100644 index 0000000000000000000000000000000000000000..aef1fb5e4d25beb4efd0084a2fd883dcb93d62d2 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ-#0(@AZA4gs6i&Xw25&~=wFeph&q=_1=kWILdlQ1KkA&L3uPf3QHGoac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?D>e*DZzUOQ-m`vq&aiPUP!)rx LtDnm{r-UW|CKfK* literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index bec93c5b82..f00aae5fac 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -820,6 +820,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/s-caron-uc-small.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/s-caron-small.png", + "y_offset": 0, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-small.png", "y_offset": 0, @@ -1253,6 +1265,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/s-caron-uc-bold.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/s-caron-bold.png", + "y_offset": 0, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-bold.png", "y_offset": 0, @@ -1694,6 +1718,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/s-caron-uc-tiny.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/s-caron-tiny.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-tiny.png", "y_offset": 0, diff --git a/src/openrct2/drawing/Font.cpp b/src/openrct2/drawing/Font.cpp index 735ca267d1..ded9cf5358 100644 --- a/src/openrct2/drawing/Font.cpp +++ b/src/openrct2/drawing/Font.cpp @@ -67,6 +67,8 @@ static const std::map codepointOffsetMap = { { UnicodeChar::s_acute, CSChar::s_acute - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::s_cedilla_uc, SPR_G2_S_CEDILLA_UPPER - SPR_CHAR_START }, { UnicodeChar::s_cedilla, SPR_G2_S_CEDILLA_LOWER - SPR_CHAR_START }, + { UnicodeChar::s_caron_uc, SPR_G2_S_CARON_UPPER - SPR_CHAR_START }, + { UnicodeChar::s_caron, SPR_G2_S_CARON_LOWER - SPR_CHAR_START }, { UnicodeChar::u_double_acute_uc, SPR_G2_U_DOUBLE_ACUTE_UPPER - SPR_CHAR_START }, { UnicodeChar::u_double_acute, SPR_G2_U_DOUBLE_ACUTE_LOWER - SPR_CHAR_START }, { UnicodeChar::z_acute_uc, CSChar::z_acute_uc - CS_SPRITE_FONT_OFFSET }, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 98af5976f7..0fbf162cdf 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -921,8 +921,10 @@ enum SPR_G2_N_CARON_LOWER = SPR_G2_CHAR_BEGIN + 75, SPR_G2_R_CARON_UPPER = SPR_G2_CHAR_BEGIN + 76, SPR_G2_R_CARON_LOWER = SPR_G2_CHAR_BEGIN + 77, - - SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 78, + SPR_G2_S_CARON_UPPER = SPR_G2_CHAR_BEGIN + 78, + SPR_G2_S_CARON_LOWER = SPR_G2_CHAR_BEGIN + 79, + + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 80, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From 92d348fe43ef4eae1e2e27d3c99118c8b1271273 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 25 Mar 2019 16:51:47 +0100 Subject: [PATCH 111/506] Add T with caron --- resources/g2/font/latin/t-caron-bold.png | Bin 0 -> 186 bytes resources/g2/font/latin/t-caron-small.png | Bin 0 -> 180 bytes resources/g2/font/latin/t-caron-tiny.png | Bin 0 -> 176 bytes resources/g2/font/latin/t-caron-uc-bold.png | Bin 0 -> 177 bytes resources/g2/font/latin/t-caron-uc-small.png | Bin 0 -> 177 bytes resources/g2/font/latin/t-caron-uc-tiny.png | Bin 0 -> 170 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/g2/font/latin/t-caron-bold.png create mode 100644 resources/g2/font/latin/t-caron-small.png create mode 100644 resources/g2/font/latin/t-caron-tiny.png create mode 100644 resources/g2/font/latin/t-caron-uc-bold.png create mode 100644 resources/g2/font/latin/t-caron-uc-small.png create mode 100644 resources/g2/font/latin/t-caron-uc-tiny.png diff --git a/resources/g2/font/latin/t-caron-bold.png b/resources/g2/font/latin/t-caron-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..ec6823604cf867c8dcc00fef7a1eb54618da7d3f GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)L#0(@^7p<8Gq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?zopr01hHDoB#j- literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/t-caron-small.png b/resources/g2/font/latin/t-caron-small.png new file mode 100644 index 0000000000000000000000000000000000000000..bbfd511a1292d2c2f4d77f333609d666fe3f9218 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ(#0(^JzHH?KQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@uLG}_)Usv|W z%#!@V3h5c`dO#sXPZ!4!j_b(*83{8&4;ZX%NIb{bX33*q(%tCzm4VrwnIUrq+hu>v Rjio@v44$rjF6*2UngGz$Ew=yw literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/t-caron-tiny.png b/resources/g2/font/latin/t-caron-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..10ce1357367126221cacaefdaa8f9ddccdd57601 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1p#0(_&p3JWWQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@uLG}_)Usv|W z%#!>P;x>xEUjc<=JzX3_IIbrLBqhwKY)G_XJ}kr5CdtF|iigLBhe5ZTx$1wiXaZ0n NgQu&X%Q~loCIB#MD`)@! literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/t-caron-uc-bold.png b/resources/g2/font/latin/t-caron-uc-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..8ffebc1330ede97bb07a4eeeda4fea1a18126995 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^96-#?#0(_uzp88lQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHciI1Tt>b0EOf{T^vI=t|vc;I_E)T#0(_Q{j0YIQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHckqS6rpPt45E8AXnqVPNR6V*hga#=R(@ ON(N6?KbLh*2~7a;H89Bl literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/t-caron-uc-tiny.png b/resources/g2/font/latin/t-caron-uc-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3a0219503e19b5b0f4ff0a98b2d5986263a040 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c#0(^T=HFcbq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?g{`Dpb`d8S3j3^ HP6 Date: Mon, 25 Mar 2019 16:51:27 +0100 Subject: [PATCH 112/506] Add U with ring --- resources/g2/font/latin/u-ring-bold.png | Bin 0 -> 180 bytes resources/g2/font/latin/u-ring-small.png | Bin 0 -> 174 bytes resources/g2/font/latin/u-ring-tiny.png | Bin 0 -> 172 bytes resources/g2/font/latin/u-ring-uc-bold.png | Bin 0 -> 194 bytes resources/g2/font/latin/u-ring-uc-small.png | Bin 0 -> 184 bytes resources/g2/font/latin/u-ring-uc-tiny.png | Bin 0 -> 171 bytes resources/g2/sprites.json | 72 ++++++++++++++++++++ src/openrct2/drawing/Font.cpp | 4 ++ src/openrct2/sprites.h | 6 +- 9 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 resources/g2/font/latin/u-ring-bold.png create mode 100644 resources/g2/font/latin/u-ring-small.png create mode 100644 resources/g2/font/latin/u-ring-tiny.png create mode 100644 resources/g2/font/latin/u-ring-uc-bold.png create mode 100644 resources/g2/font/latin/u-ring-uc-small.png create mode 100644 resources/g2/font/latin/u-ring-uc-tiny.png diff --git a/resources/g2/font/latin/u-ring-bold.png b/resources/g2/font/latin/u-ring-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..d818014dcfd5bd6e7f3862b1f55b7dbef1f6610e GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)T#0(_Q{j0YIQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHWPsCDXJ&0fiJjT^vI=t|uoXB|NY>upsQff}IVCQ9Mk(y@>(32@mWU7^(s|JQm1p RxC&Iv;OXk;vd$@?2>?uvFV_G7 literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/u-ring-small.png b/resources/g2/font/latin/u-ring-small.png new file mode 100644 index 0000000000000000000000000000000000000000..3f3afb46589ec9199c654c5a7e3e08d47c34104b GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ##0(@~B^+M>q<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?3p^r=fu;z9FeAgPITAoY_7YEDSN6xu zlKd*Vo%f=b1BLWGT^vI=t|upCBqStwB_v#!bM%0L?N^4wUzR(p;W~JEnq0yRsj3D? g(>aZe|M{62#NYEC+Agm10jQP1)78&qol`;+08xWC=>Px# literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/u-ring-uc-small.png b/resources/g2/font/latin/u-ring-uc-small.png new file mode 100644 index 0000000000000000000000000000000000000000..581629045c9a925153750c62e1404949154f7973 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^96-#?#0(_uzp88lQak}ZA+D*q=^YIJ|1)$L8~<_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHeJDE8V25fI_OCE{-7_*OL>n5+3Lz1k66TAo`%ef6K!%r2?}So?BqXu5zx1fuY%p VL&NoY^-`b)22WQ%mvv4FO#sa$F;M^j literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/u-ring-uc-tiny.png b/resources/g2/font/latin/u-ring-uc-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..908bb602141f0f58343721d69cd17c70a27a45e4 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c#0(^T=HFcbq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW? codepointOffsetMap = { { UnicodeChar::s_cedilla, SPR_G2_S_CEDILLA_LOWER - SPR_CHAR_START }, { UnicodeChar::s_caron_uc, SPR_G2_S_CARON_UPPER - SPR_CHAR_START }, { UnicodeChar::s_caron, SPR_G2_S_CARON_LOWER - SPR_CHAR_START }, + { UnicodeChar::t_caron_uc, SPR_G2_T_CARON_UPPER - SPR_CHAR_START }, + { UnicodeChar::t_caron, SPR_G2_T_CARON_LOWER - SPR_CHAR_START }, + { UnicodeChar::u_ring_uc, SPR_G2_U_RING_UPPER - SPR_CHAR_START }, + { UnicodeChar::u_ring, SPR_G2_U_RING_LOWER - SPR_CHAR_START }, { UnicodeChar::u_double_acute_uc, SPR_G2_U_DOUBLE_ACUTE_UPPER - SPR_CHAR_START }, { UnicodeChar::u_double_acute, SPR_G2_U_DOUBLE_ACUTE_LOWER - SPR_CHAR_START }, { UnicodeChar::z_acute_uc, CSChar::z_acute_uc - CS_SPRITE_FONT_OFFSET }, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 0fbf162cdf..9600cc522c 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -923,8 +923,12 @@ enum SPR_G2_R_CARON_LOWER = SPR_G2_CHAR_BEGIN + 77, SPR_G2_S_CARON_UPPER = SPR_G2_CHAR_BEGIN + 78, SPR_G2_S_CARON_LOWER = SPR_G2_CHAR_BEGIN + 79, + SPR_G2_T_CARON_UPPER = SPR_G2_CHAR_BEGIN + 80, + SPR_G2_T_CARON_LOWER = SPR_G2_CHAR_BEGIN + 81, + SPR_G2_U_RING_UPPER = SPR_G2_CHAR_BEGIN + 82, + SPR_G2_U_RING_LOWER = SPR_G2_CHAR_BEGIN + 83, - SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 80, + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 84, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From ff12d5c2028b2375ca1e70e48adc16f2e9142e54 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 25 Mar 2019 17:02:35 +0100 Subject: [PATCH 113/506] Add Z with caron --- resources/g2/font/latin/z-caron-bold.png | Bin 0 -> 180 bytes resources/g2/font/latin/z-caron-small.png | Bin 0 -> 182 bytes resources/g2/font/latin/z-caron-tiny.png | Bin 0 -> 171 bytes resources/g2/font/latin/z-caron-uc-bold.png | Bin 0 -> 190 bytes resources/g2/font/latin/z-caron-uc-small.png | Bin 0 -> 185 bytes resources/g2/font/latin/z-caron-uc-tiny.png | Bin 0 -> 176 bytes resources/g2/sprites.json | 36 +++++++++++++++++++ src/openrct2/drawing/Font.cpp | 2 ++ src/openrct2/sprites.h | 4 ++- 9 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 resources/g2/font/latin/z-caron-bold.png create mode 100644 resources/g2/font/latin/z-caron-small.png create mode 100644 resources/g2/font/latin/z-caron-tiny.png create mode 100644 resources/g2/font/latin/z-caron-uc-bold.png create mode 100644 resources/g2/font/latin/z-caron-uc-small.png create mode 100644 resources/g2/font/latin/z-caron-uc-tiny.png diff --git a/resources/g2/font/latin/z-caron-bold.png b/resources/g2/font/latin/z-caron-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..f4a69f936d7f69d88b57e1c98aa7d88eb6bd2294 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)L#0(@^7p<8Gq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?q<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?J+R>F0fVg#2iG+;er9O4Vm_>6aQz_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@uLG}_)Usv|W z%#!@(jJIBvT>}b9c)B=-a9mG*kdP3NoG_!R;ov8RDT(J97}Qp?m}~FRGY6_+@O1Ta JS?83{1OUqvEiM26 literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/z-caron-uc-bold.png b/resources/g2/font/latin/z-caron-uc-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..9503ac8284e8fde101cd577124e73162390a3c9b GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRY#0(@anEQ7CDV_kI5Z6@Q^bUsq{~0=rjsLg* z{Tl-mXDkWw3ubV5b|VeMN%D4gVd!9$^#F1>3p^r=fu;z9FeAgPITAoY_7YEDSN6xu zlKf`sg8vU?0fn?ZT^vI=t|vc;I(T4#)VTu-wstipX1!o!`@ND~Vn##FIf(@oVlF&7 c|K>9?+=}2_!@hljQC0!qCAg>jC6&7I;J!15FVIVMc~ob0mO*>?NMQuI!JQ zCHYN_!ud;`fI@1XE{-7_*OMPa9atcBc)`}D#4L;Ezr}3JEP3Xz^1Nb~NON@g$H36d Wz**kAaP=Ob4hBzGKbLh*2~7Y2fH8ak literal 0 HcmV?d00001 diff --git a/resources/g2/font/latin/z-caron-uc-tiny.png b/resources/g2/font/latin/z-caron-uc-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..5bff847a48c20cc805e6c02baa8abba4648329bc GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c#0(^T=HFcbq<8{+LR?dI(>oac|7YkhHvZrK z_iqePoUtUxFPOpM*^M+1C&}C0g`tC0)&t1lEbxddW?p0+YJlFz;kcgsAR!?jIblXs!@*As%~s5ZbqsFLV`MPSXSuZZdnCvz N22WQ%mvv4FO#sRHFg*YO literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 394671e5e5..f1b78eacbb 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -856,6 +856,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/z-caron-uc-small.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/z-caron-small.png", + "y_offset": 0, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-small.png", "y_offset": 0, @@ -1325,6 +1337,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/z-caron-uc-bold.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/z-caron-bold.png", + "y_offset": 0, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-bold.png", "y_offset": 0, @@ -1802,6 +1826,18 @@ "palette": "keep", "forceBmp": true }, + { + "path": "font/latin/z-caron-uc-tiny.png", + "y_offset": -1, + "palette": "keep", + "forceBmp": true + }, + { + "path": "font/latin/z-caron-tiny.png", + "y_offset": 0, + "palette": "keep", + "forceBmp": true + }, { "path": "font/rouble-tiny.png", "y_offset": 0, diff --git a/src/openrct2/drawing/Font.cpp b/src/openrct2/drawing/Font.cpp index ccbce487d6..4700057ab9 100644 --- a/src/openrct2/drawing/Font.cpp +++ b/src/openrct2/drawing/Font.cpp @@ -79,6 +79,8 @@ static const std::map codepointOffsetMap = { { UnicodeChar::z_acute, CSChar::z_acute - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::z_dot_uc, CSChar::z_dot_uc - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::z_dot, CSChar::z_dot - CS_SPRITE_FONT_OFFSET }, + { UnicodeChar::z_caron_uc, SPR_G2_Z_CARON_UPPER - SPR_CHAR_START }, + { UnicodeChar::z_caron, SPR_G2_Z_CARON_LOWER - SPR_CHAR_START }, { UnicodeChar::f_with_hook_uc, 'F' - CS_SPRITE_FONT_OFFSET }, { UnicodeChar::s_comma_uc, SPR_G2_S_CEDILLA_UPPER - SPR_CHAR_START }, // No visual difference { UnicodeChar::s_comma, SPR_G2_S_CEDILLA_LOWER - SPR_CHAR_START }, // Ditto diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 9600cc522c..2cfec914c0 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -927,8 +927,10 @@ enum SPR_G2_T_CARON_LOWER = SPR_G2_CHAR_BEGIN + 81, SPR_G2_U_RING_UPPER = SPR_G2_CHAR_BEGIN + 82, SPR_G2_U_RING_LOWER = SPR_G2_CHAR_BEGIN + 83, + SPR_G2_Z_CARON_UPPER = SPR_G2_CHAR_BEGIN + 84, + SPR_G2_Z_CARON_LOWER = SPR_G2_CHAR_BEGIN + 85, - SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 84, + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 86, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From bbfa2570d5c3ae7b82b3ba20a653bd55cf457423 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 25 Mar 2019 17:03:12 +0100 Subject: [PATCH 114/506] Switch Czech to sprite font --- src/openrct2/localisation/Language.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/localisation/Language.cpp b/src/openrct2/localisation/Language.cpp index bdf2eb3604..cca9d7428b 100644 --- a/src/openrct2/localisation/Language.cpp +++ b/src/openrct2/localisation/Language.cpp @@ -28,7 +28,7 @@ const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = { "ca-ES", "Catalan", u8"Català", FAMILY_OPENRCT2_SPRITE, false }, // LANGUAGE_CATALAN { "zh-CN", "Chinese (Simplified)", "Chinese (Simplified)", FAMILY(&TTFFamilyChineseSimplified), false }, // LANGUAGE_CHINESE_SIMPLIFIED { "zh-TW", "Chinese (Traditional)", "Chinese (Traditional)", FAMILY(&TTFFamilyChineseTraditional), false }, // LANGUAGE_CHINESE_TRADITIONAL - { "cs-CZ", "Czech", "Czech", FAMILY(&TTFFamilySansSerif), false }, // LANGUAGE_CZECH + { "cs-CZ", "Czech", u8"Čeština", FAMILY_OPENRCT2_SPRITE, false }, // LANGUAGE_CZECH { "da-DK", "Danish", "Dansk", FAMILY_OPENRCT2_SPRITE, false }, // LANGUAGE_DANISH { "de-DE", "German", "Deutsch", FAMILY_OPENRCT2_SPRITE, false }, // LANGUAGE_GERMAN { "en-GB", "English (UK)", "English (UK)", FAMILY_OPENRCT2_SPRITE, false }, // LANGUAGE_ENGLISH_UK From 7f045918e18474974b7e28ee3e6f6203c174756c Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 25 Mar 2019 17:24:27 +0100 Subject: [PATCH 115/506] Fix formatting --- src/openrct2/sprites.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 2cfec914c0..50b8d1ec3b 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -929,7 +929,7 @@ enum SPR_G2_U_RING_LOWER = SPR_G2_CHAR_BEGIN + 83, SPR_G2_Z_CARON_UPPER = SPR_G2_CHAR_BEGIN + 84, SPR_G2_Z_CARON_LOWER = SPR_G2_CHAR_BEGIN + 85, - + SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 86, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, From ee6cee99ced85e3ea8f7a089411e5ce917a713a0 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 10:07:30 +0100 Subject: [PATCH 116/506] Update changelog --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e692bef16e..5b18c26b12 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8919] Allow setting ride price from console. +- Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). From d88d80335db620d0af8abc73d593cfc9547e8e2f Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 27 Mar 2019 10:09:14 +0100 Subject: [PATCH 117/506] Fix #8882: Submarine Ride does not count as indoors (#8964) --- distribution/changelog.txt | 1 + src/openrct2/network/Network.cpp | 2 +- src/openrct2/ride/RideRatings.cpp | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 5b18c26b12..190f3f2c91 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -8,6 +8,7 @@ - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. +- Fix: [#8882] Submarine Ride does not count as indoors (original bug). - Fix: [#8900] Peep tracking is not synchronized. - Fix: [#8947] Detection of AVX2 support. - Improved: Allow the use of numpad enter key for console and chat. diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index ade9764b8b..cc34606792 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 "10" +#define NETWORK_STREAM_VERSION "11" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index f0257b33d6..c2908d5ab8 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -4127,7 +4127,8 @@ static void ride_ratings_calculate_submarine_ride(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + // Originally, this was always to zero, even though the default vehicle is completely enclosed. + ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; } static void ride_ratings_calculate_river_rafts(Ride* ride) From 64e51cd34b9f06a9da30f9187272c5d970490321 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 11:30:18 +0100 Subject: [PATCH 118/506] Close #8965: Refactor ride->inversions --- src/openrct2-ui/windows/Ride.cpp | 4 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 6 +- src/openrct2/rct2/S6Exporter.cpp | 7 +- src/openrct2/rct2/S6Importer.cpp | 7 +- src/openrct2/ride/Ride.h | 11 +- src/openrct2/ride/RideRatings.cpp | 286 ++++++++++---------------- src/openrct2/ride/TrackDesignSave.cpp | 6 +- src/openrct2/ride/Vehicle.cpp | 9 +- 9 files changed, 138 insertions(+), 200 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 26a4af7ec9..b6bd0aa8ba 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -5583,7 +5583,7 @@ static void window_ride_measurements_paint(rct_window* w, rct_drawpixelinfo* dpi if (ride->type == RIDE_TYPE_MINI_GOLF) { // Holes - holes = ride->holes & 0x1F; + holes = ride->holes; gfx_draw_string_left(dpi, STR_HOLES, &holes, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } @@ -5707,7 +5707,7 @@ static void window_ride_measurements_paint(rct_window* w, rct_drawpixelinfo* dpi if (ride->type != RIDE_TYPE_MINI_GOLF) { // Inversions - inversions = ride->inversions & 0x1F; + inversions = ride->inversions; if (inversions != 0) { gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, COLOUR_BLACK, x, y); diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index b0e2f32211..464c88f9ee 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1800,7 +1800,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t // Peeps won't go on rides that aren't sufficiently undercover while it's raining. // The threshold is fairly low and only requires about 10-15% of the ride to be undercover. - if (climate_is_raining() && (ride->sheltered_eighths >> 5) < 3) + if (climate_is_raining() && (ride->sheltered_eighths & 0x7) < 3) { if (peepAtRide) { diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 920eeaea8f..7813518b64 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -944,7 +944,11 @@ private: dst->drops = src->num_drops; dst->start_drop_height = src->start_drop_height / 2; dst->highest_drop_height = src->highest_drop_height / 2; - dst->inversions = src->num_inversions; + if (dst->type == RIDE_TYPE_MINI_GOLF) + dst->holes = src->num_inversions & 0x1F; + else + dst->inversions = src->num_inversions & 0x1F; + dst->sheltered_eighths = src->num_inversions >> 5; dst->boat_hire_return_direction = src->boat_hire_return_direction; dst->boat_hire_return_position = src->boat_hire_return_position; dst->measurement_index = src->data_logging_index; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index f2daaff5a1..d3047598c6 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -560,8 +560,11 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->turn_count_default = src->turn_count_default; dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; - // Includes holes and (for some strange reason?!) sheltered_eights - dst->inversions = src->inversions; + if (dst->type == RIDE_TYPE_MINI_GOLF) + dst->inversions = src->holes & 0x1F; + else + dst->inversions = src->inversions & 0x1F; + dst->inversions |= (src->sheltered_eighths << 5); dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; dst->highest_drop_height = src->highest_drop_height; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 7da7a67c56..e2d6a37b31 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -608,8 +608,11 @@ public: dst->turn_count_default = src->turn_count_default; dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; - // Includes holes and (for some strange reason?!) sheltered_eights - dst->inversions = src->inversions; + if (dst->type == RIDE_TYPE_MINI_GOLF) + dst->holes = src->inversions & 0x1F; + else + dst->inversions = src->inversions & 0x1F; + dst->sheltered_eighths = src->inversions >> 5; dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; dst->highest_drop_height = src->highest_drop_height; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 52da75a93a..2bd37f4c92 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -233,14 +233,6 @@ struct Ride uint16_t turn_count_default; // X = current turn count uint16_t turn_count_banked; uint16_t turn_count_sloped; // X = number turns > 3 elements - union - { - uint8_t inversions; // (???X XXXX) - uint8_t holes; // (???X XXXX) - // This is a very rough approximation of how much of the ride is undercover. - // It reaches the maximum value of 7 at about 50% undercover and doesn't increase beyond that. - uint8_t sheltered_eighths; // (XXX?-????) - }; // Y is number of powered lifts, X is drops uint8_t drops; // (YYXX XXXX) uint8_t start_drop_height; @@ -352,6 +344,9 @@ struct Ride uint8_t current_issues; uint32_t last_issue_time; RideStation stations[MAX_STATIONS]; + uint8_t inversions; + uint8_t holes; + uint8_t sheltered_eighths; bool CanBreakDown() const; bool IsRide() const; diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index c2908d5ab8..1a879803eb 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1078,7 +1078,7 @@ static int32_t get_num_of_sheltered_eighths(Ride* ride) } } - int32_t dh = numShelteredEighths; + int32_t trackShelteredEighths = numShelteredEighths; rct_ride_entry* rideType = get_ride_entry(ride->subtype); if (rideType == nullptr) { @@ -1087,7 +1087,7 @@ static int32_t get_num_of_sheltered_eighths(Ride* ride) if (rideType->flags & RIDE_ENTRY_FLAG_COVERED_RIDE) numShelteredEighths = 7; - return (dh << 8) | numShelteredEighths; + return (trackShelteredEighths << 8) | numShelteredEighths; } static rating_tuple get_flat_turns_rating(Ride* ride) @@ -1261,7 +1261,7 @@ static rating_tuple ride_ratings_get_turns_ratings(Ride* ride) intensity += var_112_rating.intensity; nausea += var_112_rating.nausea; - rating_tuple inversions_rating = get_inversions_ratings(ride->inversions & 0x1F); + rating_tuple inversions_rating = get_inversions_ratings(ride->inversions); excitement += inversions_rating.excitement; intensity += inversions_rating.intensity; nausea += inversions_rating.nausea; @@ -1677,12 +1677,12 @@ static void ride_ratings_calculate_spiral_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 12, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -1697,8 +1697,7 @@ static void ride_ratings_calculate_spiral_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_stand_up_roller_coaster(Ride* ride) @@ -1736,8 +1735,7 @@ static void ride_ratings_calculate_stand_up_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_suspended_swinging_coaster(Ride* ride) @@ -1777,8 +1775,7 @@ static void ride_ratings_calculate_suspended_swinging_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_inverted_roller_coaster(Ride* ride) @@ -1804,12 +1801,12 @@ static void ride_ratings_calculate_inverted_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 15657); ride_ratings_apply_scenery(&ratings, ride, 8366); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 12, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 30), 2, 2, 2); ride_ratings_apply_excessive_lateral_g_penalty(&ratings, ride); @@ -1821,8 +1818,7 @@ static void ride_ratings_calculate_inverted_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_junior_roller_coaster(Ride* ride) @@ -1860,8 +1856,7 @@ static void ride_ratings_calculate_junior_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_miniature_railway(Ride* ride) @@ -1896,8 +1891,7 @@ static void ride_ratings_calculate_miniature_railway(Ride* ride) if (((edx >> 8) & 0xFF) >= 4) ride->excitement /= 4; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_monorail(Ride* ride) @@ -1932,8 +1926,7 @@ static void ride_ratings_calculate_monorail(Ride* ride) if (((edx >> 8) & 0xFF) >= 4) ride->excitement /= 4; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mini_suspended_coaster(Ride* ride) @@ -1972,8 +1965,7 @@ static void ride_ratings_calculate_mini_suspended_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_boat_hire(Ride* ride) @@ -2005,8 +1997,7 @@ static void ride_ratings_calculate_boat_hire(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_wooden_wild_mouse(Ride* ride) @@ -2047,8 +2038,7 @@ static void ride_ratings_calculate_wooden_wild_mouse(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_steeplechase(Ride* ride) @@ -2088,8 +2078,7 @@ static void ride_ratings_calculate_steeplechase(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_car_ride(Ride* ride) @@ -2123,8 +2112,7 @@ static void ride_ratings_calculate_car_ride(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_launched_freefall(Ride* ride) @@ -2175,8 +2163,7 @@ static void ride_ratings_calculate_launched_freefall(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_bobsleigh_coaster(Ride* ride) @@ -2214,8 +2201,7 @@ static void ride_ratings_calculate_bobsleigh_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_observation_tower(Ride* ride) @@ -2241,8 +2227,7 @@ static void ride_ratings_calculate_observation_tower(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; int32_t edx = get_num_of_sheltered_eighths(ride); if (((edx >> 8) & 0xFF) >= 5) @@ -2272,12 +2257,12 @@ static void ride_ratings_calculate_looping_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 14, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 10), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -2292,8 +2277,7 @@ static void ride_ratings_calculate_looping_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_dinghy_slide(Ride* ride) @@ -2331,8 +2315,7 @@ static void ride_ratings_calculate_dinghy_slide(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mine_train_coaster(Ride* ride) @@ -2372,8 +2355,7 @@ static void ride_ratings_calculate_mine_train_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_chairlift(Ride* ride) @@ -2411,12 +2393,11 @@ static void ride_ratings_calculate_chairlift(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t edx = get_num_of_sheltered_eighths(ride); - if (((edx >> 8) & 0xFF) >= 4) + int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); + if (((shelteredEighths >> 8) & 0xFF) >= 4) ride->excitement /= 4; - ride->inversions &= 0x1F; - ride->inversions |= edx << 5; + ride->sheltered_eighths = shelteredEighths; } static void ride_ratings_calculate_corkscrew_roller_coaster(Ride* ride) @@ -2442,12 +2423,12 @@ static void ride_ratings_calculate_corkscrew_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 12, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -2462,8 +2443,7 @@ static void ride_ratings_calculate_corkscrew_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_maze(Ride* ride) @@ -2489,8 +2469,7 @@ static void ride_ratings_calculate_maze(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_spiral_slide(Ride* ride) @@ -2519,8 +2498,7 @@ static void ride_ratings_calculate_spiral_slide(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 2 << 5; + ride->sheltered_eighths = 2; } static void ride_ratings_calculate_go_karts(Ride* ride) @@ -2557,12 +2535,11 @@ static void ride_ratings_calculate_go_karts(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t edx = get_num_of_sheltered_eighths(ride); + int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); - ride->inversions &= 0x1F; - ride->inversions |= edx << 5; + ride->sheltered_eighths = shelteredEighths; - if (((edx >> 8) & 0xFF) >= 6) + if (((shelteredEighths >> 8) & 0xFF) >= 6) ride->excitement /= 2; } @@ -2595,8 +2572,7 @@ static void ride_ratings_calculate_log_flume(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_river_rapids(Ride* ride) @@ -2629,8 +2605,7 @@ static void ride_ratings_calculate_river_rapids(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_dodgems(Ride* ride) @@ -2665,8 +2640,7 @@ static void ride_ratings_calculate_dodgems(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_pirate_ship(Ride* ride) @@ -2691,8 +2665,7 @@ static void ride_ratings_calculate_pirate_ship(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_inverter_ship(Ride* ride) @@ -2717,8 +2690,7 @@ static void ride_ratings_calculate_inverter_ship(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_food_stall(Ride* ride) @@ -2758,8 +2730,7 @@ static void ride_ratings_calculate_merry_go_round(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_information_kiosk(Ride* ride) @@ -2793,8 +2764,7 @@ static void ride_ratings_calculate_ferris_wheel(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_motion_simulator(Ride* ride) @@ -2827,8 +2797,7 @@ static void ride_ratings_calculate_motion_simulator(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_3d_cinema(Ride* ride) @@ -2868,8 +2837,7 @@ static void ride_ratings_calculate_3d_cinema(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths |= 7; } static void ride_ratings_calculate_top_spin(Ride* ride) @@ -2911,8 +2879,7 @@ static void ride_ratings_calculate_top_spin(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_space_rings(Ride* ride) @@ -2934,8 +2901,7 @@ static void ride_ratings_calculate_space_rings(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_reverse_freefall_coaster(Ride* ride) @@ -2965,8 +2931,7 @@ static void ride_ratings_calculate_reverse_freefall_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_lift(Ride* ride) @@ -2996,8 +2961,7 @@ static void ride_ratings_calculate_lift(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; if ((get_num_of_sheltered_eighths(ride) >> 8) >= 5) ride->excitement /= 4; @@ -3038,8 +3002,7 @@ static void ride_ratings_calculate_vertical_drop_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_cash_machine(Ride* ride) @@ -3067,8 +3030,7 @@ static void ride_ratings_calculate_twist(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_haunted_house(Ride* ride) @@ -3092,8 +3054,7 @@ static void ride_ratings_calculate_haunted_house(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0xE0; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_flying_roller_coaster(Ride* ride) @@ -3119,12 +3080,12 @@ static void ride_ratings_calculate_flying_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ratings.excitement /= 2; ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 1, 1); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 1, 1); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 1, 1); @@ -3138,8 +3099,7 @@ static void ride_ratings_calculate_flying_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_virginia_reel(Ride* ride) @@ -3176,8 +3136,7 @@ static void ride_ratings_calculate_virginia_reel(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_splash_boats(Ride* ride) @@ -3209,8 +3168,7 @@ static void ride_ratings_calculate_splash_boats(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mini_helicopters(Ride* ride) @@ -3244,8 +3202,7 @@ static void ride_ratings_calculate_mini_helicopters(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 6 << 5; + ride->sheltered_eighths = 6; } static void ride_ratings_calculate_lay_down_roller_coaster(Ride* ride) @@ -3271,7 +3228,7 @@ static void ride_ratings_calculate_lay_down_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ratings.excitement /= 4; ratings.intensity /= 2; @@ -3280,7 +3237,7 @@ static void ride_ratings_calculate_lay_down_roller_coaster(Ride* ride) ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -3295,8 +3252,7 @@ static void ride_ratings_calculate_lay_down_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_suspended_monorail(Ride* ride) @@ -3327,12 +3283,11 @@ static void ride_ratings_calculate_suspended_monorail(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t edx = get_num_of_sheltered_eighths(ride); - if (((edx >> 8) & 0xFF) >= 4) + int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); + if (((shelteredEighths >> 8) & 0xFF) >= 4) ride->excitement /= 4; - ride->inversions &= 0x1F; - ride->inversions |= edx << 5; + ride->sheltered_eighths = shelteredEighths; } static void ride_ratings_calculate_reverser_roller_coaster(Ride* ride) @@ -3380,8 +3335,7 @@ static void ride_ratings_calculate_reverser_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_heartline_twister_coaster(Ride* ride) @@ -3407,7 +3361,7 @@ static void ride_ratings_calculate_heartline_twister_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 9841); ride_ratings_apply_scenery(&ratings, ride, 3904); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ratings.excitement /= 4; ride_ratings_apply_num_drops_penalty(&ratings, ride, 1, 4, 1, 1); @@ -3421,8 +3375,7 @@ static void ride_ratings_calculate_heartline_twister_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mini_golf(Ride* ride) @@ -3442,10 +3395,10 @@ static void ride_ratings_calculate_mini_golf(Ride* ride) ride_ratings_apply_scenery(&ratings, ride, 27887); // Apply golf holes factor - ride_ratings_add(&ratings, (ride->holes & 0x1F) * 5, 0, 0); + ride_ratings_add(&ratings, (ride->holes) * 5, 0, 0); // Apply no golf holes penalty - if ((ride->inversions & 0x1F) == 0) + if (ride->holes == 0) { ratings.excitement /= 8; ratings.intensity /= 2; @@ -3460,8 +3413,7 @@ static void ride_ratings_calculate_mini_golf(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_first_aid(Ride* ride) @@ -3491,8 +3443,7 @@ static void ride_ratings_calculate_circus_show(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 7 << 5; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_ghost_train(Ride* ride) @@ -3525,8 +3476,7 @@ static void ride_ratings_calculate_ghost_train(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_twister_roller_coaster(Ride* ride) @@ -3552,12 +3502,12 @@ static void ride_ratings_calculate_twister_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 12, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -3572,8 +3522,7 @@ static void ride_ratings_calculate_twister_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_wooden_roller_coaster(Ride* ride) @@ -3613,8 +3562,7 @@ static void ride_ratings_calculate_wooden_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_side_friction_roller_coaster(Ride* ride) @@ -3653,8 +3601,7 @@ static void ride_ratings_calculate_side_friction_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_wild_mouse(Ride* ride) @@ -3694,8 +3641,7 @@ static void ride_ratings_calculate_wild_mouse(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_multi_dimension_roller_coaster(Ride* ride) @@ -3721,14 +3667,14 @@ static void ride_ratings_calculate_multi_dimension_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ratings.excitement /= 4; ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 1, 1); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 1, 1); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 1, 1); ride_ratings_apply_excessive_lateral_g_penalty(&ratings, ride); @@ -3740,8 +3686,7 @@ static void ride_ratings_calculate_multi_dimension_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_giga_coaster(Ride* ride) @@ -3767,12 +3712,12 @@ static void ride_ratings_calculate_giga_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 16, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 40), 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -3787,8 +3732,7 @@ static void ride_ratings_calculate_giga_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_roto_drop(Ride* ride) @@ -3816,8 +3760,7 @@ static void ride_ratings_calculate_roto_drop(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_flying_saucers(Ride* ride) @@ -3855,8 +3798,7 @@ static void ride_ratings_calculate_flying_saucers(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_crooked_house(Ride* ride) @@ -3880,8 +3822,7 @@ static void ride_ratings_calculate_crooked_house(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0xE0; + ride->sheltered_eighths = 7; } static void ride_ratings_calculate_monorail_cycles(Ride* ride) @@ -3915,8 +3856,7 @@ static void ride_ratings_calculate_monorail_cycles(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_compact_inverted_coaster(Ride* ride) @@ -3942,12 +3882,12 @@ static void ride_ratings_calculate_compact_inverted_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 15657); ride_ratings_apply_scenery(&ratings, ride, 8366); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 12, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_max_negative_g_penalty(&ratings, ride, FIXED_2DP(0, 30), 2, 2, 2); ride_ratings_apply_excessive_lateral_g_penalty(&ratings, ride); @@ -3959,8 +3899,7 @@ static void ride_ratings_calculate_compact_inverted_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_water_coaster(Ride* ride) @@ -4001,8 +3940,7 @@ static void ride_ratings_calculate_water_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_air_powered_vertical_coaster(Ride* ride) @@ -4033,8 +3971,7 @@ static void ride_ratings_calculate_air_powered_vertical_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_inverted_hairpin_coaster(Ride* ride) @@ -4075,8 +4012,7 @@ static void ride_ratings_calculate_inverted_hairpin_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_magic_carpet(Ride* ride) @@ -4101,8 +4037,7 @@ static void ride_ratings_calculate_magic_carpet(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 0 << 5; + ride->sheltered_eighths = 0; } static void ride_ratings_calculate_submarine_ride(Ride* ride) @@ -4126,9 +4061,8 @@ static void ride_ratings_calculate_submarine_ride(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; // Originally, this was always to zero, even though the default vehicle is completely enclosed. - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_river_rafts(Ride* ride) @@ -4158,8 +4092,7 @@ static void ride_ratings_calculate_river_rafts(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_enterprise(Ride* ride) @@ -4188,8 +4121,7 @@ static void ride_ratings_calculate_enterprise(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= 3 << 5; + ride->sheltered_eighths = 3; } static void ride_ratings_calculate_inverted_impulse_coaster(Ride* ride) @@ -4226,8 +4158,7 @@ static void ride_ratings_calculate_inverted_impulse_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mini_roller_coaster(Ride* ride) @@ -4266,8 +4197,7 @@ static void ride_ratings_calculate_mini_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_mine_ride(Ride* ride) @@ -4303,8 +4233,7 @@ static void ride_ratings_calculate_mine_ride(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } static void ride_ratings_calculate_lim_launched_roller_coaster(Ride* ride) @@ -4330,12 +4259,12 @@ static void ride_ratings_calculate_lim_launched_roller_coaster(Ride* ride) ride_ratings_apply_proximity(&ratings, 20130); ride_ratings_apply_scenery(&ratings, ride, 6693); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) ride_ratings_apply_highest_drop_height_penalty(&ratings, ride, 10, 2, 2, 2); ride_ratings_apply_max_speed_penalty(&ratings, ride, 0xA0000, 2, 2, 2); - if ((ride->inversions & 0x1F) == 0) + if (ride->inversions == 0) { ride_ratings_apply_max_negative_g_penalty(&ratings, ride, 10, 2, 2, 2); ride_ratings_apply_num_drops_penalty(&ratings, ride, 2, 2, 2, 2); @@ -4350,8 +4279,7 @@ static void ride_ratings_calculate_lim_launched_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->inversions &= 0x1F; - ride->inversions |= get_num_of_sheltered_eighths(ride) << 5; + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); } #pragma endregion diff --git a/src/openrct2/ride/TrackDesignSave.cpp b/src/openrct2/ride/TrackDesignSave.cpp index 2013554cb1..ba72309037 100644 --- a/src/openrct2/ride/TrackDesignSave.cpp +++ b/src/openrct2/ride/TrackDesignSave.cpp @@ -797,7 +797,11 @@ static rct_track_td6* track_design_save_to_td6(ride_id_t rideIndex) td6->max_positive_vertical_g = ride->max_positive_vertical_g / 32; td6->max_negative_vertical_g = ride->max_negative_vertical_g / 32; td6->max_lateral_g = ride->max_lateral_g / 32; - td6->inversions = ride->inversions; + if (ride->type == RIDE_TYPE_MINI_GOLF) + td6->inversions = ride->holes & 0x1F; + else + td6->inversions = ride->inversions & 0x1F; + td6->inversions |= (ride->sheltered_eighths << 5); td6->drops = ride->drops; td6->highest_drop_height = ride->highest_drop_height; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 00a449b979..be2c18c701 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1783,12 +1783,11 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) if (track_flags & TRACK_ELEM_FLAG_NORMAL_TO_INVERSION) { - uint8_t inversions = ride->inversions & 0x1F; - if (inversions != 0x1F) + uint8_t inversions = ride->inversions; + if (inversions != 255) inversions++; - ride->inversions &= ~0x1F; - ride->inversions |= inversions; + ride->inversions = inversions; } if (track_flags & TRACK_ELEM_FLAG_HELIX) @@ -3105,6 +3104,8 @@ void vehicle_test_reset(rct_vehicle* vehicle) ride->turn_count_banked = 0; ride->turn_count_sloped = 0; ride->inversions = 0; + ride->holes = 0; + ride->sheltered_eighths = 0; ride->drops = 0; ride->sheltered_length = 0; ride->var_11C = 0; From 31d32caf8c25fd473960acc7367ccd48e9ff0bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Wed, 27 Mar 2019 03:30:41 -0700 Subject: [PATCH 119/506] Fix #8972: Master server unable to query game info --- src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkTypes.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index cc34606792..c310c5897a 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 "11" +#define NETWORK_STREAM_VERSION "12" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index c6fb88ce81..2308662055 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -55,7 +55,6 @@ enum NETWORK_COMMAND NETWORK_COMMAND_GAMECMD, NETWORK_COMMAND_TICK, NETWORK_COMMAND_PLAYERLIST, - NETWORK_COMMAND_PLAYERINFO, NETWORK_COMMAND_PING, NETWORK_COMMAND_PINGLIST, NETWORK_COMMAND_SETDISCONNECTMSG, @@ -66,10 +65,13 @@ enum NETWORK_COMMAND NETWORK_COMMAND_TOKEN, NETWORK_COMMAND_OBJECTS, NETWORK_COMMAND_GAME_ACTION, + NETWORK_COMMAND_PLAYERINFO, NETWORK_COMMAND_MAX, NETWORK_COMMAND_INVALID = -1 }; +static_assert(NETWORK_COMMAND::NETWORK_COMMAND_GAMEINFO == 9, "Master server expects this to be 9"); + // Structure is used for networking specific fields with meaning, // this structure can be used in combination with DataSerialiser // to provide extra details with template specialization. From 2a99c42242c56742963614a585858c4153f19da6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 12:29:15 +0100 Subject: [PATCH 120/506] Fix code to determine number of golf holes --- src/openrct2/ride/RideRatings.cpp | 3 ++- src/openrct2/ride/Track.h | 1 + src/openrct2/ride/TrackData.cpp | 10 +++++----- src/openrct2/ride/Vehicle.cpp | 20 ++++++++++++++------ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 1a879803eb..651de21db0 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1261,7 +1261,8 @@ static rating_tuple ride_ratings_get_turns_ratings(Ride* ride) intensity += var_112_rating.intensity; nausea += var_112_rating.nausea; - rating_tuple inversions_rating = get_inversions_ratings(ride->inversions); + auto inversions = (ride->type == RIDE_TYPE_MINI_GOLF) ? ride->holes : ride->inversions; + rating_tuple inversions_rating = get_inversions_ratings(inversions); excitement += inversions_rating.excitement; intensity += inversions_rating.intensity; nausea += inversions_rating.nausea; diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 52bdc49be0..1ecbaabc4e 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -197,6 +197,7 @@ enum TRACK_ELEM_FLAG_DOWN = (1 << 5), TRACK_ELEM_FLAG_UP = (1 << 6), TRACK_ELEM_FLAG_NORMAL_TO_INVERSION = (1 << 7), + TRACK_ELEM_FLAG_IS_GOLF_HOLE = (1 << 7), TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT = (1 << 8), TRACK_ELEM_FLAG_ONLY_ABOVE_GROUND = (1 << 9), TRACK_ELEM_FLAG_IS_STEEP_UP = (1 << 10), // Used to allow steep backwards lifts on roller coasters that do not allow steep diff --git a/src/openrct2/ride/TrackData.cpp b/src/openrct2/ride/TrackData.cpp index 35b16613d3..4e30f7de72 100644 --- a/src/openrct2/ride/TrackData.cpp +++ b/src/openrct2/ride/TrackData.cpp @@ -32250,11 +32250,11 @@ const uint16_t TrackFlags[] = { /* TRACK_ELEM_HEARTLINE_TRANSFER_DOWN */ 0, /* TRACK_ELEM_LEFT_HEARTLINE_ROLL */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL, /* TRACK_ELEM_RIGHT_HEARTLINE_ROLL */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL, - /* TRACK_ELEM_MINI_GOLF_HOLE_A */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION, - /* TRACK_ELEM_MINI_GOLF_HOLE_B */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION, - /* TRACK_ELEM_MINI_GOLF_HOLE_C */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION, - /* TRACK_ELEM_MINI_GOLF_HOLE_D */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION, - /* TRACK_ELEM_MINI_GOLF_HOLE_E */ TRACK_ELEM_FLAG_NORMAL_TO_INVERSION, + /* TRACK_ELEM_MINI_GOLF_HOLE_A */ TRACK_ELEM_FLAG_IS_GOLF_HOLE, + /* TRACK_ELEM_MINI_GOLF_HOLE_B */ TRACK_ELEM_FLAG_IS_GOLF_HOLE, + /* TRACK_ELEM_MINI_GOLF_HOLE_C */ TRACK_ELEM_FLAG_IS_GOLF_HOLE, + /* TRACK_ELEM_MINI_GOLF_HOLE_D */ TRACK_ELEM_FLAG_IS_GOLF_HOLE, + /* TRACK_ELEM_MINI_GOLF_HOLE_E */ TRACK_ELEM_FLAG_IS_GOLF_HOLE, /* TRACK_ELEM_MULTIDIM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN */ TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL, /* TRACK_ELEM_90_DEG_TO_INVERTED_FLAT_QUARTER_LOOP_UP */ TRACK_ELEM_FLAG_UP | TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL, /* TRACK_ELEM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN */ TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL, diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index be2c18c701..a93136acda 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1781,13 +1781,21 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) ride->start_drop_height = vehicle->z / 8; } - if (track_flags & TRACK_ELEM_FLAG_NORMAL_TO_INVERSION) + if (ride->type == RIDE_TYPE_MINI_GOLF) { - uint8_t inversions = ride->inversions; - if (inversions != 255) - inversions++; - - ride->inversions = inversions; + if (track_flags & TRACK_ELEM_FLAG_IS_GOLF_HOLE) + { + if (ride->holes < 255) + ride->holes++; + } + } + else + { + if (track_flags & TRACK_ELEM_FLAG_NORMAL_TO_INVERSION) + { + if (ride->inversions < 255) + ride->inversions++; + } } if (track_flags & TRACK_ELEM_FLAG_HELIX) From ba404338cc14b7b3a68c6b868dedde536f6812bf Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 14:02:32 +0100 Subject: [PATCH 121/506] Max out inversions value instead of truncating --- src/openrct2/rct2/S6Exporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index d3047598c6..6b66620460 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -561,9 +561,9 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; if (dst->type == RIDE_TYPE_MINI_GOLF) - dst->inversions = src->holes & 0x1F; + dst->inversions = std::min(src->holes, (uint8_t)31); else - dst->inversions = src->inversions & 0x1F; + dst->inversions = std::min(src->inversions, (uint8_t)31); dst->inversions |= (src->sheltered_eighths << 5); dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; From 44da799afd30c03ee31732eaa089d437c724ef01 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 15:52:18 +0100 Subject: [PATCH 122/506] Modify return type of get_num_of_sheltered_eighths() --- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/ride/RideRatings.cpp | 143 ++++++++++++++++-------------- 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 464c88f9ee..e952c3ada1 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1800,7 +1800,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t // Peeps won't go on rides that aren't sufficiently undercover while it's raining. // The threshold is fairly low and only requires about 10-15% of the ride to be undercover. - if (climate_is_raining() && (ride->sheltered_eighths & 0x7) < 3) + if (climate_is_raining() && (ride->sheltered_eighths) < 3) { if (peepAtRide) { diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 651de21db0..58382d1e47 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -65,6 +65,12 @@ enum PROXIMITY_COUNT }; +struct ShelteredEights +{ + uint8_t TrackShelteredEighths; + uint8_t TotalShelteredEighths; +}; + using ride_ratings_calculation = void (*)(Ride* ride); rct_ride_rating_calc_data gRideRatingsCalcData; @@ -1062,13 +1068,13 @@ static uint32_t ride_ratings_get_proximity_score() * Calculates how much of the track is sheltered in eighths. * rct2: 0x0065E72D */ -static int32_t get_num_of_sheltered_eighths(Ride* ride) +static ShelteredEights get_num_of_sheltered_eighths(Ride* ride) { int32_t totalLength = ride_get_total_length(ride); int32_t shelteredLength = ride->sheltered_length; int32_t lengthEighth = totalLength / 8; int32_t lengthCounter = lengthEighth; - int32_t numShelteredEighths = 0; + uint8_t numShelteredEighths = 0; for (int32_t i = 0; i < 7; i++) { if (shelteredLength >= lengthCounter) @@ -1078,16 +1084,16 @@ static int32_t get_num_of_sheltered_eighths(Ride* ride) } } - int32_t trackShelteredEighths = numShelteredEighths; + uint8_t trackShelteredEighths = numShelteredEighths; rct_ride_entry* rideType = get_ride_entry(ride->subtype); if (rideType == nullptr) { - return 0; + return { 0, 0 }; } if (rideType->flags & RIDE_ENTRY_FLAG_COVERED_RIDE) numShelteredEighths = 7; - return (trackShelteredEighths << 8) | numShelteredEighths; + return { trackShelteredEighths, numShelteredEighths }; } static rating_tuple get_flat_turns_rating(Ride* ride) @@ -1698,7 +1704,7 @@ static void ride_ratings_calculate_spiral_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_stand_up_roller_coaster(Ride* ride) @@ -1736,7 +1742,7 @@ static void ride_ratings_calculate_stand_up_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_suspended_swinging_coaster(Ride* ride) @@ -1776,7 +1782,7 @@ static void ride_ratings_calculate_suspended_swinging_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_inverted_roller_coaster(Ride* ride) @@ -1819,7 +1825,7 @@ static void ride_ratings_calculate_inverted_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_junior_roller_coaster(Ride* ride) @@ -1857,7 +1863,7 @@ static void ride_ratings_calculate_junior_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_miniature_railway(Ride* ride) @@ -1888,11 +1894,11 @@ static void ride_ratings_calculate_miniature_railway(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t edx = get_num_of_sheltered_eighths(ride); - if (((edx >> 8) & 0xFF) >= 4) + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) ride->excitement /= 4; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; } static void ride_ratings_calculate_monorail(Ride* ride) @@ -1923,11 +1929,11 @@ static void ride_ratings_calculate_monorail(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t edx = get_num_of_sheltered_eighths(ride); - if (((edx >> 8) & 0xFF) >= 4) + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) ride->excitement /= 4; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; } static void ride_ratings_calculate_mini_suspended_coaster(Ride* ride) @@ -1966,7 +1972,7 @@ static void ride_ratings_calculate_mini_suspended_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_boat_hire(Ride* ride) @@ -2039,7 +2045,7 @@ static void ride_ratings_calculate_wooden_wild_mouse(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_steeplechase(Ride* ride) @@ -2079,7 +2085,7 @@ static void ride_ratings_calculate_steeplechase(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_car_ride(Ride* ride) @@ -2113,7 +2119,7 @@ static void ride_ratings_calculate_car_ride(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_launched_freefall(Ride* ride) @@ -2164,7 +2170,7 @@ static void ride_ratings_calculate_launched_freefall(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_bobsleigh_coaster(Ride* ride) @@ -2202,7 +2208,7 @@ static void ride_ratings_calculate_bobsleigh_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_observation_tower(Ride* ride) @@ -2230,8 +2236,8 @@ static void ride_ratings_calculate_observation_tower(Ride* ride) ride->sheltered_eighths = 7; - int32_t edx = get_num_of_sheltered_eighths(ride); - if (((edx >> 8) & 0xFF) >= 5) + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 5) ride->excitement /= 4; } @@ -2278,7 +2284,7 @@ static void ride_ratings_calculate_looping_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_dinghy_slide(Ride* ride) @@ -2316,7 +2322,7 @@ static void ride_ratings_calculate_dinghy_slide(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_mine_train_coaster(Ride* ride) @@ -2356,7 +2362,7 @@ static void ride_ratings_calculate_mine_train_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_chairlift(Ride* ride) @@ -2394,11 +2400,11 @@ static void ride_ratings_calculate_chairlift(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); - if (((shelteredEighths >> 8) & 0xFF) >= 4) + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) ride->excitement /= 4; - ride->sheltered_eighths = shelteredEighths; + ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; } static void ride_ratings_calculate_corkscrew_roller_coaster(Ride* ride) @@ -2444,7 +2450,7 @@ static void ride_ratings_calculate_corkscrew_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_maze(Ride* ride) @@ -2536,11 +2542,10 @@ static void ride_ratings_calculate_go_karts(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; - ride->sheltered_eighths = shelteredEighths; - - if (((shelteredEighths >> 8) & 0xFF) >= 6) + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 6) ride->excitement /= 2; } @@ -2573,7 +2578,7 @@ static void ride_ratings_calculate_log_flume(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_river_rapids(Ride* ride) @@ -2606,7 +2611,7 @@ static void ride_ratings_calculate_river_rapids(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_dodgems(Ride* ride) @@ -2932,7 +2937,7 @@ static void ride_ratings_calculate_reverse_freefall_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_lift(Ride* ride) @@ -2964,7 +2969,7 @@ static void ride_ratings_calculate_lift(Ride* ride) ride->sheltered_eighths = 7; - if ((get_num_of_sheltered_eighths(ride) >> 8) >= 5) + if ((get_num_of_sheltered_eighths(ride).TrackShelteredEighths) >= 5) ride->excitement /= 4; } @@ -3003,7 +3008,7 @@ static void ride_ratings_calculate_vertical_drop_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_cash_machine(Ride* ride) @@ -3100,7 +3105,7 @@ static void ride_ratings_calculate_flying_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_virginia_reel(Ride* ride) @@ -3137,7 +3142,7 @@ static void ride_ratings_calculate_virginia_reel(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_splash_boats(Ride* ride) @@ -3169,7 +3174,7 @@ static void ride_ratings_calculate_splash_boats(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_mini_helicopters(Ride* ride) @@ -3253,7 +3258,7 @@ static void ride_ratings_calculate_lay_down_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_suspended_monorail(Ride* ride) @@ -3284,11 +3289,11 @@ static void ride_ratings_calculate_suspended_monorail(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - int32_t shelteredEighths = get_num_of_sheltered_eighths(ride); - if (((shelteredEighths >> 8) & 0xFF) >= 4) + auto shelteredEighths = get_num_of_sheltered_eighths(ride); + if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) ride->excitement /= 4; - ride->sheltered_eighths = shelteredEighths; + ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; } static void ride_ratings_calculate_reverser_roller_coaster(Ride* ride) @@ -3336,7 +3341,7 @@ static void ride_ratings_calculate_reverser_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_heartline_twister_coaster(Ride* ride) @@ -3376,7 +3381,7 @@ static void ride_ratings_calculate_heartline_twister_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_mini_golf(Ride* ride) @@ -3414,7 +3419,7 @@ static void ride_ratings_calculate_mini_golf(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_first_aid(Ride* ride) @@ -3477,7 +3482,7 @@ static void ride_ratings_calculate_ghost_train(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_twister_roller_coaster(Ride* ride) @@ -3523,7 +3528,7 @@ static void ride_ratings_calculate_twister_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_wooden_roller_coaster(Ride* ride) @@ -3563,7 +3568,7 @@ static void ride_ratings_calculate_wooden_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_side_friction_roller_coaster(Ride* ride) @@ -3602,7 +3607,7 @@ static void ride_ratings_calculate_side_friction_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_wild_mouse(Ride* ride) @@ -3642,7 +3647,7 @@ static void ride_ratings_calculate_wild_mouse(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_multi_dimension_roller_coaster(Ride* ride) @@ -3687,7 +3692,7 @@ static void ride_ratings_calculate_multi_dimension_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_giga_coaster(Ride* ride) @@ -3733,7 +3738,7 @@ static void ride_ratings_calculate_giga_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_roto_drop(Ride* ride) @@ -3761,7 +3766,7 @@ static void ride_ratings_calculate_roto_drop(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_flying_saucers(Ride* ride) @@ -3857,7 +3862,7 @@ static void ride_ratings_calculate_monorail_cycles(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_compact_inverted_coaster(Ride* ride) @@ -3900,7 +3905,7 @@ static void ride_ratings_calculate_compact_inverted_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_water_coaster(Ride* ride) @@ -3941,7 +3946,7 @@ static void ride_ratings_calculate_water_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_air_powered_vertical_coaster(Ride* ride) @@ -3972,7 +3977,7 @@ static void ride_ratings_calculate_air_powered_vertical_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_inverted_hairpin_coaster(Ride* ride) @@ -4013,7 +4018,7 @@ static void ride_ratings_calculate_inverted_hairpin_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_magic_carpet(Ride* ride) @@ -4063,7 +4068,7 @@ static void ride_ratings_calculate_submarine_ride(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; // Originally, this was always to zero, even though the default vehicle is completely enclosed. - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_river_rafts(Ride* ride) @@ -4093,7 +4098,7 @@ static void ride_ratings_calculate_river_rafts(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_enterprise(Ride* ride) @@ -4159,7 +4164,7 @@ static void ride_ratings_calculate_inverted_impulse_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_mini_roller_coaster(Ride* ride) @@ -4198,7 +4203,7 @@ static void ride_ratings_calculate_mini_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_mine_ride(Ride* ride) @@ -4234,7 +4239,7 @@ static void ride_ratings_calculate_mine_ride(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } static void ride_ratings_calculate_lim_launched_roller_coaster(Ride* ride) @@ -4280,7 +4285,7 @@ static void ride_ratings_calculate_lim_launched_roller_coaster(Ride* ride) ride->upkeep_cost = ride_compute_upkeep(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - ride->sheltered_eighths = get_num_of_sheltered_eighths(ride); + ride->sheltered_eighths = get_num_of_sheltered_eighths(ride).TotalShelteredEighths; } #pragma endregion From 921e426605aba2a1ad6176bffed843e44a7122b6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 15:55:34 +0100 Subject: [PATCH 123/506] Increase size of inversions and holes to uint16_t --- src/openrct2/rct2/S6Exporter.cpp | 4 ++-- src/openrct2/ride/Ride.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 6b66620460..dc38335f45 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -561,9 +561,9 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; if (dst->type == RIDE_TYPE_MINI_GOLF) - dst->inversions = std::min(src->holes, (uint8_t)31); + dst->inversions = std::min((uint8_t)src->holes, (uint8_t)31); else - dst->inversions = std::min(src->inversions, (uint8_t)31); + dst->inversions = std::min((uint8_t)src->inversions, (uint8_t)31); dst->inversions |= (src->sheltered_eighths << 5); dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 2bd37f4c92..941d4d4007 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -344,8 +344,8 @@ struct Ride uint8_t current_issues; uint32_t last_issue_time; RideStation stations[MAX_STATIONS]; - uint8_t inversions; - uint8_t holes; + uint16_t inversions; + uint16_t holes; uint8_t sheltered_eighths; bool CanBreakDown() const; From bc0b0fe23151feee62dec7d9a919a0a00a875783 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 15:57:17 +0100 Subject: [PATCH 124/506] Increase argument size of get_inversions_ratings() --- src/openrct2/ride/RideRatings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 58382d1e47..cf1cafdde7 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1171,7 +1171,7 @@ static rating_tuple get_sloped_turns_rating(Ride* ride) * * rct2: 0x0065E0F2 */ -static rating_tuple get_inversions_ratings(uint8_t inversions) +static rating_tuple get_inversions_ratings(uint16_t inversions) { rating_tuple rating; From 5fa4c718cdcc565abca420d56b17183d686de722 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 17:25:39 +0100 Subject: [PATCH 125/506] Add #8300 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 190f3f2c91..82dc199ef6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -70,6 +70,7 @@ - Fix: [#8200] Incorrect behaviour when removing entrances and exits that are on the same tile. - Fix: [#8204] Crash when tile element has no surface elements. - Fix: [#8264] Rides and scenery placeable outside of map with ZC and Sandbox mode enabled. +- Fix: [#8300] Crash in UpdateRideMazePathfinding(). - Fix: [#8335] Rides with arbitrary ride types can crash the game when they break down. - Fix: [#8358] Infinite loop when changing vehicle count on stopped ride. - Fix: [#8402] Crash closing a window in some cases. From 2ca83c203a0620882a35cf4be218f826faa8d63e Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 17:29:15 +0100 Subject: [PATCH 126/506] Add #8736 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 82dc199ef6..236dcfdfe2 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -90,6 +90,7 @@ - Fix: [#8647] Marketing campaigns check for entry fees below £1 (original bug). - Fix: [#8653] Crash when peeps attempt to enter a ride with no vehicles. - Fix: [#8720] Desync due to boats colliding with ghost pieces. +- Fix: [#8736] Incomplete warning when all ride slots are full. - Fix: [#8739] Savegame from original game crashes when cruising through map. - Fix: [#8742] Access violation in vehicle_update_sound_params. - Fix: [#8804] Raising water shows money effect at the bottom rather than new height. From a3a102838565765c243b7c22fce1512486bafcbc Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 19:44:33 +0100 Subject: [PATCH 127/506] Drop bitmask from TrackShelteredEighths comparisons --- src/openrct2/ride/RideRatings.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index cf1cafdde7..b1ef7e0e77 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1895,7 +1895,7 @@ static void ride_ratings_calculate_miniature_railway(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; auto shelteredEighths = get_num_of_sheltered_eighths(ride); - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) + if (shelteredEighths.TrackShelteredEighths >= 4) ride->excitement /= 4; ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; @@ -1930,7 +1930,7 @@ static void ride_ratings_calculate_monorail(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; auto shelteredEighths = get_num_of_sheltered_eighths(ride); - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) + if (shelteredEighths.TrackShelteredEighths >= 4) ride->excitement /= 4; ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; @@ -2237,7 +2237,7 @@ static void ride_ratings_calculate_observation_tower(Ride* ride) ride->sheltered_eighths = 7; auto shelteredEighths = get_num_of_sheltered_eighths(ride); - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 5) + if (shelteredEighths.TrackShelteredEighths >= 5) ride->excitement /= 4; } @@ -2401,7 +2401,7 @@ static void ride_ratings_calculate_chairlift(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; auto shelteredEighths = get_num_of_sheltered_eighths(ride); - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) + if (shelteredEighths.TrackShelteredEighths >= 4) ride->excitement /= 4; ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; @@ -2545,7 +2545,7 @@ static void ride_ratings_calculate_go_karts(Ride* ride) auto shelteredEighths = get_num_of_sheltered_eighths(ride); ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 6) + if (shelteredEighths.TrackShelteredEighths >= 6) ride->excitement /= 2; } @@ -3290,7 +3290,7 @@ static void ride_ratings_calculate_suspended_monorail(Ride* ride) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; auto shelteredEighths = get_num_of_sheltered_eighths(ride); - if ((shelteredEighths.TrackShelteredEighths & 0xFF) >= 4) + if (shelteredEighths.TrackShelteredEighths >= 4) ride->excitement /= 4; ride->sheltered_eighths = shelteredEighths.TotalShelteredEighths; From a27e04e5a3c47659447622731276a8e8c1e691b6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 19:44:46 +0100 Subject: [PATCH 128/506] Limit inversions and holes to 31 (for now) --- src/openrct2/rct12/RCT12.h | 4 ++++ src/openrct2/rct2/S6Exporter.cpp | 4 ++-- src/openrct2/ride/Ride.h | 3 +++ src/openrct2/ride/Vehicle.cpp | 6 +++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 0784f460d6..78c69372bf 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -39,6 +39,10 @@ #define RCT12_PEEP_MAX_THOUGHTS 5 +#define RCT12_MAX_INVERSIONS 31 +#define RCT12_MAX_GOLF_HOLES 31 +#define RCT12_MAX_HELICES 31 + #pragma pack(push, 1) struct rct12_award diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index dc38335f45..7af8b06ef3 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -561,9 +561,9 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; if (dst->type == RIDE_TYPE_MINI_GOLF) - dst->inversions = std::min((uint8_t)src->holes, (uint8_t)31); + dst->inversions = std::min((uint8_t)src->holes, (uint8_t)RCT12_MAX_GOLF_HOLES); else - dst->inversions = std::min((uint8_t)src->inversions, (uint8_t)31); + dst->inversions = std::min((uint8_t)src->inversions, (uint8_t)RCT12_MAX_INVERSIONS); dst->inversions |= (src->sheltered_eighths << 5); dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 941d4d4007..3b512969c5 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -39,6 +39,9 @@ struct Staff; #define MAX_RIDES 255 #define RIDE_ID_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 +#define MAX_INVERSIONS RCT12_MAX_INVERSIONS +#define MAX_GOLF_HOLES RCT12_MAX_GOLF_HOLES +#define MAX_HELICES RCT12_MAX_HELICES #pragma pack(push, 1) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index a93136acda..dc5aa6a078 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1785,7 +1785,7 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) { if (track_flags & TRACK_ELEM_FLAG_IS_GOLF_HOLE) { - if (ride->holes < 255) + if (ride->holes < MAX_GOLF_HOLES) ride->holes++; } } @@ -1793,7 +1793,7 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) { if (track_flags & TRACK_ELEM_FLAG_NORMAL_TO_INVERSION) { - if (ride->inversions < 255) + if (ride->inversions < MAX_INVERSIONS) ride->inversions++; } } @@ -1801,7 +1801,7 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) if (track_flags & TRACK_ELEM_FLAG_HELIX) { uint8_t helixes = ride_get_helix_sections(ride); - if (helixes != 0x1F) + if (helixes != MAX_HELICES) helixes++; ride->special_track_elements &= ~0x1F; From 81307f71dfa015a22a2f852b868d03b6e22eb50a Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 22:04:58 +0000 Subject: [PATCH 129/506] Implement LandSmoothAction --- src/openrct2-ui/windows/TopToolbar.cpp | 26 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/LandSmoothAction.hpp | 628 ++++++++++++++++++ 3 files changed, 645 insertions(+), 11 deletions(-) create mode 100644 src/openrct2/actions/LandSmoothAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 6089a17b6d..a1a02ab3b9 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -2892,13 +2893,15 @@ static money32 selection_raise_land(uint8_t flags) centreX += 16; centreY += 16; - uint32_t xBounds = (gMapSelectPositionA.x & 0xFFFF) | (gMapSelectPositionB.x << 16); - uint32_t yBounds = (gMapSelectPositionA.y & 0xFFFF) | (gMapSelectPositionB.y << 16); - - gGameCommandErrorTitle = STR_CANT_RAISE_LAND_HERE; if (gLandMountainMode) { - return game_do_command(centreX, flags, centreY, xBounds, GAME_COMMAND_EDIT_LAND_SMOOTH, gMapSelectType, yBounds); + auto landSmoothAction = LandSmoothAction( + { centreX, centreY }, + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, gMapSelectType, + false); + auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::Execute(&landSmoothAction) + : GameActions::Query(&landSmoothAction); + return res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } else { @@ -2923,14 +2926,15 @@ static money32 selection_lower_land(uint8_t flags) centreX += 16; centreY += 16; - uint32_t xBounds = (gMapSelectPositionA.x & 0xFFFF) | (gMapSelectPositionB.x << 16); - uint32_t yBounds = (gMapSelectPositionA.y & 0xFFFF) | (gMapSelectPositionB.y << 16); - - gGameCommandErrorTitle = STR_CANT_LOWER_LAND_HERE; if (gLandMountainMode) { - return game_do_command( - centreX, flags, centreY, xBounds, GAME_COMMAND_EDIT_LAND_SMOOTH, 0x8000 + gMapSelectType, yBounds); + auto landSmoothAction = LandSmoothAction( + { centreX, centreY }, + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, gMapSelectType, + true); + auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::Execute(&landSmoothAction) + : GameActions::Query(&landSmoothAction); + return res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } else { diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 170ec89a32..f13264d1d8 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -21,6 +21,7 @@ #include "LandLowerAction.hpp" #include "LandRaiseAction.hpp" #include "LandSetHeightAction.hpp" +#include "LandSmoothAction.hpp" #include "LargeSceneryRemoveAction.hpp" #include "LoadOrQuitAction.hpp" #include "MazeSetTrackAction.hpp" @@ -115,6 +116,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/LandSmoothAction.hpp b/src/openrct2/actions/LandSmoothAction.hpp new file mode 100644 index 0000000000..d96b35f512 --- /dev/null +++ b/src/openrct2/actions/LandSmoothAction.hpp @@ -0,0 +1,628 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../actions/LandSetHeightAction.hpp" +#include "../audio/audio.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/RideData.h" +#include "../windows/Intent.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(LandSmoothAction, GAME_COMMAND_EDIT_LAND_SMOOTH, GameActionResult) +{ +private: + CoordsXY _coords; + MapRange _range; + uint8_t _selectionType; + bool _isLowering; + + constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_LOWER_LAND_HERE, STR_CANT_RAISE_LAND_HERE }; + +public: + LandSmoothAction() + { + } + LandSmoothAction(CoordsXY coords, MapRange range, uint8_t selectionType, bool isLowering) + : _coords(coords) + , _range(range) + , _selectionType(selectionType) + , _isLowering(isLowering) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_coords) << DS_TAG(_range) << DS_TAG(_selectionType) << DS_TAG(_isLowering); + } + + GameActionResult::Ptr Query() const override + { + return smooth_land(false); + } + + GameActionResult::Ptr Execute() const override + { + return smooth_land(true); + } + +private: + GameActionResult::Ptr QueryExecute(bool isExecuting) const + { + auto res = MakeResult(); + + return res; + } + + money32 smooth_land_tile( + int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement * tileElement) const + { + int32_t targetBaseZ = tileElement->base_height; + int32_t slope = tileElement->AsSurface()->GetSlope(); + if (_isLowering) + { + slope = tile_element_lower_styles[direction][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ -= 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + else + { + slope = tile_element_raise_styles[direction][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ += 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + + auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); + landSetHeightAction.SetFlags(GetFlags()); + auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + + if (res->Error == GA_ERROR::OK) + { + return res->Cost; + } + else + { + return MONEY32_UNDEFINED; + } + } + + money32 smooth_land_row_by_edge( + bool isExecuting, int32_t x, int32_t y, int32_t expectedLandHeight1, int32_t expectedLandHeight2, int32_t stepX, + int32_t stepY, int32_t direction1, int32_t direction2, int32_t checkDirection1, int32_t checkDirection2) const + { + uint8_t shouldContinue = 0xF; + int32_t landChangePerTile = _isLowering ? 2 : -2; + TileElement *tileElement, *nextTileElement; + money32 totalCost = 0; + + // check if we need to start at all + if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) + { + return 0; + } + tileElement = map_get_surface_element_at({ x, y }); + nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); + if (tileElement == nullptr || nextTileElement == nullptr) + { + return 0; + } + if (tile_element_get_corner_height(tileElement, checkDirection1) != expectedLandHeight1 + landChangePerTile) + { + shouldContinue &= ~0x1; + } + if (tile_element_get_corner_height(tileElement, checkDirection2) != expectedLandHeight2 + landChangePerTile) + { + shouldContinue &= ~0x2; + } + if (tile_element_get_corner_height(tileElement, checkDirection1) + != tile_element_get_corner_height(nextTileElement, direction1)) + { + shouldContinue &= ~0x1; + } + if (tile_element_get_corner_height(tileElement, checkDirection2) + != tile_element_get_corner_height(nextTileElement, direction2)) + { + shouldContinue &= ~0x2; + } + while ((shouldContinue & 0x3) != 0) + { + shouldContinue = ((shouldContinue << 2) | 0x3) & shouldContinue; + x += stepX; + y += stepY; + // check if we need to continue after raising the current tile + // this needs to be checked before the tile is changed + if (!map_is_location_valid({ x + stepX, y + stepY })) + { + shouldContinue &= ~0x3; + } + else + { + tileElement = nextTileElement; + nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); + if (nextTileElement == nullptr) + { + shouldContinue &= ~0x3; + } + if (tile_element_get_corner_height(tileElement, direction1) + landChangePerTile + != tile_element_get_corner_height(tileElement, checkDirection1)) + { + shouldContinue &= ~0x1; + } + if (tile_element_get_corner_height(tileElement, direction2) + landChangePerTile + != tile_element_get_corner_height(tileElement, checkDirection2)) + { + shouldContinue &= ~0x2; + } + if ((shouldContinue & 0x1) + && tile_element_get_corner_height(tileElement, checkDirection1) + != tile_element_get_corner_height(nextTileElement, direction1)) + { + shouldContinue &= ~0x1; + } + if ((shouldContinue & 0x2) + && tile_element_get_corner_height(tileElement, checkDirection2) + != tile_element_get_corner_height(nextTileElement, direction2)) + { + shouldContinue &= ~0x2; + } + } + expectedLandHeight1 += landChangePerTile; + + // change land of current tile + int32_t targetBaseZ = tileElement->base_height; + int32_t slope = tileElement->AsSurface()->GetSlope(); + int32_t oldSlope = slope; + if (_isLowering) + { + if (shouldContinue & 0x4) + { + slope = tile_element_lower_styles[direction1][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ -= 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + if ((shouldContinue & 0x8) + && map_get_corner_height(tileElement->base_height, oldSlope, direction2) + == map_get_corner_height(targetBaseZ, slope, direction2)) + { + slope = tile_element_lower_styles[direction2][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ -= 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + } + else + { + if (shouldContinue & 0x4) + { + slope = tile_element_raise_styles[direction1][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ += 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + if ((shouldContinue & 0x8) + && map_get_corner_height(tileElement->base_height, oldSlope, direction2) + == map_get_corner_height(targetBaseZ, slope, direction2)) + { + slope = tile_element_raise_styles[direction2][slope]; + if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + targetBaseZ += 2; + slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + } + } + auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); + landSetHeightAction.SetFlags(GetFlags()); + auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) + : GameActions::QueryNested(&landSetHeightAction); + if (res->Error == GA_ERROR::OK) + { + totalCost += res->Cost; + } + } + return totalCost; + } + + money32 smooth_land_row_by_corner( + bool isExecuting, int32_t x, int32_t y, int32_t expectedLandHeight, int32_t stepX, int32_t stepY, int32_t direction, + int32_t checkDirection) const + { + bool shouldContinue = true; + TileElement *tileElement, *nextTileElement; + money32 totalCost = 0; + money32 result; + int32_t landChangePerTile; + if (stepX == 0 || stepY == 0) + { + landChangePerTile = _isLowering ? 2 : -2; + } + else + { + landChangePerTile = _isLowering ? 4 : -4; + } + + // check if we need to start at all + if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) + { + return 0; + } + tileElement = map_get_surface_element_at({ x, y }); + nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); + if (tileElement == nullptr || nextTileElement == nullptr) + { + return 0; + } + if (tile_element_get_corner_height(tileElement, checkDirection) != expectedLandHeight + (_isLowering ? 2 : -2)) + { + return 0; + } + if (tile_element_get_corner_height(tileElement, checkDirection) + != tile_element_get_corner_height(nextTileElement, direction)) + { + return 0; + } + while (shouldContinue) + { + x += stepX; + y += stepY; + // check if we need to continue after raising the current tile + // this needs to be checked before the tile is changed + if (!map_is_location_valid({ x + stepX, y + stepY })) + { + shouldContinue = false; + } + else + { + tileElement = nextTileElement; + nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); + if (nextTileElement == nullptr) + { + shouldContinue = false; + } + if (tile_element_get_corner_height(tileElement, direction) + landChangePerTile + != tile_element_get_corner_height(tileElement, checkDirection)) + { + shouldContinue = false; + } + if (shouldContinue + && tile_element_get_corner_height(tileElement, checkDirection) + != tile_element_get_corner_height(nextTileElement, direction)) + { + shouldContinue = false; + } + } + if (stepX * stepY != 0) + { + totalCost += smooth_land_row_by_corner( + isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3 + ); + totalCost += smooth_land_row_by_corner( + isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1 + ); + } + expectedLandHeight += landChangePerTile; + // change land of current tile + result = smooth_land_tile(direction, isExecuting, x, y, tileElement); + if (result != MONEY32_UNDEFINED) + { + totalCost += result; + } + } + return totalCost; + } + + GameActionResult::Ptr smooth_land(bool isExecuting) const + { + // break up information in command + const bool raiseLand = !_isLowering; + const int32_t selectionType = _selectionType; + const int32_t heightOffset = raiseLand ? 2 : -2; + + auto normRange = _range.Normalise(); + // Cap bounds to map + auto l = std::max(normRange.GetLeft(), 32); + auto t = std::max(normRange.GetTop(), 32); + auto r = std::clamp(normRange.GetRight(), 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); + auto b = std::clamp(normRange.GetBottom(), 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); + auto validRange = MapRange{ l, t, r, b }; + + // Play sound (only once) + int32_t centreZ = tile_element_height(_coords.x, _coords.y) & 0xFFFF; + + + auto res = MakeResult(); + res->ErrorTitle = _ErrorTitles[_isLowering ? 0 : 1]; + res->Position = { _coords.x, _coords.y, centreZ }; + + // Do the smoothing + switch (selectionType) + { + case MAP_SELECT_TYPE_FULL: + { + uint8_t minHeight = heightOffset + map_get_lowest_land_height(validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom()); + uint8_t maxHeight = heightOffset + + map_get_highest_land_height( + validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), + validRange.GetBottom()); + + // Smooth the 4 corners + { // top-left + TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + } + { // bottom-left + TileElement* tileElement = map_get_surface_element_at( + { validRange.GetLeft(), validRange.GetBottom() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetBottom(), z, -32, 32, 1, 3); + } + { // bottom-right + TileElement* tileElement = map_get_surface_element_at( + { validRange.GetRight(), validRange.GetBottom() } ); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetRight(), validRange.GetBottom(), z, 32, 32, 2, 0); + } + { // top-right + TileElement* tileElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetTop() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetRight(), validRange.GetTop(), z, 32, -32, 3, 1); + } + + // Smooth the edges + TileElement* tileElement = nullptr; + int32_t z1, z2; + for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + tileElement = map_get_surface_element_at({ validRange.GetLeft(), y }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); + res->Cost += smooth_land_row_by_edge(isExecuting, validRange.GetLeft(), y, z1, z2, -32, 0, 0, 1, 3, 2); + + tileElement = map_get_surface_element_at({ validRange.GetRight(), y }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); + res->Cost += smooth_land_row_by_edge(isExecuting, validRange.GetRight(), y, z1, z2, 32, 0, 2, 3, 1, 0); + } + + for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + tileElement = map_get_surface_element_at({ x, validRange.GetTop() }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); + res->Cost += smooth_land_row_by_edge(isExecuting, x, validRange.GetTop(), z1, z2, 0, -32, 0, 3, 1, 2); + + tileElement = map_get_surface_element_at({ x, validRange.GetBottom() }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); + res->Cost += smooth_land_row_by_edge(isExecuting, x, validRange.GetBottom(), z1, z2, 0, 32, 1, 2, 0, 3); + } + break; + } + case MAP_SELECT_TYPE_CORNER_0: + case MAP_SELECT_TYPE_CORNER_1: + case MAP_SELECT_TYPE_CORNER_2: + case MAP_SELECT_TYPE_CORNER_3: + { + TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + uint8_t newBaseZ = tileElement->base_height; + uint8_t newSlope = tileElement->AsSurface()->GetSlope(); + + if (raiseLand) + { + newSlope = tile_element_raise_styles[selectionType][newSlope]; + } + else + { + newSlope = tile_element_lower_styles[selectionType][newSlope]; + } + + if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) + { + newBaseZ += heightOffset; + newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + + // Smooth the corners + int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + z = map_get_corner_height(newBaseZ, newSlope, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); + z = map_get_corner_height(newBaseZ, newSlope, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + z = map_get_corner_height(newBaseZ, newSlope, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + + // Smooth the edges + switch (selectionType) + { + case MAP_SELECT_TYPE_CORNER_0: + z = map_get_corner_height(newBaseZ, newSlope, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + z = map_get_corner_height(newBaseZ, newSlope, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); + z = map_get_corner_height(newBaseZ, newSlope, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + break; + case MAP_SELECT_TYPE_CORNER_1: + z = map_get_corner_height(newBaseZ, newSlope, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + z = map_get_corner_height(newBaseZ, newSlope, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); + z = map_get_corner_height(newBaseZ, newSlope, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + break; + case MAP_SELECT_TYPE_CORNER_2: + z = map_get_corner_height(newBaseZ, newSlope, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + z = map_get_corner_height(newBaseZ, newSlope, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); + z = map_get_corner_height(newBaseZ, newSlope, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + break; + case MAP_SELECT_TYPE_CORNER_3: + z = map_get_corner_height(newBaseZ, newSlope, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + z = map_get_corner_height(newBaseZ, newSlope, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); + z = map_get_corner_height(newBaseZ, newSlope, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + break; + } + break; + } + case MAP_SELECT_TYPE_EDGE_0: + case MAP_SELECT_TYPE_EDGE_1: + case MAP_SELECT_TYPE_EDGE_2: + case MAP_SELECT_TYPE_EDGE_3: + { + // TODO: Handle smoothing by edge + // Get the two corners to raise + TileElement* surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + uint8_t newBaseZ = surfaceElement->base_height; + uint8_t oldSlope = surfaceElement->AsSurface()->GetSlope(); + uint8_t newSlope = oldSlope; + int32_t rowIndex = selectionType - (MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1); + + if (raiseLand) + { + newSlope = tile_element_raise_styles[rowIndex][oldSlope]; + } + else + { + newSlope = tile_element_lower_styles[rowIndex][oldSlope]; + } + + const bool changeBaseHeight = newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + if (changeBaseHeight) + { + newBaseZ += heightOffset; + newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; + } + + const uint8_t edge = selectionType - MAP_SELECT_TYPE_EDGE_0; + + // Table with corners for each edge selection. The first two are the selected corners, the latter two are the + // opposites + static constexpr uint8_t cornerIndices[][4] = { + { 2, 3, 1, 0 }, // MAP_SELECT_TYPE_EDGE_0 + { 3, 0, 2, 1 }, // MAP_SELECT_TYPE_EDGE_1 + { 0, 1, 3, 2 }, // MAP_SELECT_TYPE_EDGE_2 + { 1, 2, 0, 3 }, // MAP_SELECT_TYPE_EDGE_3 + }; + // Big coordinate offsets for the neigbouring tile for the given edge selection + static constexpr sLocationXY8 stepOffsets[] = { + { -32, 0 }, + { 0, 32 }, + { 32, 0 }, + { 0, -32 }, + }; + + // Smooth higher and lower edges + uint8_t c1 = cornerIndices[edge][0]; + uint8_t c2 = cornerIndices[edge][1]; + uint8_t c3 = cornerIndices[edge][2]; + uint8_t c4 = cornerIndices[edge][3]; + uint8_t z1 = map_get_corner_height(newBaseZ, newSlope, c1); + uint8_t z2 = map_get_corner_height(newBaseZ, newSlope, c2); + uint8_t z3 = map_get_corner_height(newBaseZ, newSlope, c3); + uint8_t z4 = map_get_corner_height(newBaseZ, newSlope, c4); + // Smooth the edge at the top of the new slope + res->Cost += smooth_land_row_by_edge( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, c3, c4, c1, c2); + // Smooth the edge at the bottom of the new slope + res->Cost += smooth_land_row_by_edge( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, c1, c2, c3, c4); + + // Smooth corners + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, c1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, c2); + int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + z = map_get_corner_height(newBaseZ, newSlope, 0); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); + z = map_get_corner_height(newBaseZ, newSlope, 3); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + z = map_get_corner_height(newBaseZ, newSlope, 1); + res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + break; + } + } // switch selectionType + + // Raise / lower the land tool selection area + GameActionResult::Ptr result; + if (raiseLand) + { + auto raiseLandAction = LandRaiseAction( + { _coords.x, _coords.y }, validRange, selectionType); + raiseLandAction.SetFlags(GetFlags()); + result = isExecuting ? GameActions::ExecuteNested(&raiseLandAction) + : GameActions::QueryNested(&raiseLandAction); + } + else + { + auto lowerLandAction = LandLowerAction({ _coords.x, _coords.y }, validRange, selectionType); + lowerLandAction.SetFlags(GetFlags()); + result = isExecuting ? GameActions::ExecuteNested(&lowerLandAction) + : GameActions::QueryNested(&lowerLandAction); + } + if (result->Error != GA_ERROR::OK) + { + return result; + } + + if (isExecuting) + { + audio_play_sound_at_location(SOUND_PLACE_ITEM, _coords.x, _coords.y, centreZ); + } + res->Cost += res->Cost; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + return res; + } +}; From 227786e05b59920859466dd49f6fdec5247a6efc Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 22:16:56 +0000 Subject: [PATCH 130/506] Remove game command --- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 20 +- src/openrct2/world/Map.cpp | 565 ------------------------------------- src/openrct2/world/Map.h | 1 - 4 files changed, 11 insertions(+), 577 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 3a0da405de..996f430970 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1268,7 +1268,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_set_staff_name, nullptr, nullptr, - game_command_smooth_land, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index f62bf9e9d1..b944b2a875 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -44,16 +44,16 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_NAME, // GA GAME_COMMAND_RAISE_LAND, // GA GAME_COMMAND_LOWER_LAND, // GA - GAME_COMMAND_EDIT_LAND_SMOOTH, - GAME_COMMAND_RAISE_WATER, // GA - GAME_COMMAND_LOWER_WATER, // GA - GAME_COMMAND_SET_BRAKES_SPEED, // GA - GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA - GAME_COMMAND_SET_STAFF_PATROL, // GA - GAME_COMMAND_FIRE_STAFF_MEMBER, // GA - GAME_COMMAND_SET_STAFF_ORDERS, // GA - GAME_COMMAND_SET_PARK_NAME, // GA - GAME_COMMAND_SET_PARK_OPEN, // GA + GAME_COMMAND_EDIT_LAND_SMOOTH, // GA + GAME_COMMAND_RAISE_WATER, // GA + GAME_COMMAND_LOWER_WATER, // GA + GAME_COMMAND_SET_BRAKES_SPEED, // GA + GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA + GAME_COMMAND_SET_STAFF_PATROL, // GA + GAME_COMMAND_FIRE_STAFF_MEMBER, // GA + GAME_COMMAND_SET_STAFF_ORDERS, // GA + GAME_COMMAND_SET_PARK_NAME, // GA + GAME_COMMAND_SET_PARK_OPEN, // GA GAME_COMMAND_BUY_LAND_RIGHTS, GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 94c090c140..3d39d6e68c 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1080,571 +1080,6 @@ uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, in return max_height; } -static money32 smooth_land_tile( - int32_t direction, uint8_t flags, int32_t x, int32_t y, TileElement* tileElement, bool raiseLand) -{ - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); - if (raiseLand) - { - slope = tile_element_raise_styles[direction][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - else - { - slope = tile_element_lower_styles[direction][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - - auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); - landSetHeightAction.SetFlags(flags); - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - - if (res->Error == GA_ERROR::OK) - { - return res->Cost; - } - else - { - return MONEY32_UNDEFINED; - } -} - -static money32 smooth_land_row_by_edge( - int32_t flags, int32_t x, int32_t y, int32_t expectedLandHeight1, int32_t expectedLandHeight2, int32_t stepX, int32_t stepY, - int32_t direction1, int32_t direction2, int32_t checkDirection1, int32_t checkDirection2, bool raiseLand) -{ - uint8_t shouldContinue = 0xF; - int32_t landChangePerTile = raiseLand ? -2 : 2; - TileElement *tileElement, *nextTileElement; - money32 totalCost = 0; - - // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) - { - return 0; - } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (tileElement == nullptr || nextTileElement == nullptr) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection1) != expectedLandHeight1 + (raiseLand ? -2 : 2)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, checkDirection2) != expectedLandHeight2 + (raiseLand ? -2 : 2)) - { - shouldContinue &= ~0x2; - } - if (tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) - { - shouldContinue &= ~0x2; - } - while ((shouldContinue & 0x3) != 0) - { - shouldContinue = ((shouldContinue << 2) | 0x3) & shouldContinue; - x += stepX; - y += stepY; - // check if we need to continue after raising the current tile - // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) - { - shouldContinue &= ~0x3; - } - else - { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (nextTileElement == nullptr) - { - shouldContinue &= ~0x3; - } - if (tile_element_get_corner_height(tileElement, direction1) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection1)) - { - shouldContinue &= ~0x1; - } - if (tile_element_get_corner_height(tileElement, direction2) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection2)) - { - shouldContinue &= ~0x2; - } - if ((shouldContinue & 0x1) - && tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) - { - shouldContinue &= ~0x1; - } - if ((shouldContinue & 0x2) - && tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) - { - shouldContinue &= ~0x2; - } - } - expectedLandHeight1 += landChangePerTile; - - // change land of current tile - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); - int32_t oldSlope = slope; - if (raiseLand) - { - if (shouldContinue & 0x4) - { - slope = tile_element_raise_styles[direction1][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) - == map_get_corner_height(targetBaseZ, slope, direction2)) - { - slope = tile_element_raise_styles[direction2][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ += 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - } - else - { - if (shouldContinue & 0x4) - { - slope = tile_element_lower_styles[direction1][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) - == map_get_corner_height(targetBaseZ, slope, direction2)) - { - slope = tile_element_lower_styles[direction2][slope]; - if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - targetBaseZ -= 2; - slope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - } - } - auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); - landSetHeightAction.SetFlags(flags); - auto res = (flags & GAME_COMMAND_FLAG_APPLY) ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); - if (res->Error == GA_ERROR::OK) - { - totalCost += res->Cost; - } - } - return totalCost; -} - -static money32 smooth_land_row_by_corner( - int32_t flags, int32_t x, int32_t y, int32_t expectedLandHeight, int32_t stepX, int32_t stepY, int32_t direction, - int32_t checkDirection, bool raiseLand) -{ - bool shouldContinue = true; - TileElement *tileElement, *nextTileElement; - money32 totalCost = 0; - money32 result; - int32_t landChangePerTile; - if (stepX == 0 || stepY == 0) - { - landChangePerTile = raiseLand ? -2 : 2; - } - else - { - landChangePerTile = raiseLand ? -4 : 4; - } - - // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) - { - return 0; - } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (tileElement == nullptr || nextTileElement == nullptr) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection) != expectedLandHeight + (raiseLand ? -2 : 2)) - { - return 0; - } - if (tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) - { - return 0; - } - while (shouldContinue) - { - x += stepX; - y += stepY; - // check if we need to continue after raising the current tile - // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) - { - shouldContinue = false; - } - else - { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (nextTileElement == nullptr) - { - shouldContinue = false; - } - if (tile_element_get_corner_height(tileElement, direction) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection)) - { - shouldContinue = false; - } - if (shouldContinue - && tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) - { - shouldContinue = false; - } - } - if (stepX * stepY != 0) - { - totalCost += smooth_land_row_by_corner( - flags, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3, raiseLand); - totalCost += smooth_land_row_by_corner( - flags, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1, raiseLand); - } - expectedLandHeight += landChangePerTile; - // change land of current tile - result = smooth_land_tile(direction, flags, x, y, tileElement, raiseLand); - if (result != MONEY32_UNDEFINED) - { - totalCost += result; - } - } - return totalCost; -} - -static money32 smooth_land( - int32_t flags, int32_t centreX, int32_t centreY, int32_t mapLeft, int32_t mapTop, int32_t mapRight, int32_t mapBottom, - int32_t command) -{ - // break up information in command - const bool raiseLand = command < 0x7FFF; - const int32_t selectionType = command & 0x7FFF; - const int32_t heightOffset = raiseLand ? 2 : -2; - - // Cap bounds to map - mapLeft = std::max(mapLeft, 32); - mapTop = std::max(mapTop, 32); - mapRight = std::clamp(mapRight, 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); - mapBottom = std::clamp(mapBottom, 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); - - // Play sound (only once) - int32_t centreZ = tile_element_height(centreX, centreY); - if ((flags & GAME_COMMAND_FLAG_APPLY) && gGameCommandNestLevel == 1) - { - audio_play_sound_at_location(SOUND_PLACE_ITEM, centreX, centreY, centreZ); - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - LocationXYZ16 coord; - coord.x = centreX + 16; - coord.y = centreY + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - // Do the smoothing - money32 totalCost = 0; - switch (selectionType) - { - case MAP_SELECT_TYPE_FULL: - { - uint8_t minHeight = heightOffset + map_get_lowest_land_height(mapLeft, mapRight, mapTop, mapBottom); - uint8_t maxHeight = heightOffset + map_get_highest_land_height(mapLeft, mapRight, mapTop, mapBottom); - - // Smooth the 4 corners - { // top-left - TileElement* tileElement = map_get_surface_element_at({ mapLeft, mapTop }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - } - { // bottom-left - TileElement* tileElement = map_get_surface_element_at(mapLeft >> 5, mapBottom >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapBottom, z, -32, 32, 1, 3, raiseLand); - } - { // bottom-right - TileElement* tileElement = map_get_surface_element_at(mapRight >> 5, mapBottom >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapRight, mapBottom, z, 32, 32, 2, 0, raiseLand); - } - { // top-right - TileElement* tileElement = map_get_surface_element_at(mapRight >> 5, mapTop >> 5); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - totalCost += smooth_land_row_by_corner(flags, mapRight, mapTop, z, 32, -32, 3, 1, raiseLand); - } - - // Smooth the edges - TileElement* tileElement = nullptr; - int32_t z1, z2; - for (int32_t y = mapTop; y <= mapBottom; y += 32) - { - tileElement = map_get_surface_element_at({ mapLeft, y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, mapLeft, y, z1, z2, -32, 0, 0, 1, 3, 2, raiseLand); - - tileElement = map_get_surface_element_at({ mapRight, y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, mapRight, y, z1, z2, 32, 0, 2, 3, 1, 0, raiseLand); - } - - for (int32_t x = mapLeft; x <= mapRight; x += 32) - { - tileElement = map_get_surface_element_at({ x, mapTop }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, x, mapTop, z1, z2, 0, -32, 0, 3, 1, 2, raiseLand); - - tileElement = map_get_surface_element_at({ x, mapBottom }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - totalCost += smooth_land_row_by_edge(flags, x, mapBottom, z1, z2, 0, 32, 1, 2, 0, 3, raiseLand); - } - break; - } - case MAP_SELECT_TYPE_CORNER_0: - case MAP_SELECT_TYPE_CORNER_1: - case MAP_SELECT_TYPE_CORNER_2: - case MAP_SELECT_TYPE_CORNER_3: - { - TileElement* tileElement = map_get_surface_element_at({ mapLeft, mapTop }); - uint8_t newBaseZ = tileElement->base_height; - uint8_t newSlope = tileElement->AsSurface()->GetSlope(); - - if (raiseLand) - { - newSlope = tile_element_raise_styles[selectionType][newSlope]; - } - else - { - newSlope = tile_element_lower_styles[selectionType][newSlope]; - } - - if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT) - { - newBaseZ += heightOffset; - newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - - // Smooth the corners - int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 32, 2, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 32, 1, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, -32, 3, 1, raiseLand); - - // Smooth the edges - switch (selectionType) - { - case MAP_SELECT_TYPE_CORNER_0: - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 3, 0, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 1, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 0, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 0, 1, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_1: - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 2, 1, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 0, 1, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 1, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 1, 0, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_2: - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 1, 2, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 3, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 2, 1, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 2, 3, raiseLand); - break; - case MAP_SELECT_TYPE_CORNER_3: - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 0, 0, 3, raiseLand); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, 32, 2, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 0, 3, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 0, -32, 3, 2, raiseLand); - break; - } - break; - } - case MAP_SELECT_TYPE_EDGE_0: - case MAP_SELECT_TYPE_EDGE_1: - case MAP_SELECT_TYPE_EDGE_2: - case MAP_SELECT_TYPE_EDGE_3: - { - // TODO: Handle smoothing by edge - // Get the two corners to raise - TileElement* surfaceElement = map_get_surface_element_at({ mapLeft, mapTop }); - uint8_t newBaseZ = surfaceElement->base_height; - uint8_t oldSlope = surfaceElement->AsSurface()->GetSlope(); - uint8_t newSlope = oldSlope; - int32_t rowIndex = selectionType - (MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1); - - if (raiseLand) - { - newSlope = tile_element_raise_styles[rowIndex][oldSlope]; - } - else - { - newSlope = tile_element_lower_styles[rowIndex][oldSlope]; - } - - const bool changeBaseHeight = newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - if (changeBaseHeight) - { - newBaseZ += heightOffset; - newSlope &= ~SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT; - } - - const uint8_t edge = selectionType - MAP_SELECT_TYPE_EDGE_0; - - // Table with corners for each edge selection. The first two are the selected corners, the latter two are the - // opposites - static constexpr uint8_t cornerIndices[][4] = { - { 2, 3, 1, 0 }, // MAP_SELECT_TYPE_EDGE_0 - { 3, 0, 2, 1 }, // MAP_SELECT_TYPE_EDGE_1 - { 0, 1, 3, 2 }, // MAP_SELECT_TYPE_EDGE_2 - { 1, 2, 0, 3 }, // MAP_SELECT_TYPE_EDGE_3 - }; - // Big coordinate offsets for the neigbouring tile for the given edge selection - static constexpr sLocationXY8 stepOffsets[] = { - { -32, 0 }, - { 0, 32 }, - { 32, 0 }, - { 0, -32 }, - }; - - // Smooth higher and lower edges - uint8_t c1 = cornerIndices[edge][0]; - uint8_t c2 = cornerIndices[edge][1]; - uint8_t c3 = cornerIndices[edge][2]; - uint8_t c4 = cornerIndices[edge][3]; - uint8_t z1 = map_get_corner_height(newBaseZ, newSlope, c1); - uint8_t z2 = map_get_corner_height(newBaseZ, newSlope, c2); - uint8_t z3 = map_get_corner_height(newBaseZ, newSlope, c3); - uint8_t z4 = map_get_corner_height(newBaseZ, newSlope, c4); - // Smooth the edge at the top of the new slope - totalCost += smooth_land_row_by_edge( - flags, mapLeft, mapTop, z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, c3, c4, c1, c2, raiseLand); - // Smooth the edge at the bottom of the new slope - totalCost += smooth_land_row_by_edge( - flags, mapLeft, mapTop, z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, c1, c2, c3, c4, raiseLand); - - // Smooth corners - totalCost += smooth_land_row_by_corner( - flags, mapLeft, mapTop, z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, c1, raiseLand); - totalCost += smooth_land_row_by_corner( - flags, mapLeft, mapTop, z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, c2, raiseLand); - int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, -32, 0, 2, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 0); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, 32, 2, 0, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 3); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, -32, 32, 1, 3, raiseLand); - z = map_get_corner_height(newBaseZ, newSlope, 1); - totalCost += smooth_land_row_by_corner(flags, mapLeft, mapTop, z, 32, -32, 3, 1, raiseLand); - break; - } - } // switch selectionType - - // Raise / lower the land tool selection area - GameActionResult::Ptr res; - if (raiseLand) - { - auto raiseLandAction = LandRaiseAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); - raiseLandAction.SetFlags(flags); - res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&raiseLandAction) - : GameActions::QueryNested(&raiseLandAction); - } - else - { - auto lowerLandAction = LandLowerAction({ centreX, centreY }, { mapLeft, mapTop, mapRight, mapBottom }, selectionType); - lowerLandAction.SetFlags(flags); - res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&lowerLandAction) - : GameActions::QueryNested(&lowerLandAction); - } - if (res->Error != GA_ERROR::OK) - { - return MONEY32_UNDEFINED; - } - - totalCost += res->Cost; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = centreX; - gCommandPosition.y = centreY; - gCommandPosition.z = centreZ; - return totalCost; -} - -/** - * - * rct2: 0x0068BC01 - */ -void game_command_smooth_land( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t flags = *ebx & 0xFF; - int32_t centreX = *eax & 0xFFFF; - int32_t centreY = *ecx & 0xFFFF; - int32_t mapLeft = (int16_t)(*edx & 0xFFFF); - int32_t mapTop = (int16_t)(*ebp & 0xFFFF); - int32_t mapRight = (int16_t)(*edx >> 16); - int32_t mapBottom = (int16_t)(*ebp >> 16); - int32_t command = *edi; - *ebx = smooth_land(flags, centreX, centreY, mapLeft, mapTop, mapRight, mapBottom, command); -} - bool map_is_location_at_edge(int32_t x, int32_t y) { return x < 32 || y < 32 || x >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32) || y >= ((MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 7c7a395a05..64660ef626 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -202,7 +202,6 @@ void game_command_set_large_scenery_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_smooth_land(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_wall(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); From cc57de791a3c08e76c7c12852dd09187fbf86ec2 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 16 Mar 2019 22:37:20 +0000 Subject: [PATCH 131/506] Fix formatting. Add correct headers --- src/openrct2/actions/LandSmoothAction.hpp | 123 +++++++++++++--------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/src/openrct2/actions/LandSmoothAction.hpp b/src/openrct2/actions/LandSmoothAction.hpp index d96b35f512..8819356fda 100644 --- a/src/openrct2/actions/LandSmoothAction.hpp +++ b/src/openrct2/actions/LandSmoothAction.hpp @@ -11,6 +11,8 @@ #include "../Context.h" #include "../OpenRCT2.h" +#include "../actions/LandLowerAction.hpp" +#include "../actions/LandRaiseAction.hpp" #include "../actions/LandSetHeightAction.hpp" #include "../audio/audio.h" #include "../interface/Window.h" @@ -77,8 +79,7 @@ private: return res; } - money32 smooth_land_tile( - int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement * tileElement) const + money32 smooth_land_tile(int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement* tileElement) const { int32_t targetBaseZ = tileElement->base_height; int32_t slope = tileElement->AsSurface()->GetSlope(); @@ -104,7 +105,7 @@ private: auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); landSetHeightAction.SetFlags(GetFlags()); auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); + : GameActions::QueryNested(&landSetHeightAction); if (res->Error == GA_ERROR::OK) { @@ -251,7 +252,7 @@ private: auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); landSetHeightAction.SetFlags(GetFlags()); auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) - : GameActions::QueryNested(&landSetHeightAction); + : GameActions::QueryNested(&landSetHeightAction); if (res->Error == GA_ERROR::OK) { totalCost += res->Cost; @@ -331,11 +332,9 @@ private: if (stepX * stepY != 0) { totalCost += smooth_land_row_by_corner( - isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3 - ); + isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3); totalCost += smooth_land_row_by_corner( - isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1 - ); + isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1); } expectedLandHeight += landChangePerTile; // change land of current tile @@ -366,7 +365,6 @@ private: // Play sound (only once) int32_t centreZ = tile_element_height(_coords.x, _coords.y) & 0xFFFF; - auto res = MakeResult(); res->ErrorTitle = _ErrorTitles[_isLowering ? 0 : 1]; res->Position = { _coords.x, _coords.y, centreZ }; @@ -376,7 +374,10 @@ private: { case MAP_SELECT_TYPE_FULL: { - uint8_t minHeight = heightOffset + map_get_lowest_land_height(validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), validRange.GetBottom()); + uint8_t minHeight = heightOffset + + map_get_lowest_land_height( + validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), + validRange.GetBottom()); uint8_t maxHeight = heightOffset + map_get_highest_land_height( validRange.GetLeft(), validRange.GetRight(), validRange.GetTop(), @@ -390,21 +391,22 @@ private: isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); } { // bottom-left - TileElement* tileElement = map_get_surface_element_at( - { validRange.GetLeft(), validRange.GetBottom() }); + TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetBottom() }); int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetBottom(), z, -32, 32, 1, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetBottom(), z, -32, 32, 1, 3); } { // bottom-right - TileElement* tileElement = map_get_surface_element_at( - { validRange.GetRight(), validRange.GetBottom() } ); + TileElement* tileElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetBottom() }); int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetRight(), validRange.GetBottom(), z, 32, 32, 2, 0); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetRight(), validRange.GetBottom(), z, 32, 32, 2, 0); } { // top-right TileElement* tileElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetTop() }); int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetRight(), validRange.GetTop(), z, 32, -32, 3, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetRight(), validRange.GetTop(), z, 32, -32, 3, 1); } // Smooth the edges @@ -463,52 +465,71 @@ private: // Smooth the corners int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); // Smooth the edges switch (selectionType) { case MAP_SELECT_TYPE_CORNER_0: z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); break; case MAP_SELECT_TYPE_CORNER_1: z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); break; case MAP_SELECT_TYPE_CORNER_2: z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); break; case MAP_SELECT_TYPE_CORNER_3: z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); break; } break; @@ -571,24 +592,31 @@ private: uint8_t z4 = map_get_corner_height(newBaseZ, newSlope, c4); // Smooth the edge at the top of the new slope res->Cost += smooth_land_row_by_edge( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, c3, c4, c1, c2); + isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, + c3, c4, c1, c2); // Smooth the edge at the bottom of the new slope res->Cost += smooth_land_row_by_edge( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, c1, c2, c3, c4); + isExecuting, validRange.GetLeft(), validRange.GetTop(), z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, + c1, c2, c3, c4); // Smooth corners res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, c1); + isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, + c1); res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, c2); + isExecuting, validRange.GetLeft(), validRange.GetTop(), z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, + c2); int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + res->Cost += smooth_land_row_by_corner( + isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); break; } } // switch selectionType @@ -597,18 +625,15 @@ private: GameActionResult::Ptr result; if (raiseLand) { - auto raiseLandAction = LandRaiseAction( - { _coords.x, _coords.y }, validRange, selectionType); + auto raiseLandAction = LandRaiseAction({ _coords.x, _coords.y }, validRange, selectionType); raiseLandAction.SetFlags(GetFlags()); - result = isExecuting ? GameActions::ExecuteNested(&raiseLandAction) - : GameActions::QueryNested(&raiseLandAction); + result = isExecuting ? GameActions::ExecuteNested(&raiseLandAction) : GameActions::QueryNested(&raiseLandAction); } else { auto lowerLandAction = LandLowerAction({ _coords.x, _coords.y }, validRange, selectionType); lowerLandAction.SetFlags(GetFlags()); - result = isExecuting ? GameActions::ExecuteNested(&lowerLandAction) - : GameActions::QueryNested(&lowerLandAction); + result = isExecuting ? GameActions::ExecuteNested(&lowerLandAction) : GameActions::QueryNested(&lowerLandAction); } if (result->Error != GA_ERROR::OK) { From 95b7a90c556c483d80d53d2a62fe00d394975b12 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 20 Mar 2019 19:47:07 +0000 Subject: [PATCH 132/506] Refactor function names and variables --- src/openrct2/actions/LandSmoothAction.hpp | 340 +++++++++++----------- 1 file changed, 168 insertions(+), 172 deletions(-) diff --git a/src/openrct2/actions/LandSmoothAction.hpp b/src/openrct2/actions/LandSmoothAction.hpp index 8819356fda..287feb97a4 100644 --- a/src/openrct2/actions/LandSmoothAction.hpp +++ b/src/openrct2/actions/LandSmoothAction.hpp @@ -63,12 +63,12 @@ public: GameActionResult::Ptr Query() const override { - return smooth_land(false); + return SmoothLand(false); } GameActionResult::Ptr Execute() const override { - return smooth_land(true); + return SmoothLand(true); } private: @@ -79,10 +79,11 @@ private: return res; } - money32 smooth_land_tile(int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement* tileElement) const + GameActionResult::Ptr SmoothLandTile(int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement* surfaceElement) + const { - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); + int32_t targetBaseZ = surfaceElement->base_height; + int32_t slope = surfaceElement->AsSurface()->GetSlope(); if (_isLowering) { slope = tile_element_lower_styles[direction][slope]; @@ -107,92 +108,85 @@ private: auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) : GameActions::QueryNested(&landSetHeightAction); - if (res->Error == GA_ERROR::OK) - { - return res->Cost; - } - else - { - return MONEY32_UNDEFINED; - } + return res; } - money32 smooth_land_row_by_edge( - bool isExecuting, int32_t x, int32_t y, int32_t expectedLandHeight1, int32_t expectedLandHeight2, int32_t stepX, - int32_t stepY, int32_t direction1, int32_t direction2, int32_t checkDirection1, int32_t checkDirection2) const + money32 SmoothLandRowByEdge( + bool isExecuting, CoordsXY loc, int32_t expectedLandHeight1, int32_t expectedLandHeight2, int32_t stepX, int32_t stepY, + int32_t direction1, int32_t direction2, int32_t checkDirection1, int32_t checkDirection2) const { uint8_t shouldContinue = 0xF; int32_t landChangePerTile = _isLowering ? 2 : -2; - TileElement *tileElement, *nextTileElement; money32 totalCost = 0; // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) + if (!map_is_location_valid(loc) || !map_is_location_valid({ loc.x + stepX, loc.y + stepY })) { return 0; } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (tileElement == nullptr || nextTileElement == nullptr) + auto surfaceElement = map_get_surface_element_at(loc); + auto nextSurfaceElement = map_get_surface_element_at({ loc.x + stepX, loc.y + stepY }); + if (surfaceElement == nullptr || nextSurfaceElement == nullptr) { return 0; } - if (tile_element_get_corner_height(tileElement, checkDirection1) != expectedLandHeight1 + landChangePerTile) + if (tile_element_get_corner_height(surfaceElement, checkDirection1) != expectedLandHeight1 + landChangePerTile) { shouldContinue &= ~0x1; } - if (tile_element_get_corner_height(tileElement, checkDirection2) != expectedLandHeight2 + landChangePerTile) + if (tile_element_get_corner_height(surfaceElement, checkDirection2) != expectedLandHeight2 + landChangePerTile) { shouldContinue &= ~0x2; } - if (tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) + if (tile_element_get_corner_height(surfaceElement, checkDirection1) + != tile_element_get_corner_height(nextSurfaceElement, direction1)) { shouldContinue &= ~0x1; } - if (tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) + if (tile_element_get_corner_height(surfaceElement, checkDirection2) + != tile_element_get_corner_height(nextSurfaceElement, direction2)) { shouldContinue &= ~0x2; } + auto nextLoc = loc; while ((shouldContinue & 0x3) != 0) { shouldContinue = ((shouldContinue << 2) | 0x3) & shouldContinue; - x += stepX; - y += stepY; + nextLoc.x += stepX; + nextLoc.y += stepY; // check if we need to continue after raising the current tile // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) + if (!map_is_location_valid({ nextLoc.x + stepX, nextLoc.y + stepY })) { shouldContinue &= ~0x3; } else { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at({ x + stepX, y + stepY }); - if (nextTileElement == nullptr) + surfaceElement = nextSurfaceElement; + nextSurfaceElement = map_get_surface_element_at({ nextLoc.x + stepX, nextLoc.y + stepY }); + if (nextSurfaceElement == nullptr) { shouldContinue &= ~0x3; } - if (tile_element_get_corner_height(tileElement, direction1) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection1)) + if (tile_element_get_corner_height(surfaceElement, direction1) + landChangePerTile + != tile_element_get_corner_height(surfaceElement, checkDirection1)) { shouldContinue &= ~0x1; } - if (tile_element_get_corner_height(tileElement, direction2) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection2)) + if (tile_element_get_corner_height(surfaceElement, direction2) + landChangePerTile + != tile_element_get_corner_height(surfaceElement, checkDirection2)) { shouldContinue &= ~0x2; } if ((shouldContinue & 0x1) - && tile_element_get_corner_height(tileElement, checkDirection1) - != tile_element_get_corner_height(nextTileElement, direction1)) + && tile_element_get_corner_height(surfaceElement, checkDirection1) + != tile_element_get_corner_height(nextSurfaceElement, direction1)) { shouldContinue &= ~0x1; } if ((shouldContinue & 0x2) - && tile_element_get_corner_height(tileElement, checkDirection2) - != tile_element_get_corner_height(nextTileElement, direction2)) + && tile_element_get_corner_height(surfaceElement, checkDirection2) + != tile_element_get_corner_height(nextSurfaceElement, direction2)) { shouldContinue &= ~0x2; } @@ -200,8 +194,8 @@ private: expectedLandHeight1 += landChangePerTile; // change land of current tile - int32_t targetBaseZ = tileElement->base_height; - int32_t slope = tileElement->AsSurface()->GetSlope(); + int32_t targetBaseZ = surfaceElement->base_height; + int32_t slope = surfaceElement->AsSurface()->GetSlope(); int32_t oldSlope = slope; if (_isLowering) { @@ -215,7 +209,7 @@ private: } } if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) + && map_get_corner_height(surfaceElement->base_height, oldSlope, direction2) == map_get_corner_height(targetBaseZ, slope, direction2)) { slope = tile_element_lower_styles[direction2][slope]; @@ -238,7 +232,7 @@ private: } } if ((shouldContinue & 0x8) - && map_get_corner_height(tileElement->base_height, oldSlope, direction2) + && map_get_corner_height(surfaceElement->base_height, oldSlope, direction2) == map_get_corner_height(targetBaseZ, slope, direction2)) { slope = tile_element_raise_styles[direction2][slope]; @@ -249,7 +243,7 @@ private: } } } - auto landSetHeightAction = LandSetHeightAction({ x, y }, targetBaseZ, slope); + auto landSetHeightAction = LandSetHeightAction(nextLoc, targetBaseZ, slope); landSetHeightAction.SetFlags(GetFlags()); auto res = isExecuting ? GameActions::ExecuteNested(&landSetHeightAction) : GameActions::QueryNested(&landSetHeightAction); @@ -261,14 +255,12 @@ private: return totalCost; } - money32 smooth_land_row_by_corner( - bool isExecuting, int32_t x, int32_t y, int32_t expectedLandHeight, int32_t stepX, int32_t stepY, int32_t direction, + money32 SmoothLandRowByCorner( + bool isExecuting, CoordsXY loc, int32_t expectedLandHeight, int32_t stepX, int32_t stepY, int32_t direction, int32_t checkDirection) const { bool shouldContinue = true; - TileElement *tileElement, *nextTileElement; money32 totalCost = 0; - money32 result; int32_t landChangePerTile; if (stepX == 0 || stepY == 0) { @@ -280,74 +272,78 @@ private: } // check if we need to start at all - if (!map_is_location_valid({ x, y }) || !map_is_location_valid({ x + stepX, y + stepY })) + if (!map_is_location_valid(loc) || !map_is_location_valid({ loc.x + stepX, loc.y + stepY })) { return 0; } - tileElement = map_get_surface_element_at({ x, y }); - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (tileElement == nullptr || nextTileElement == nullptr) + auto surfaceElement = map_get_surface_element_at(loc); + auto nextSurfaceElement = map_get_surface_element_at({ loc.x + stepX, loc.y + stepY }); + if (surfaceElement == nullptr || nextSurfaceElement == nullptr) { return 0; } - if (tile_element_get_corner_height(tileElement, checkDirection) != expectedLandHeight + (_isLowering ? 2 : -2)) + if (tile_element_get_corner_height(surfaceElement, checkDirection) != expectedLandHeight + (_isLowering ? 2 : -2)) { return 0; } - if (tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) + if (tile_element_get_corner_height(surfaceElement, checkDirection) + != tile_element_get_corner_height(nextSurfaceElement, direction)) { return 0; } + + auto nextLoc = loc; while (shouldContinue) { - x += stepX; - y += stepY; + nextLoc.x += stepX; + nextLoc.y += stepY; // check if we need to continue after raising the current tile // this needs to be checked before the tile is changed - if (!map_is_location_valid({ x + stepX, y + stepY })) + if (!map_is_location_valid({ nextLoc.x + stepX, nextLoc.y + stepY })) { shouldContinue = false; } else { - tileElement = nextTileElement; - nextTileElement = map_get_surface_element_at((x + stepX) >> 5, (y + stepY) >> 5); - if (nextTileElement == nullptr) + surfaceElement = nextSurfaceElement; + nextSurfaceElement = map_get_surface_element_at({ nextLoc.x + stepX, nextLoc.y + stepY }); + if (nextSurfaceElement == nullptr) { shouldContinue = false; } - if (tile_element_get_corner_height(tileElement, direction) + landChangePerTile - != tile_element_get_corner_height(tileElement, checkDirection)) + if (tile_element_get_corner_height(surfaceElement, direction) + landChangePerTile + != tile_element_get_corner_height(surfaceElement, checkDirection)) { shouldContinue = false; } if (shouldContinue - && tile_element_get_corner_height(tileElement, checkDirection) - != tile_element_get_corner_height(nextTileElement, direction)) + && tile_element_get_corner_height(surfaceElement, checkDirection) + != tile_element_get_corner_height(nextSurfaceElement, direction)) { shouldContinue = false; } } if (stepX * stepY != 0) { - totalCost += smooth_land_row_by_corner( - isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, checkDirection ^ 3); - totalCost += smooth_land_row_by_corner( - isExecuting, x, y, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, checkDirection ^ 1); + totalCost += SmoothLandRowByCorner( + isExecuting, nextLoc, expectedLandHeight + (landChangePerTile / 2), 0, stepY, direction, + checkDirection ^ 3); + totalCost += SmoothLandRowByCorner( + isExecuting, nextLoc, expectedLandHeight + (landChangePerTile / 2), stepX, 0, direction, + checkDirection ^ 1); } expectedLandHeight += landChangePerTile; // change land of current tile - result = smooth_land_tile(direction, isExecuting, x, y, tileElement); - if (result != MONEY32_UNDEFINED) + auto result = SmoothLandTile(direction, isExecuting, nextLoc.x, nextLoc.y, surfaceElement); + if (result->Error == GA_ERROR::OK) { - totalCost += result; + totalCost += result->Cost; } } return totalCost; } - GameActionResult::Ptr smooth_land(bool isExecuting) const + GameActionResult::Ptr SmoothLand(bool isExecuting) const { // break up information in command const bool raiseLand = !_isLowering; @@ -385,57 +381,57 @@ private: // Smooth the 4 corners { // top-left - TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + auto surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 2), minHeight, maxHeight); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, -32, 0, 2); } { // bottom-left - TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetBottom() }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetBottom(), z, -32, 32, 1, 3); + auto surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetBottom() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 3), minHeight, maxHeight); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetBottom() }, z, -32, 32, 1, 3); } { // bottom-right - TileElement* tileElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetBottom() }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetRight(), validRange.GetBottom(), z, 32, 32, 2, 0); + auto surfaceElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetBottom() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 0), minHeight, maxHeight); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetRight(), validRange.GetBottom() }, z, 32, 32, 2, 0); } { // top-right - TileElement* tileElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetTop() }); - int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetRight(), validRange.GetTop(), z, 32, -32, 3, 1); + auto surfaceElement = map_get_surface_element_at({ validRange.GetRight(), validRange.GetTop() }); + int32_t z = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 1), minHeight, maxHeight); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetRight(), validRange.GetTop() }, z, 32, -32, 3, 1); } // Smooth the edges - TileElement* tileElement = nullptr; + TileElement* surfaceElement = nullptr; int32_t z1, z2; for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) { - tileElement = map_get_surface_element_at({ validRange.GetLeft(), y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - res->Cost += smooth_land_row_by_edge(isExecuting, validRange.GetLeft(), y, z1, z2, -32, 0, 0, 1, 3, 2); + surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), y }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 3), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 2), minHeight, maxHeight); + res->Cost += SmoothLandRowByEdge(isExecuting, { validRange.GetLeft(), y }, z1, z2, -32, 0, 0, 1, 3, 2); - tileElement = map_get_surface_element_at({ validRange.GetRight(), y }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - res->Cost += smooth_land_row_by_edge(isExecuting, validRange.GetRight(), y, z1, z2, 32, 0, 2, 3, 1, 0); + surfaceElement = map_get_surface_element_at({ validRange.GetRight(), y }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 1), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 0), minHeight, maxHeight); + res->Cost += SmoothLandRowByEdge(isExecuting, { validRange.GetRight(), y }, z1, z2, 32, 0, 2, 3, 1, 0); } for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) { - tileElement = map_get_surface_element_at({ x, validRange.GetTop() }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 1), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 2), minHeight, maxHeight); - res->Cost += smooth_land_row_by_edge(isExecuting, x, validRange.GetTop(), z1, z2, 0, -32, 0, 3, 1, 2); + surfaceElement = map_get_surface_element_at({ x, validRange.GetTop() }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 1), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 2), minHeight, maxHeight); + res->Cost += SmoothLandRowByEdge(isExecuting, { x, validRange.GetTop() }, z1, z2, 0, -32, 0, 3, 1, 2); - tileElement = map_get_surface_element_at({ x, validRange.GetBottom() }); - z1 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 0), minHeight, maxHeight); - z2 = std::clamp((uint8_t)tile_element_get_corner_height(tileElement, 3), minHeight, maxHeight); - res->Cost += smooth_land_row_by_edge(isExecuting, x, validRange.GetBottom(), z1, z2, 0, 32, 1, 2, 0, 3); + surfaceElement = map_get_surface_element_at({ x, validRange.GetBottom() }); + z1 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 0), minHeight, maxHeight); + z2 = std::clamp((uint8_t)tile_element_get_corner_height(surfaceElement, 3), minHeight, maxHeight); + res->Cost += SmoothLandRowByEdge(isExecuting, { x, validRange.GetBottom() }, z1, z2, 0, 32, 1, 2, 0, 3); } break; } @@ -444,9 +440,9 @@ private: case MAP_SELECT_TYPE_CORNER_2: case MAP_SELECT_TYPE_CORNER_3: { - TileElement* tileElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); - uint8_t newBaseZ = tileElement->base_height; - uint8_t newSlope = tileElement->AsSurface()->GetSlope(); + auto surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + uint8_t newBaseZ = surfaceElement->base_height; + uint8_t newSlope = surfaceElement->AsSurface()->GetSlope(); if (raiseLand) { @@ -465,71 +461,71 @@ private: // Smooth the corners int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, -32, 0, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); + res->Cost += SmoothLandRowByCorner(isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 32, 2, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 32, 1, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, -32, 3, 1); // Smooth the edges switch (selectionType) { case MAP_SELECT_TYPE_CORNER_0: z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 0, 3, 0); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, 32, 1, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 0, 0, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, -32, 0, 1); break; case MAP_SELECT_TYPE_CORNER_1: z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 0, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 0, 2, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, -32, 0, 1); z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 0, 1, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 1, 0); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, 32, 1, 0); break; case MAP_SELECT_TYPE_CORNER_2: z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 1, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 0, 1, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, -32, 3, 2); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 2, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 0, 2, 1); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, 32, 2, 3); break; case MAP_SELECT_TYPE_CORNER_3: z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 0, 0, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, 32, 2, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 0, 0, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, 32, 2, 3); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 0, 3, 0); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 0, 3, 0); z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 0, -32, 3, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 0, -32, 3, 2); break; } break; @@ -541,7 +537,7 @@ private: { // TODO: Handle smoothing by edge // Get the two corners to raise - TileElement* surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); + auto surfaceElement = map_get_surface_element_at({ validRange.GetLeft(), validRange.GetTop() }); uint8_t newBaseZ = surfaceElement->base_height; uint8_t oldSlope = surfaceElement->AsSurface()->GetSlope(); uint8_t newSlope = oldSlope; @@ -565,8 +561,8 @@ private: const uint8_t edge = selectionType - MAP_SELECT_TYPE_EDGE_0; - // Table with corners for each edge selection. The first two are the selected corners, the latter two are the - // opposites + // Table with corners for each edge selection. The first two are the selected corners, the latter + // two are the opposites static constexpr uint8_t cornerIndices[][4] = { { 2, 3, 1, 0 }, // MAP_SELECT_TYPE_EDGE_0 { 3, 0, 2, 1 }, // MAP_SELECT_TYPE_EDGE_1 @@ -591,32 +587,32 @@ private: uint8_t z3 = map_get_corner_height(newBaseZ, newSlope, c3); uint8_t z4 = map_get_corner_height(newBaseZ, newSlope, c4); // Smooth the edge at the top of the new slope - res->Cost += smooth_land_row_by_edge( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, z2, stepOffsets[edge].x, stepOffsets[edge].y, - c3, c4, c1, c2); + res->Cost += SmoothLandRowByEdge( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z1, z2, stepOffsets[edge].x, + stepOffsets[edge].y, c3, c4, c1, c2); // Smooth the edge at the bottom of the new slope - res->Cost += smooth_land_row_by_edge( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z3, z4, -stepOffsets[edge].x, -stepOffsets[edge].y, - c1, c2, c3, c4); + res->Cost += SmoothLandRowByEdge( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z3, z4, -stepOffsets[edge].x, + -stepOffsets[edge].y, c1, c2, c3, c4); // Smooth corners - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z1, -stepOffsets[edge].y, stepOffsets[edge].x, c2, - c1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z2, stepOffsets[edge].y, -stepOffsets[edge].x, c1, - c2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z1, -stepOffsets[edge].y, stepOffsets[edge].x, + c2, c1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z2, stepOffsets[edge].y, -stepOffsets[edge].x, + c1, c2); int32_t z = map_get_corner_height(newBaseZ, newSlope, 2); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, -32, 0, 2); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, -32, 0, 2); z = map_get_corner_height(newBaseZ, newSlope, 0); - res->Cost += smooth_land_row_by_corner(isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, 32, 2, 0); + res->Cost += SmoothLandRowByCorner(isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, 32, 2, 0); z = map_get_corner_height(newBaseZ, newSlope, 3); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, -32, 32, 1, 3); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, -32, 32, 1, 3); z = map_get_corner_height(newBaseZ, newSlope, 1); - res->Cost += smooth_land_row_by_corner( - isExecuting, validRange.GetLeft(), validRange.GetTop(), z, 32, -32, 3, 1); + res->Cost += SmoothLandRowByCorner( + isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, -32, 3, 1); break; } } // switch selectionType From 3e7a5bdd7e40f57d0bb9ec235ba5971c353255ce Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 20 Mar 2019 20:36:20 +0100 Subject: [PATCH 133/506] Add LandSmoothAction.hpp to Xcode project. --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 085105a046..2d374072be 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -118,6 +118,7 @@ 9346F9DB208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; }; 9346F9DC208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; }; 9346F9DD208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; }; + 937A92152242CDAA00B09278 /* LandSmoothAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */; }; 939A359A20C12FC800630B3F /* Paint.Litter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359720C12FC700630B3F /* Paint.Litter.cpp */; }; 939A359B20C12FC800630B3F /* Paint.Misc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359820C12FC700630B3F /* Paint.Misc.cpp */; }; 939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 939A359920C12FC700630B3F /* Paint.Sprite.h */; }; @@ -1240,6 +1241,7 @@ 9350B52720B46E0900897BC5 /* ftbdf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftbdf.h; sourceTree = ""; }; 9350B52820B46E0900897BC5 /* ftrender.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftrender.h; sourceTree = ""; }; 9350B52920B46E0900897BC5 /* ft2build.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ft2build.h; sourceTree = ""; }; + 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandSmoothAction.hpp; sourceTree = ""; }; 939A359720C12FC700630B3F /* Paint.Litter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Litter.cpp; sourceTree = ""; }; 939A359820C12FC700630B3F /* Paint.Misc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Misc.cpp; sourceTree = ""; }; 939A359920C12FC700630B3F /* Paint.Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Paint.Sprite.h; sourceTree = ""; }; @@ -2152,6 +2154,7 @@ C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */, C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */, C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */, + 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */, 2A61CAFA2229E5C50095AD67 /* RideEntranceExitPlaceAction.hpp */, 2A61CAF82229E59F0095AD67 /* WaterSetHeightAction.hpp */, 2A61CAF42229E5720095AD67 /* FootpathPlaceAction.hpp */, @@ -3520,6 +3523,7 @@ 2ADE2F0A2244187B002598AF /* ParkSetResearchFundingAction.hpp in Headers */, 2ADE2F142244187B002598AF /* FootpathRemoveAction.hpp in Headers */, 2ADE2F1F2244187B002598AF /* BannerSetNameAction.hpp in Headers */, + 937A92152242CDAA00B09278 /* LandSmoothAction.hpp in Headers */, C6352B941F477032006CCEE3 /* PlaceParkEntranceAction.hpp in Headers */, C6352B911F477032006CCEE3 /* GameAction.h in Headers */, 2A43D2BA2225B8D900E8F73B /* RideSetVehiclesAction.hpp in Headers */, From 68bf1bc46409bea7d774adc4067cb2e5e57d001e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 25 Mar 2019 18:28:21 +0000 Subject: [PATCH 134/506] Make requested changes --- src/openrct2/actions/LandSmoothAction.hpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/openrct2/actions/LandSmoothAction.hpp b/src/openrct2/actions/LandSmoothAction.hpp index 287feb97a4..289e0a13c0 100644 --- a/src/openrct2/actions/LandSmoothAction.hpp +++ b/src/openrct2/actions/LandSmoothAction.hpp @@ -32,8 +32,8 @@ DEFINE_GAME_ACTION(LandSmoothAction, GAME_COMMAND_EDIT_LAND_SMOOTH, GameActionRe private: CoordsXY _coords; MapRange _range; - uint8_t _selectionType; - bool _isLowering; + uint8_t _selectionType{ 0 }; + bool _isLowering{ false }; constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_LOWER_LAND_HERE, STR_CANT_RAISE_LAND_HERE }; @@ -72,13 +72,6 @@ public: } private: - GameActionResult::Ptr QueryExecute(bool isExecuting) const - { - auto res = MakeResult(); - - return res; - } - GameActionResult::Ptr SmoothLandTile(int32_t direction, bool isExecuting, int32_t x, int32_t y, TileElement* surfaceElement) const { @@ -345,7 +338,6 @@ private: GameActionResult::Ptr SmoothLand(bool isExecuting) const { - // break up information in command const bool raiseLand = !_isLowering; const int32_t selectionType = _selectionType; const int32_t heightOffset = raiseLand ? 2 : -2; @@ -358,11 +350,11 @@ private: auto b = std::clamp(normRange.GetBottom(), 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); auto validRange = MapRange{ l, t, r, b }; - // Play sound (only once) int32_t centreZ = tile_element_height(_coords.x, _coords.y) & 0xFFFF; auto res = MakeResult(); res->ErrorTitle = _ErrorTitles[_isLowering ? 0 : 1]; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; res->Position = { _coords.x, _coords.y, centreZ }; // Do the smoothing @@ -615,6 +607,9 @@ private: isExecuting, { validRange.GetLeft(), validRange.GetTop() }, z, 32, -32, 3, 1); break; } + default: + log_error("Invalid map selection %u", _selectionType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, res->ErrorTitle); } // switch selectionType // Raise / lower the land tool selection area @@ -640,10 +635,7 @@ private: { audio_play_sound_at_location(SOUND_PLACE_ITEM, _coords.x, _coords.y, centreZ); } - res->Cost += res->Cost; - - res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - + res->Cost += result->Cost; return res; } }; From 9b4bc97826e416aac85969e60ae4f0af0162f496 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 27 Mar 2019 18:49:19 +0000 Subject: [PATCH 135/506] 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 c310c5897a..90c27248ee 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 "12" +#define NETWORK_STREAM_VERSION "13" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From bbf523e829f9645f436b5d8909510deecf6abb87 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 27 Mar 2019 20:07:13 +0100 Subject: [PATCH 136/506] Fix #8537: Imported RCT1 rides/shops are all numbered 1 --- distribution/changelog.txt | 1 + src/openrct2/rct1/S4Importer.cpp | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 236dcfdfe2..9480598377 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Fix: [#5579] Network desync immediately after connecting. - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. +- Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). - Fix: [#8900] Peep tracking is not synchronized. diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 920eeaea8f..0e61e26db1 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -198,6 +198,7 @@ public: ImportSavedView(); FixLandOwnership(); CountBlockSections(); + SetDefaultNames(); determine_ride_entrance_and_exit_locations(); // Importing the strings is done later on, although that approach needs looking at. @@ -789,10 +790,6 @@ private: } } } - if (dst->name == 0) - { - ride_set_name_to_default(dst, rideEntry); - } dst->status = src->status; @@ -2979,6 +2976,24 @@ private: } } } + + /** + * This has to be done after importing tile elements, because it needs those to detect if a pre-existing ride + * name should be considered reserved. + */ + void SetDefaultNames() + { + ride_id_t i; + Ride* ride; + FOR_ALL_RIDES (i, ride) + { + if (ride->name == 0) + { + auto rideEntry = get_ride_entry(ride->subtype); + ride_set_name_to_default(ride, rideEntry); + } + } + } }; std::unique_ptr ParkImporter::CreateS4() From ec3d757854163d7bd2fc145ede0c7e759883a785 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 27 Mar 2019 20:53:48 +0100 Subject: [PATCH 137/506] Fix #5905: Urban Park MGR has entrance/exit swapped --- distribution/changelog.txt | 1 + src/openrct2/rct1/S4Importer.cpp | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9480598377..cb3415c26d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. +- Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 0e61e26db1..9c86195a03 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -103,6 +103,7 @@ private: rct1_s4 _s4 = {}; uint8_t _gameVersion = 0; uint8_t _parkValueConversionFactor = 0; + bool _isScenario = false; // Lists of dynamic object entries EntryList _rideEntries; @@ -168,6 +169,7 @@ public: { _s4 = *ReadAndDecodeS4(stream, isScenario); _s4Path = path; + _isScenario = isScenario; // Only determine what objects we required to import this saved game InitialiseEntryMaps(); @@ -197,6 +199,7 @@ public: ImportScenarioObjective(); ImportSavedView(); FixLandOwnership(); + FixUrbanPark(); CountBlockSections(); SetDefaultNames(); determine_ride_entrance_and_exit_locations(); @@ -2937,6 +2940,50 @@ private: } } + /** + * In Urban Park, the entrance and exit of the merry-go-round are the wrong way round. This code fixes that. + * To avoid messing up saves (in which this problem is most likely solved by the user), only carry out this + * fix when loading from a scenario. + */ + void FixUrbanPark() + { + if (_s4.scenario_slot_index == SC_URBAN_PARK && _isScenario) + { + // First, make the queuing peep exit + int32_t i; + Peep* peep; + FOR_ALL_GUESTS (i, peep) + { + if (peep->state == PEEP_STATE_QUEUING_FRONT && peep->current_ride == 0) + { + peep->RemoveFromQueue(); + peep->SetState(PEEP_STATE_FALLING); + break; + } + } + + // Now, swap the entrance and exit. + Ride* ride = get_ride(0); + auto entranceCoords = ride->stations[0].Exit; + auto exitCoords = ride->stations[0].Entrance; + ride->stations[0].Entrance = entranceCoords; + ride->stations[0].Exit = exitCoords; + + auto entranceElement = map_get_ride_exit_element_at( + entranceCoords.x * 32, entranceCoords.y * 32, entranceCoords.z, false); + entranceElement->SetEntranceType(ENTRANCE_TYPE_RIDE_ENTRANCE); + auto exitElement = map_get_ride_entrance_element_at(exitCoords.x * 32, exitCoords.y * 32, exitCoords.z, false); + exitElement->SetEntranceType(ENTRANCE_TYPE_RIDE_EXIT); + + // Trigger footpath update + footpath_queue_chain_reset(); + footpath_connect_edges( + entranceCoords.x * 32, (entranceCoords.y) * 32, (TileElement*)entranceElement, + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); + footpath_update_queue_chains(); + } + } + /** * Counts the block sections. The reason this iterates over the map is to avoid getting into infinite loops, * which can happen with hacked parks. From 731af7473202b931ce243321bc7c42f9800dafc9 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 27 Mar 2019 21:49:10 +0100 Subject: [PATCH 138/506] Cast after std::min --- src/openrct2/rct12/RCT12.h | 6 +++--- src/openrct2/rct2/S6Exporter.cpp | 4 ++-- src/openrct2/ride/Ride.h | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 78c69372bf..d355722fe8 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -39,9 +39,9 @@ #define RCT12_PEEP_MAX_THOUGHTS 5 -#define RCT12_MAX_INVERSIONS 31 -#define RCT12_MAX_GOLF_HOLES 31 -#define RCT12_MAX_HELICES 31 +constexpr uint16_t const RCT12_MAX_INVERSIONS = 31; +constexpr uint16_t const RCT12_MAX_GOLF_HOLES = 31; +constexpr uint16_t const RCT12_MAX_HELICES = 31; #pragma pack(push, 1) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 7af8b06ef3..6c3b21e48c 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -561,9 +561,9 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->turn_count_banked = src->turn_count_banked; dst->turn_count_sloped = src->turn_count_sloped; if (dst->type == RIDE_TYPE_MINI_GOLF) - dst->inversions = std::min((uint8_t)src->holes, (uint8_t)RCT12_MAX_GOLF_HOLES); + dst->inversions = (uint8_t)std::min(src->holes, RCT12_MAX_GOLF_HOLES); else - dst->inversions = std::min((uint8_t)src->inversions, (uint8_t)RCT12_MAX_INVERSIONS); + dst->inversions = (uint8_t)std::min(src->inversions, RCT12_MAX_INVERSIONS); dst->inversions |= (src->sheltered_eighths << 5); dst->drops = src->drops; dst->start_drop_height = src->start_drop_height; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 3b512969c5..5663193bf0 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -39,9 +39,10 @@ struct Staff; #define MAX_RIDES 255 #define RIDE_ID_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 -#define MAX_INVERSIONS RCT12_MAX_INVERSIONS -#define MAX_GOLF_HOLES RCT12_MAX_GOLF_HOLES -#define MAX_HELICES RCT12_MAX_HELICES + +constexpr uint16_t const MAX_INVERSIONS = RCT12_MAX_INVERSIONS; +constexpr uint16_t const MAX_GOLF_HOLES = RCT12_MAX_GOLF_HOLES; +constexpr uint16_t const MAX_HELICES = RCT12_MAX_HELICES; #pragma pack(push, 1) From a50c7836f807fa8021bb62c5a9b234d8dbf64477 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 27 Mar 2019 21:53:38 +0100 Subject: [PATCH 139/506] Move more ride functions to struct methods (#8977) --- src/openrct2/actions/RideCreateAction.hpp | 4 +- src/openrct2/actions/RideDemolishAction.hpp | 2 +- src/openrct2/ride/Ride.cpp | 68 ++++++++++----------- src/openrct2/ride/Ride.h | 32 ++++++---- src/openrct2/ride/RideRatings.cpp | 13 ++-- src/openrct2/ride/Vehicle.cpp | 8 +-- 6 files changed, 67 insertions(+), 60 deletions(-) diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 93e35cd2cc..1f676d3c63 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -134,7 +134,7 @@ public: ride->id = rideIndex; ride->type = _rideType; ride->subtype = rideEntryIndex; - ride_set_colour_preset(ride, _colour1); + ride->SetColourPreset(_colour1); ride->overall_view.xy = RCT_XY8_UNDEFINED; // Ride name @@ -301,7 +301,7 @@ public: ride->guests_favourite = 0; ride->num_circuits = 1; - ride->mode = ride_get_default_mode(ride); + ride->mode = ride->GetDefaultMode(); ride->min_max_cars_per_train = (rideEntry->min_cars_in_train << 4) | rideEntry->max_cars_in_train; ride_set_vehicle_colours_to_random_preset(ride, _colour2); window_invalidate_by_class(WC_RIDE_LIST); diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 28f67d1876..3264f5ee1f 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -130,7 +130,7 @@ private: ride_clear_for_construction(ride); ride_remove_peeps(ride); - ride_stop_peeps_queuing(ride); + ride->StopGuestsQueuing(); sub_6CB945(ride); ride_clear_leftover_entrances(ride); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 0236682626..9d32efe96c 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4569,7 +4569,7 @@ static void ride_set_start_finish_points(ride_id_t rideIndex, CoordsXYE* startEl break; } - if (ride_is_block_sectioned(ride) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) + if (ride->IsBlockSectioned() && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) { ride_set_block_points(startElement); } @@ -4843,7 +4843,7 @@ static void vehicle_create_trains(ride_id_t rideIndex, int32_t x, int32_t y, int for (int32_t vehicleIndex = 0; vehicleIndex < ride->num_vehicles; vehicleIndex++) { - if (ride_is_block_sectioned(ride)) + if (ride->IsBlockSectioned()) { remainingDistance = 0; } @@ -5023,7 +5023,7 @@ static bool ride_create_vehicles(Ride* ride, CoordsXYE* element, int32_t isApply // if (ride->type != RIDE_TYPE_SPACE_RINGS && !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_16)) { - if (ride_is_block_sectioned(ride)) + if (ride->IsBlockSectioned()) { CoordsXYE firstBlock; ride_create_vehicles_find_first_block(ride, &firstBlock); @@ -5776,7 +5776,7 @@ int32_t ride_get_refund_price(const Ride* ride) * * rct2: 0x00696707 */ -void ride_stop_peeps_queuing(Ride* ride) +void Ride::StopGuestsQueuing() { uint16_t spriteIndex; Peep* peep; @@ -5785,7 +5785,7 @@ void ride_stop_peeps_queuing(Ride* ride) { if (peep->state != PEEP_STATE_QUEUING) continue; - if (peep->current_ride != ride->id) + if (peep->current_ride != id) continue; peep->RemoveFromQueue(); @@ -5806,14 +5806,14 @@ ride_id_t ride_get_empty_slot() return RIDE_ID_NULL; } -int32_t ride_get_default_mode(Ride* ride) +uint8_t Ride::GetDefaultMode() const { - const rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); + const rct_ride_entry* rideEntry = get_ride_entry(subtype); const uint8_t* availableModes = RideAvailableModes; - for (int32_t i = 0; i < ride->type; i++) + for (int32_t i = 0; i < type; i++) { - while (*(availableModes++) != 255) + while (*(availableModes++) != RIDE_MODE_NULL) { } } @@ -5894,14 +5894,14 @@ int32_t ride_get_random_colour_preset_index(uint8_t ride_type) * * Based on rct2: 0x006B4776 */ -void ride_set_colour_preset(Ride* ride, uint8_t index) +void Ride::SetColourPreset(uint8_t index) { - const track_colour_preset_list* colourPresets = &RideColourPresets[ride->type]; + const track_colour_preset_list* colourPresets = &RideColourPresets[type]; TrackColour colours = { COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK }; // Stalls save their default colour in the vehicle settings (since they share a common ride type) - if (!ride->IsRide()) + if (!IsRide()) { - auto rideEntry = get_ride_entry(ride->subtype); + auto rideEntry = get_ride_entry(subtype); if (rideEntry != nullptr && rideEntry->vehicle_preset_list->count > 0) { auto list = rideEntry->vehicle_preset_list->list[0]; @@ -5914,11 +5914,11 @@ void ride_set_colour_preset(Ride* ride, uint8_t index) } for (int32_t i = 0; i < NUM_COLOUR_SCHEMES; i++) { - ride->track_colour[i].main = colours.main; - ride->track_colour[i].additional = colours.additional; - ride->track_colour[i].supports = colours.supports; + track_colour[i].main = colours.main; + track_colour[i].additional = colours.additional; + track_colour[i].supports = colours.supports; } - ride->colour_scheme_type = 0; + colour_scheme_type = 0; } money32 ride_get_common_price(Ride* forRide) @@ -6228,34 +6228,34 @@ int32_t get_turn_count_4_plus_elements(Ride* ride, uint8_t type) return ((*turn_count) & TURN_MASK_4_PLUS_ELEMENTS) >> 11; } -bool ride_has_spinning_tunnel(Ride* ride) +bool Ride::HasSpinningTunnel() const { - return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; + return special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; } -bool ride_has_water_splash(Ride* ride) +bool Ride::HasWaterSplash() const { - return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; + return special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; } -bool ride_has_rapids(Ride* ride) +bool Ride::HasRapids() const { - return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; + return special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS; } -bool ride_has_log_reverser(Ride* ride) +bool Ride::HasLogReverser() const { - return ride->special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL; + return special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL; } -bool ride_has_waterfall(Ride* ride) +bool Ride::HasWaterfall() const { - return ride->special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL; + return special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL; } -bool ride_has_whirlpool(Ride* ride) +bool Ride::HasWhirlpool() const { - return ride->special_track_elements & RIDE_ELEMENT_WHIRLPOOL; + return special_track_elements & RIDE_ELEMENT_WHIRLPOOL; } uint8_t ride_get_helix_sections(Ride* ride) @@ -6264,15 +6264,15 @@ uint8_t ride_get_helix_sections(Ride* ride) return ride->special_track_elements & 0x1F; } -bool ride_is_powered_launched(Ride* ride) +bool Ride::IsPoweredLaunched() const { - return ride->mode == RIDE_MODE_POWERED_LAUNCH_PASSTROUGH || ride->mode == RIDE_MODE_POWERED_LAUNCH - || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED; + return mode == RIDE_MODE_POWERED_LAUNCH_PASSTROUGH || mode == RIDE_MODE_POWERED_LAUNCH + || mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED; } -bool ride_is_block_sectioned(Ride* ride) +bool Ride::IsBlockSectioned() const { - return ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED; + return mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED; } bool ride_has_any_track_elements(const Ride* ride) diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 52da75a93a..e57a453a8d 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -364,6 +364,22 @@ struct Ride void SetNumVehicles(int32_t numVehicles); void SetNumCarsPerVehicle(int32_t numCarsPerVehicle); void UpdateMaxVehicles(); + + bool HasSpinningTunnel() const; + bool HasWaterSplash() const; + bool HasRapids() const; + bool HasLogReverser() const; + bool HasWaterfall() const; + bool HasWhirlpool() const; + + bool IsPoweredLaunched() const; + bool IsBlockSectioned() const; + + void StopGuestsQueuing(); + + uint8_t GetDefaultMode() const; + + void SetColourPreset(uint8_t index); }; #pragma pack(push, 1) @@ -638,7 +654,10 @@ enum RIDE_MODE_FREEFALL_DROP, RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED, RIDE_MODE_POWERED_LAUNCH, // RCT1 style, don't pass through station - RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED + RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED, + + RIDE_MOUNT_COUNT, + RIDE_MODE_NULL = 255, }; enum @@ -1005,7 +1024,6 @@ extern bool gGotoStartPlacementMode; extern uint8_t gLastEntranceStyle; ride_id_t ride_get_empty_slot(); -int32_t ride_get_default_mode(Ride* ride); int32_t ride_get_count(); int32_t ride_get_total_queue_length(Ride* ride); int32_t ride_get_max_queue_time(Ride* ride); @@ -1065,7 +1083,6 @@ void game_command_set_ride_name( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); int32_t ride_get_refund_price(const Ride* ride); int32_t ride_get_random_colour_preset_index(uint8_t ride_type); -void ride_set_colour_preset(Ride* ride, uint8_t index); money32 ride_get_common_price(Ride* forRide); rct_ride_name get_ride_naming(const uint8_t rideType, rct_ride_entry* rideEntry); void game_command_create_ride(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); @@ -1098,16 +1115,8 @@ int32_t get_turn_count_3_elements(Ride* ride, uint8_t type); int32_t get_turn_count_4_plus_elements(Ride* ride, uint8_t type); uint8_t ride_get_helix_sections(Ride* ride); -bool ride_has_spinning_tunnel(Ride* ride); -bool ride_has_water_splash(Ride* ride); -bool ride_has_rapids(Ride* ride); -bool ride_has_log_reverser(Ride* ride); -bool ride_has_waterfall(Ride* ride); -bool ride_has_whirlpool(Ride* ride); bool ride_type_has_flag(int32_t rideType, uint32_t flag); -bool ride_is_powered_launched(Ride* ride); -bool ride_is_block_sectioned(Ride* ride); bool ride_has_any_track_elements(const Ride* ride); void ride_all_has_any_track_elements(bool* rideIndexArray); @@ -1188,7 +1197,6 @@ int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType); StationObject* ride_get_station_object(const Ride* ride); void ride_action_modify(Ride* ride, int32_t modifyType, int32_t flags); -void ride_stop_peeps_queuing(Ride* ride); LocationXY16 ride_get_rotated_coords(int16_t x, int16_t y, int16_t z); diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index c2908d5ab8..e73be2f51a 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1181,7 +1181,7 @@ static rating_tuple get_special_track_elements_rating(uint8_t type, Ride* ride) int32_t excitement = 0, intensity = 0, nausea = 0; if (type == RIDE_TYPE_GHOST_TRAIN) { - if (ride_has_spinning_tunnel(ride)) + if (ride->HasSpinningTunnel()) { excitement += 40; intensity += 25; @@ -1190,8 +1190,7 @@ static rating_tuple get_special_track_elements_rating(uint8_t type, Ride* ride) } else if (type == RIDE_TYPE_LOG_FLUME) { - // Reverser for log flume - if (ride_has_log_reverser(ride)) + if (ride->HasLogReverser()) { excitement += 48; intensity += 55; @@ -1200,18 +1199,18 @@ static rating_tuple get_special_track_elements_rating(uint8_t type, Ride* ride) } else { - if (ride_has_water_splash(ride)) + if (ride->HasWaterSplash()) { excitement += 50; intensity += 30; nausea += 20; } - if (ride_has_waterfall(ride)) + if (ride->HasWaterfall()) { excitement += 55; intensity += 30; } - if (ride_has_whirlpool(ride)) + if (ride->HasWhirlpool()) { excitement += 35; intensity += 20; @@ -2254,7 +2253,7 @@ static void ride_ratings_calculate_looping_roller_coaster(Ride* ride) if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) return; - ride->unreliability_factor = ride_is_powered_launched(ride) ? 20 : 15; + ride->unreliability_factor = ride->IsPoweredLaunched() ? 20 : 15; set_unreliability_factor(ride); rating_tuple ratings; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 00a449b979..f04cddd96f 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2906,7 +2906,7 @@ static bool vehicle_can_depart_synchronised(rct_vehicle* vehicle) { if (sv_ride->status != RIDE_STATUS_CLOSED) { - if (ride_is_block_sectioned(sv_ride)) + if (sv_ride->IsBlockSectioned()) { if (!(sv_ride->stations[sv->station_id].Depart & STATION_DEPART_FLAG)) { @@ -6655,7 +6655,7 @@ static void check_and_apply_block_section_stop_site(rct_vehicle* vehicle) switch (trackType) { case TRACK_ELEM_BLOCK_BRAKES: - if (ride_is_block_sectioned(ride)) + if (ride->IsBlockSectioned()) apply_block_brakes(vehicle, trackElement->AsTrack()->BlockBrakeClosed()); else apply_non_stop_block_brake(vehicle, true); @@ -6671,7 +6671,7 @@ static void check_and_apply_block_section_stop_site(rct_vehicle* vehicle) case TRACK_ELEM_CABLE_LIFT_HILL: case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT: case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT: - if (ride_is_block_sectioned(ride)) + if (ride->IsBlockSectioned()) { if (trackType == TRACK_ELEM_CABLE_LIFT_HILL || trackElement->AsTrack()->HasChain()) { @@ -6774,7 +6774,7 @@ static void vehicle_update_block_brakes_open_previous_section(rct_vehicle* vehic if (trackType == TRACK_ELEM_BLOCK_BRAKES || trackType == TRACK_ELEM_END_STATION) { Ride* ride = get_ride(vehicle->ride); - if (ride_is_block_sectioned(ride)) + if (ride->IsBlockSectioned()) { audio_play_sound_at_location(SOUND_48, x, y, z); } From 9ed3c39aefd24a1d0abab09cac593ea10d5a46a0 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 27 Mar 2019 21:56:12 +0100 Subject: [PATCH 140/506] Fix #7913: RCT1/RCT2 title sequence timing is off (#8980) --- CMakeLists.txt | 4 ++-- distribution/changelog.txt | 1 + openrct2.proj | 4 ++-- shell.nix | 4 ++-- src/openrct2-android/app/build.gradle | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1da9947a08..31e705baaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") set(CMAKE_MACOSX_RPATH 1) -set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip") -set(TITLE_SEQUENCE_SHA1 "1136ef92bfb05cd1cba9831ba6dc4a653d87a246") +set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip") +set(TITLE_SEQUENCE_SHA1 "261a7185d8f60b90d1a390bf4e48a0c797b52e48") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip") set(OBJECTS_SHA1 "0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f") diff --git a/distribution/changelog.txt b/distribution/changelog.txt index cb3415c26d..cd6527ed8a 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -8,6 +8,7 @@ - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. +- Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). diff --git a/openrct2.proj b/openrct2.proj index ed32fda0fd..03829d1ac2 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -68,8 +68,8 @@ 2fe3bd994b3189899d93f1d5a881e725e046fdc2 https://github.com/google/googletest/archive/$(GtestVersion).zip 058b9df80244c03f1633cb06e9f70471a29ebb8e - https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip - 1136ef92bfb05cd1cba9831ba6dc4a653d87a246 + https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip + 261a7185d8f60b90d1a390bf4e48a0c797b52e48 https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip 0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f diff --git a/shell.nix b/shell.nix index 28bd1b8844..6e10ccd999 100644 --- a/shell.nix +++ b/shell.nix @@ -22,8 +22,8 @@ let title-sequences-src = pkgs.fetchFromGitHub { owner = "OpenRCT2"; repo = "title-sequences"; - rev = "v0.1.2"; - sha256 = "1yb1ynkfmiankii3fngr9km5wbc07rp30nh0apkj6wryrhy7imgm"; + rev = "v0.1.2a"; + sha256 = "7536dbd7c8b91554306e5823128f6bb7e94862175ef09d366d25e4bce573d155"; }; in pkgs.stdenv.mkDerivation { diff --git a/src/openrct2-android/app/build.gradle b/src/openrct2-android/app/build.gradle index 8085ee78ff..090fb9caff 100644 --- a/src/openrct2-android/app/build.gradle +++ b/src/openrct2-android/app/build.gradle @@ -90,7 +90,7 @@ android.applicationVariants.all { variant -> dest "$variant.mergeAssets.outputDir/data" } download { - src 'https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip' + src 'https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip' dest new File(buildDir, 'title-sequence.zip') } copy { From 0902b019d453d0d488df5b71802b3e6d78cb4d41 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 28 Mar 2019 04:00:23 +0000 Subject: [PATCH 141/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 1 - data/language/nl-NL.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 3f70a44e1a..4714b91bda 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -2420,7 +2420,6 @@ STR_3190 :공원 기타 STR_3191 :조형물 분류 STR_3192 :공원 입구 STR_3193 :물 -STR_3194 :시나리오 설명 STR_3195 :연구 목록 STR_3196 :{WINDOW_COLOUR_2}개발 그룹: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}게임 시작시 바로 사용할 수 있는 항목: diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index 30ec7939d1..bb0d625519 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -2426,7 +2426,6 @@ STR_3190 :Extra's voor paden STR_3191 :Decorgroepen STR_3192 :Parkingang STR_3193 :Water -STR_3194 :Scenariobeschrijving STR_3195 :Lijst van uitvindingen STR_3196 :{WINDOW_COLOUR_2}Onderzoeksgroep: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Items die aan het begin al zijn uitgevonden: From 70ae847a7299bea864b38ee316a914c5a4162a0e Mon Sep 17 00:00:00 2001 From: hokasha2016 <46494088+hokasha2016@users.noreply.github.com> Date: Thu, 28 Mar 2019 15:20:01 -0400 Subject: [PATCH 142/506] Fix #8219: Faulty folder recreation in "save" folder --- src/openrct2-ui/windows/LoadSave.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index e090441d79..2432414cfa 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -240,17 +240,10 @@ static const char* getFilterPatternByType(const int32_t type, const bool isSave) static int32_t window_loadsave_get_dir(const int32_t type, char* path, size_t pathSize) { const char* last_save = getLastDirectoryByType(type); - if (last_save && platform_ensure_directory_exists(last_save)) + if (last_save != nullptr && platform_directory_exists(last_save)) safe_strcpy(path, last_save, pathSize); else getInitialDirectoryByType(type, path, pathSize); - - if (!platform_ensure_directory_exists(path)) - { - log_error("Unable to create save directory."); - return 0; - } - return 1; } From 1bb5b61f3e45ef846b93fe0fb380b12fd0f29d66 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 28 Mar 2019 20:21:13 +0100 Subject: [PATCH 143/506] Add #8219 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index cd6527ed8a..8aa12f2c15 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -9,6 +9,7 @@ - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. +- Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). From ba08997c33f995561b7c1ec5c6c2ff951caf10ef Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Fri, 29 Mar 2019 04:00:31 +0000 Subject: [PATCH 144/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 318 ++++++++++++++++++++-------------------- 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 4714b91bda..3e0b80cb60 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -73,7 +73,7 @@ STR_0068 :하트라인 트위스터 코스터 STR_0069 :미니 골프 STR_0070 :기가 코스터 STR_0071 :자이로드롭 -STR_0072 :비행 접시 +STR_0072 :비행접시 STR_0073 :비뚤어진 집 STR_0074 :모노레일 사이클 STR_0075 :컴팩트 인버티드 코스터 @@ -112,7 +112,7 @@ STR_0526 :손님들이 높은 곳으로 회전하면서 올라가는 관망 STR_0527 :수직 루프를 사용할 수 있는 부드러운 철제 트랙의 롤러코스터입니다. STR_0528 :손님들이 공기를 넣은 고무 보트를 타고 반원이나 원형의 튜브 트랙을 따라 이동하는 놀이기구입니다. STR_0529 :오래된 기차 선로처럼 보이게 만든 철제 트랙을 따라 움직이는 탄광 열차 테마를 한 롤러코스터 차량입니다. -STR_0530 :철제 케이블에 달린 차량이 연속적으로 놀이기구의 한쪽 끝에서 다른쪽 끝을 왕복 운행합니다. +STR_0530 :철제 케이블에 달린 차량이 연속적으로 놀이기구의 한쪽 끝에서 다른 쪽 끝을 왕복 운행합니다. STR_0531 :차량이 나선 트랙과 루프를 통과하는 알찬 구성의 철제 트랙 롤러코스터입니다. STR_0532 : STR_0533 : @@ -144,7 +144,7 @@ STR_0561 : STR_0562 :무서운 풍경과 특수 효과를 통과하며 여러 높이의 트랙을 따라 이동하는 전동 차량입니다. STR_0563 :탑승객들은 한 바퀴를 운행하는 편안한 좌석에 앉아 언덕을 오르면서 느낄 수 있는 '무중력 시간'뿐만이 아니라 크고 부드러운 낙하와 꼬인 트랙의 느낌을 즐길 수 있습니다. STR_0564 :목재 트랙 위를 움직이는 이 롤러코스터는 빠르고, 거칠고, 시끄럽고, 많은 '무중력 시간'과 함께 '제어 불가능할 것 같은' 탑승감을 선사합니다. -STR_0565 :완만한 경사와 커브만을 가진 간단한 목재 롤러코스터로, 이 롤러코스터의 차량은 오직 측면 마찰륜과 중력만으로 트랙 위에 얹혀진 상태로 운행합니다. +STR_0565 :완만한 경사와 커브만을 가진 간단한 나무 롤러코스터로, 이 롤러코스터의 차량은 트랙 위에 얹힌 상태에서 오직 측면 마찰용 바퀴와 중력에 의해 운행됩니다. STR_0566 :개별적인 롤러코스터 차량이 급커브와 짧고 급한 경사를 가진 지그재그 모양의 트랙을 어지럽게 돌아다닙니다. STR_0567 :트랙 반대편에 매달린 좌석에 앉아서, 탑승객들은 급강하와 여러 가지 반전 트랙을 통과하면서 거꾸러지는 동안 머리와 다리가 뒤집히게 됩니다. STR_0569 :차량 밑에 달린 특별한 마차에 탑승하여, 탑승객들은 공중으로 급강하면서 하늘을 나는 기분을 느끼게 만듭니다. @@ -153,7 +153,7 @@ STR_0572 :대형 보트가 넓은 수로를 따라 컨베이어 벨트에 의 STR_0573 :탑승객이 직접 페달을 밟아 이동하는, 철제 트랙을 달리는 헬리콥터 모양의 전동 차량입니다. STR_0574 :탑승객은 특수한 마차에 누운 자세로 매달려, 이리 저리 꼬이고 뒤집히는 트랙을 땅을 등지거나 마주보는 자세로 탑승하게 됩니다. STR_0575 :공원 여기 저기로 사람들을 실어나르는, 단선 레일에 매달린 전동 열차입니다. -STR_0577 :특수한 반전 섹션에서 앞뒤가 바뀌는 목재 트랙을 달리는 보우기 차입니다 +STR_0577 :특수한 반전 섹션에서 앞뒤가 바뀌는 나무 트랙을 달리는 보우기 차입니다 STR_0578 :원형 고리로 둘러싸여 급강하와 하트라인 트위스트를 횡단하는 트랙을 달리는 차량입니다. STR_0579 : STR_0580 :90m 이상의 언덕을 부드럽게 오르내리는 거대한 철제 롤러코스터입니다. @@ -262,8 +262,8 @@ STR_0875 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP STR_0876 :{BLACK}▼ STR_0877 :너무 낮습니다! STR_0878 :너무 높습니다! -STR_0879 :여기를 더 이상 내릴 수 없습니다... -STR_0880 :여기를 더 이상 올릴 수 없습니다... +STR_0879 :여기를 더 내릴 수 없습니다... +STR_0880 :여기를 더 올릴 수 없습니다... STR_0881 :오브젝트가 있습니다 STR_0882 :게임 불러오기 STR_0883 :게임 저장하기 @@ -361,7 +361,7 @@ STR_0976 :화장실 및 안내소 STR_0977 :새로운 운송용 놀이기구 STR_0978 :새로운 얌전한 놀이기구 STR_0979 :새로운 롤러코스터 -STR_0980 :새로운 스릴있는 놀이기구 +STR_0980 :새로운 스릴 있는 놀이기구 STR_0981 :새로운 물 놀이기구 STR_0982 :새로운 상점·매점 STR_0983 :연구 & 개발 @@ -554,7 +554,7 @@ STR_1169 :(없음) STR_1170 :{STRING} STR_1171 :{RED}닫힘 - - STR_1172 :{YELLOW}{STRINGID} - - -STR_1173 :{SMALLFONT}{BLACK}보도와 대기줄을 만듭니다 +STR_1173 :{SMALLFONT}{BLACK}보도와 대기 줄을 만듭니다 STR_1174 :전광판 사인이 있습니다 STR_1175 :경사진 보도 위에 건설할 수 없습니다 STR_1176 :보도를 여기에 건설할 수 없습니다... @@ -607,7 +607,7 @@ STR_1222 :출구 없음 STR_1223 :{SMALLFONT}{BLACK}운송용 놀이기구 STR_1224 :{SMALLFONT}{BLACK}얌전한 놀이기구 STR_1225 :{SMALLFONT}{BLACK}롤러코스터 -STR_1226 :{SMALLFONT}{BLACK}스릴있는 놀이기구 +STR_1226 :{SMALLFONT}{BLACK}스릴 있는 놀이기구 STR_1227 :{SMALLFONT}{BLACK}물 놀이기구 STR_1228 :{SMALLFONT}{BLACK}상점 & 매점 STR_1229 :열차 @@ -745,7 +745,7 @@ STR_1360 :{WINDOW_COLOUR_2}대기 시간: {BLACK}{COMMA16}분 STR_1361 :속력을 바꿀 수 없습니다... STR_1362 :발진 속도를 바꿀 수 없습니다... STR_1363 :지지대가 버틸 수 있는 최대 높이입니다! -STR_1364 :위 트랙의 지지대를 더 이상 늘릴 수 없습니다! +STR_1364 :위 트랙의 지지대를 더 늘릴 수 없습니다! STR_1365 :인라인 트위스트 (왼쪽) STR_1366 :인라인 트위스트 (오른쪽) STR_1367 :1/2 루프 @@ -804,10 +804,10 @@ STR_1419 :{SMALLFONT}{BLACK}{VELOCITY} STR_1420 :{SMALLFONT}{BLACK}{LENGTH} STR_1421 :{SMALLFONT}{BLACK}{COMMA16}g STR_1422 :{SMALLFONT}{BLACK}{POP16}{STRINGID}을 기준으로 데이터 기록 중 -STR_1423 :{SMALLFONT}{BLACK}대기줄 +STR_1423 :{SMALLFONT}{BLACK}대기 줄 STR_1424 :{SMALLFONT}{BLACK}보도 STR_1425 :보도 -STR_1426 :대기줄 +STR_1426 :대기 줄 STR_1427 :{WINDOW_COLOUR_2}손님: {BLACK}{COMMA32}명/시간 STR_1428 :{WINDOW_COLOUR_2}입장료: STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} @@ -816,7 +816,7 @@ STR_1431 :걷는 중 STR_1432 :목적지 : {STRINGID} STR_1433 :{STRINGID} 대기 중 STR_1434 :물에 빠짐 -STR_1435 :{STRINGID} 탑승중 +STR_1435 :{STRINGID} 탑승 중 STR_1436 :{STRINGID} 안에 STR_1437 :{STRINGID}에 STR_1438 :앉음 @@ -865,7 +865,7 @@ STR_1480 :{SMALLFONT}“{STRINGID}에 쓸 돈은 없어” STR_1481 :{SMALLFONT}“내 돈을 전부 다 써버렸어” STR_1482 :{SMALLFONT}“속이 메스꺼워” STR_1483 :{SMALLFONT}“속이 정말 메스꺼워” -STR_1484 :{SMALLFONT}“{STRINGID}보다 더 스릴있는 걸 타고 싶어” +STR_1484 :{SMALLFONT}“{STRINGID}보다 더 스릴 있는 걸 타고 싶어” STR_1485 :{SMALLFONT}“{STRINGID}(은)는 내가 타기엔 너무 격렬해 보여” STR_1486 :{SMALLFONT}“아직 {STRINGID}(을)를 다 먹지 않았어” STR_1487 :{SMALLFONT}“{STRINGID}(은)는 바라만 봐도 속이 메스꺼워” @@ -879,7 +879,7 @@ STR_1494 :{SMALLFONT}“목마르지 않아” STR_1495 :{SMALLFONT}“살려주세요! 물에 빠졌어요!” STR_1496 :{SMALLFONT}“길을 잃어버렸어!” STR_1497 :{SMALLFONT}“{STRINGID}(은)는 정말 훌륭했어” -STR_1498 :{SMALLFONT}“{STRINGID}(을)를 타려고 한참동안이나 기다렸어” +STR_1498 :{SMALLFONT}“{STRINGID}(을)를 타려고 한참이나 기다렸어” STR_1499 :{SMALLFONT}“피곤해” STR_1500 :{SMALLFONT}“배고파” STR_1501 :{SMALLFONT}“목말라” @@ -906,7 +906,7 @@ STR_1521 :{SMALLFONT}“{STRINGID}에서 산 탑승 사진은 가격이 참 STR_1522 :{SMALLFONT}“{STRINGID}에서 산 우산은 가격이 참 적당한 것 같아” STR_1523 :{SMALLFONT}“{STRINGID}에서 산 음료수는 가격이 참 적당한 것 같아” STR_1524 :{SMALLFONT}“{STRINGID}에서 산 햄버거는 가격이 참 적당한 것 같아” -STR_1525 :{SMALLFONT}“{STRINGID}에서 산 감자칩은 가격이 참 적당한 것 같아” +STR_1525 :{SMALLFONT}“{STRINGID}에서 산 감자 칩은 가격이 참 적당한 것 같아” STR_1526 :{SMALLFONT}“{STRINGID}에서 산 아이스크림은 가격이 참 적당한 것 같아” STR_1527 :{SMALLFONT}“{STRINGID}에서 산 솜사탕은 가격이 참 적당한 것 같아” STR_1528 : @@ -923,7 +923,7 @@ STR_1538 :{SMALLFONT}“{STRINGID}에서 산 티셔츠는 가격이 참 적 STR_1539 :{SMALLFONT}“{STRINGID}에서 산 도넛은 가격이 참 적당한 것 같아” STR_1540 :{SMALLFONT}“{STRINGID}에서 산 커피는 가격이 참 적당한 것 같아” STR_1541 : -STR_1542 :{SMALLFONT}“{STRINGID}에서 산 프라이드 치킨은 가격이 참 적당한 것 같아” +STR_1542 :{SMALLFONT}“{STRINGID}에서 산 프라이드치킨은 가격이 참 적당한 것 같아” STR_1543 :{SMALLFONT}“{STRINGID}에서 산 레모네이드는 가격이 참 적당한 것 같아” STR_1544 : STR_1545 : @@ -940,7 +940,7 @@ STR_1555 :{SMALLFONT}“{STRINGID}의 탑승 사진에 돈을 쓰고 싶지 STR_1556 :{SMALLFONT}“{STRINGID}의 우산에 돈을 쓰고 싶지 않아” STR_1557 :{SMALLFONT}“{STRINGID}의 음료수에 돈을 쓰고 싶지 않아” STR_1558 :{SMALLFONT}“{STRINGID}의 햄버거에 돈을 쓰고 싶지 않아” -STR_1559 :{SMALLFONT}“{STRINGID}의 감자칩에 돈을 쓰고 싶지 않아” +STR_1559 :{SMALLFONT}“{STRINGID}의 감자 칩에 돈을 쓰고 싶지 않아” STR_1560 :{SMALLFONT}“{STRINGID}의 아이스크립에 돈을 쓰고 싶지 않아” STR_1561 :{SMALLFONT}“{STRINGID}의 솜사탕에 돈을 쓰고 싶지 않아” STR_1562 : @@ -957,7 +957,7 @@ STR_1572 :{SMALLFONT}“{STRINGID}의 티셔츠에 돈을 쓰고 싶지 않 STR_1573 :{SMALLFONT}“{STRINGID}의 도넛에 돈을 쓰고 싶지 않아” STR_1574 :{SMALLFONT}“{STRINGID}의 커피에 돈을 쓰고 싶지 않아” STR_1575 : -STR_1576 :{SMALLFONT}“{STRINGID}의 프라이드 치킨에 돈을 쓰고 싶지 않아” +STR_1576 :{SMALLFONT}“{STRINGID}의 프라이드치킨에 돈을 쓰고 싶지 않아” STR_1577 :{SMALLFONT}“{STRINGID}의 레모네이드에 돈을 쓰고 싶지 않아” STR_1578 : STR_1579 : @@ -969,14 +969,14 @@ STR_1584 :{SMALLFONT}“{STRINGID}에서 산 탑승 사진은 가격이 참 STR_1585 :{SMALLFONT}“{STRINGID}에서 산 탑승 사진은 가격이 참 적당한 것 같아” STR_1586 :{SMALLFONT}“{STRINGID}에서 산 탑승 사진은 가격이 참 적당한 것 같아” STR_1587 :{SMALLFONT}“{STRINGID}에서 산 프레첼은 가격이 참 적당한 것 같아” -STR_1588 :{SMALLFONT}“{STRINGID}에서 산 핫 초코는 가격이 참 적당한 것 같아” +STR_1588 :{SMALLFONT}“{STRINGID}에서 산 핫초코는 가격이 참 적당한 것 같아” STR_1589 :{SMALLFONT}“{STRINGID}에서 산 아이스 티는 가격이 참 적당한 것 같아” STR_1590 :{SMALLFONT}“{STRINGID}에서 산 퍼넬 케이크는 가격이 참 적당한 것 같아” STR_1591 :{SMALLFONT}“{STRINGID}에서 산 선글라스는 가격이 참 적당한 것 같아” -STR_1592 :{SMALLFONT}“{STRINGID}에서 산 고기국수는 가격이 참 적당한 것 같아” -STR_1593 :{SMALLFONT}“{STRINGID}에서 산 볶음쌀국수은 가격이 참 적당한 것 같아” +STR_1592 :{SMALLFONT}“{STRINGID}에서 산 고기 국수는 가격이 참 적당한 것 같아” +STR_1593 :{SMALLFONT}“{STRINGID}에서 산 볶음 쌀국수은 가격이 참 적당한 것 같아” STR_1594 :{SMALLFONT}“{STRINGID}에서 산 만둣국은 가격이 참 적당한 것 같아” -STR_1595 :{SMALLFONT}“{STRINGID}에서 산 미트볼 스프는 가격이 참 적당한 것 같아” +STR_1595 :{SMALLFONT}“{STRINGID}에서 산 미트볼 수프는 가격이 참 적당한 것 같아” STR_1596 :{SMALLFONT}“{STRINGID}에서 산 과일 주스는 가격이 참 적당한 것 같아” STR_1597 :{SMALLFONT}“{STRINGID}에서 산 두유는 가격이 참 적당한 것 같아” STR_1598 :{SMALLFONT}“{STRINGID}에서 산 수정과는 가격이 참 적당한 것 같아” @@ -1001,14 +1001,14 @@ STR_1616 :{SMALLFONT}“{STRINGID}의 탑승 사진에 돈을 쓰고 싶지 STR_1617 :{SMALLFONT}“{STRINGID}의 탑승 사진에 돈을 쓰고 싶지 않아” STR_1618 :{SMALLFONT}“{STRINGID}의 탑승 사진에 돈을 쓰고 싶지 않아” STR_1619 :{SMALLFONT}“{STRINGID}의 프레첼에 돈을 쓰고 싶지 않아” -STR_1620 :{SMALLFONT}“{STRINGID}의 핫 초코에 돈을 쓰고 싶지 않아” +STR_1620 :{SMALLFONT}“{STRINGID}의 핫초코에 돈을 쓰고 싶지 않아” STR_1621 :{SMALLFONT}“{STRINGID}의 아이스 티에 돈을 쓰고 싶지 않아” STR_1622 :{SMALLFONT}“{STRINGID}의 퍼넬 케이크에 돈을 쓰고 싶지 않아” STR_1623 :{SMALLFONT}“{STRINGID}의 선글라스에 돈을 쓰고 싶지 않아” STR_1624 :{SMALLFONT}“{STRINGID}의 고기 국수에 돈을 쓰고 싶지 않아” -STR_1625 :{SMALLFONT}“{STRINGID}의 볶음쌀국수에 돈을 쓰고 싶지 않아” +STR_1625 :{SMALLFONT}“{STRINGID}의 볶음 쌀국수에 돈을 쓰고 싶지 않아” STR_1626 :{SMALLFONT}“{STRINGID}의 만둣국에 돈을 쓰고 싶지 않아” -STR_1627 :{SMALLFONT}“{STRINGID}의 미트볼 스프에 돈을 쓰고 싶지 않아” +STR_1627 :{SMALLFONT}“{STRINGID}의 미트볼 수프에 돈을 쓰고 싶지 않아” STR_1628 :{SMALLFONT}“{STRINGID}의 과일 주스에 돈을 쓰고 싶지 않아” STR_1629 :{SMALLFONT}“{STRINGID}의 두유에 돈을 쓰고 싶지 않아” STR_1630 :{SMALLFONT}“{STRINGID}의 수정과에 돈을 쓰고 싶지 않아” @@ -1077,8 +1077,8 @@ STR_1693 :{SMALLFONT}{BLACK}손님 STR_1694 :{SMALLFONT}{BLACK}직원 STR_1695 :{SMALLFONT}{BLACK}수익 및 지출 STR_1696 :{SMALLFONT}{BLACK}고객 정보 -STR_1697 :대기줄에 놓을 수 없습니다 -STR_1698 :대기줄에만 놓을 수 있습니다 +STR_1697 :대기 줄에 놓을 수 없습니다 +STR_1698 :대기 줄에만 놓을 수 있습니다 STR_1699 :게임에 사람이 너무 많습니다 STR_1700 :새 미화원 고용 STR_1701 :새 정비기술자 고용 @@ -1105,10 +1105,10 @@ STR_1721 :공원 닫힘 STR_1722 :공원 열림 STR_1723 :공원을 열 수 없습니다... STR_1724 :공원을 닫을 수 없습니다... -STR_1725 :땅을 구입할 수 없습니다... +STR_1725 :땅을 살 수 없습니다... STR_1726 :판매 중인 땅이 아닙니다! STR_1727 :판매 중인 건설권이 아닙니다! -STR_1728 :이 곳의 건설권을 구입할 수 없습니다... +STR_1728 :이곳의 건설권을 살 수 없습니다... STR_1729 :공원 소유의 땅이 아닙니다! STR_1730 :{RED}닫힘 - - STR_1731 :{WHITE}{STRINGID} - - @@ -1153,7 +1153,7 @@ STR_1773 :한 놀이기구에는 하나의 탑승 사진 섹션만 만들 수 STR_1774 :한 놀이기구에는 하나의 케이블 리프트만 만들 수 있습니다 STR_1777 :놀이기구 음악 STR_1778 :{STRINGID} - - -STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} 팬더 복장 +STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} 판다 복장 STR_1780 :{INLINE_SPRITE}{255}{19}{00}{00} 호랑이 복장 STR_1781 :{INLINE_SPRITE}{00}{20}{00}{00} 코끼리 복장 STR_1782 :{INLINE_SPRITE}{01}{20}{00}{00} 로마 전사 복장 @@ -1208,9 +1208,9 @@ STR_1831 :대기 시간 STR_1832 :신뢰도 STR_1833 :고장률 STR_1834 :좋아하는 손님 수 -STR_1835 :인기도 : 알 수 없음 +STR_1835 :인기도: 알 수 없음 STR_1836 :인기도: {COMMA16}% -STR_1837 :만족도: 알 수 없움 +STR_1837 :만족도: 알 수 없음 STR_1838 :만족도: {COMMA16}% STR_1839 :신뢰도: {COMMA16}% STR_1840 :고장률: {COMMA16}% @@ -1290,7 +1290,7 @@ STR_1914 :{BLACK}{CURRENCY2DP} STR_1915 :{RED}{CURRENCY2DP} STR_1916 :{WINDOW_COLOUR_2}대출: STR_1917 :{POP16}{POP16}{POP16}{CURRENCY} -STR_1918 :더 이상 돈을 빌릴 수 없습니다! +STR_1918 :돈을 더 빌릴 수 없습니다! STR_1919 :돈이 충분하지 않습니다! STR_1920 :대출을 갚을 수 없습니다! STR_1921 :{SMALLFONT}{BLACK}새로운 게임을 시작합니다 @@ -1302,7 +1302,7 @@ STR_1927 :{YELLOW}{STRINGID} 고장 발생 STR_1928 :{RED}{STRINGID} 충돌! STR_1929 :{RED}{STRINGID} - 아직 수리되지 않음{NEWLINE}정비기술자의 위치와 업무 효율을 점검하세요 STR_1930 :{SMALLFONT}{BLACK}이 손님의 행동을 추적합니다.{NEWLINE}(이 설정을 켜면 이 손님의 모든 행동을 메시지 창으로 알려줍니다) -STR_1931 :{STRINGID} - {STRINGID}(을)를 타기 위해 대기줄에 섰습니다 +STR_1931 :{STRINGID} - {STRINGID}(을)를 타기 위해 대기 줄에 섰습니다 STR_1932 :{STRINGID} - {STRINGID}(을)를 탔습니다 STR_1933 :{STRINGID} - {STRINGID} 안에 있습니다 STR_1934 :{STRINGID} - {STRINGID}(을)를 떠났습니다 @@ -1338,7 +1338,7 @@ STR_1963 :{WINDOW_COLOUR_2}탑승 사진 가격: STR_1964 :{WINDOW_COLOUR_2}우산 가격: STR_1965 :{WINDOW_COLOUR_2}음료수 가격: STR_1966 :{WINDOW_COLOUR_2}햄버거 가격: -STR_1967 :{WINDOW_COLOUR_2}감자칩 가격: +STR_1967 :{WINDOW_COLOUR_2}감자 칩 가격: STR_1968 :{WINDOW_COLOUR_2}아이스크림 가격: STR_1969 :{WINDOW_COLOUR_2}솜사탕 가격: STR_1970 :{WINDOW_COLOUR_2} @@ -1366,7 +1366,7 @@ STR_1991 :탑승 사진 STR_1992 :우산 STR_1993 :음료수 STR_1994 :햄버거 -STR_1995 :감자칩 +STR_1995 :감자 칩 STR_1996 :아이스크림 STR_1997 :솜사탕 STR_1998 :빈 캔 @@ -1394,7 +1394,7 @@ STR_2019 :탑승 사진 STR_2020 :우산 STR_2021 :음료수 STR_2022 :햄버거 -STR_2023 :감자칩 +STR_2023 :감자 칩 STR_2024 :아이스크림 STR_2025 :솜사탕 STR_2026 :빈 캔 @@ -1422,7 +1422,7 @@ STR_2047 :탑승 사진 STR_2048 :우산 STR_2049 :음료수 STR_2050 :햄버거 -STR_2051 :감자칩 +STR_2051 :감자 칩 STR_2052 :아이스크림 STR_2053 :솜사탕 STR_2054 :빈 캔 @@ -1450,7 +1450,7 @@ STR_2075 :{STRINGID} 탑승 사진 STR_2076 :“{STRINGID}” 우산 STR_2077 :음료수 STR_2078 :햄버거 -STR_2079 :감자칩 +STR_2079 :감자 칩 STR_2080 :아이스크림 STR_2081 :솜사탕 STR_2082 :빈 캔 @@ -1477,9 +1477,9 @@ STR_2105 :{WINDOW_COLOUR_2}아이스 티 가격: STR_2106 :{WINDOW_COLOUR_2}퍼넬 케이크 가격: STR_2107 :{WINDOW_COLOUR_2}선글라스 가격: STR_2108 :{WINDOW_COLOUR_2}고기 국수 가격: -STR_2109 :{WINDOW_COLOUR_2}볶음쌀국수 가격: +STR_2109 :{WINDOW_COLOUR_2}볶음 쌀국수 가격: STR_2110 :{WINDOW_COLOUR_2}만둣국 가격: -STR_2111 :{WINDOW_COLOUR_2}미트볼 스프 가격: +STR_2111 :{WINDOW_COLOUR_2}미트볼 수프 가격: STR_2112 :{WINDOW_COLOUR_2}과일 주스 가격: STR_2113 :{WINDOW_COLOUR_2}두유 가격: STR_2114 :{WINDOW_COLOUR_2}수정과 가격: @@ -1496,16 +1496,16 @@ STR_2127 :아이스 티 STR_2128 :퍼넬 케이크 STR_2129 :선글라스 STR_2130 :고기 국수 -STR_2131 :볶음쌀국수 +STR_2131 :볶음 쌀국수 STR_2132 :만둣국 -STR_2133 :미트볼 스프 +STR_2133 :미트볼 수프 STR_2134 :과일 주스 STR_2135 :두유 STR_2136 :수정과 STR_2137 :샌드위치 STR_2138 :쿠키 STR_2139 :빈 사발 -STR_2140 :빈 음료수 통 +STR_2140 :빈 음료수 캔 STR_2141 :빈 주스 컵 STR_2142 :구운 소시지 STR_2143 :빈 사발 @@ -1515,9 +1515,9 @@ STR_2149 :아이스 티 STR_2150 :퍼넬 케이크 STR_2151 :선글라스 STR_2152 :고기 국수 -STR_2153 :볶음쌀국수 +STR_2153 :볶음 쌀국수 STR_2154 :만둣국 -STR_2155 :미트볼 스프 +STR_2155 :미트볼 수프 STR_2156 :과일 주스 STR_2157 :두유 STR_2158 :수정과 @@ -1534,9 +1534,9 @@ STR_2171 :아이스 티 STR_2172 :퍼넬 케이크 STR_2173 :선글라스 STR_2174 :고기 국수 -STR_2175 :볶음쌀국수 +STR_2175 :볶음 쌀국수 STR_2176 :만둣국 -STR_2177 :미트볼 스프 +STR_2177 :미트볼 수프 STR_2178 :과일 주스 STR_2179 :두유 STR_2180 :수정과 @@ -1553,9 +1553,9 @@ STR_2193 :아이스 티 STR_2194 :퍼넬 케이크 STR_2195 :선글라스 STR_2196 :고기 국수 -STR_2197 :볶음쌀국수 +STR_2197 :볶음 쌀국수 STR_2198 :만둣국 -STR_2199 :미트볼 스프 +STR_2199 :미트볼 수프 STR_2200 :과일 주스 STR_2201 :두유 STR_2202 :수정과 @@ -1612,7 +1612,7 @@ STR_2252 :보도를 가로질러야만 설치할 수 있습니다! STR_2253 :운송용 놀이기구 STR_2254 :얌전한 놀이기구 STR_2255 :롤러코스터 -STR_2256 :스릴있는 놀이기구 +STR_2256 :스릴 있는 놀이기구 STR_2257 :물 놀이기구 STR_2258 :상점 & 매점 STR_2259 :풍경 & 테마 @@ -1630,14 +1630,14 @@ STR_2270 :{WINDOW_COLOUR_2}진행: {BLACK}{STRINGID} STR_2271 :{WINDOW_COLOUR_2}예상: {BLACK}{STRINGID} STR_2272 :{WINDOW_COLOUR_2}놀이기구/시설:{NEWLINE}{BLACK}{STRINGID} STR_2273 :{WINDOW_COLOUR_2}풍경/테마:{NEWLINE}{BLACK}{STRINGID} -STR_2274 :{SMALLFONT}{BLACK}이 개발에 대한 상세 내역을 보여줍니다 +STR_2274 :{SMALLFONT}{BLACK}이 개발에 대한 상세 내용을 보여줍니다 STR_2275 :{SMALLFONT}{BLACK}연구 & 개발을 위한 투자 설정 창을 보여줍니다 STR_2276 :{SMALLFONT}{BLACK}연구 & 개발 상황을 보여줍니다 STR_2277 :알 수 없음 STR_2278 :운송용 놀이기구 STR_2279 :얌전한 놀이기구 STR_2280 :롤러코스터 -STR_2281 :스릴있는 놀이기구 +STR_2281 :스릴 있는 놀이기구 STR_2282 :물 놀이기구 STR_2283 :상점/매점 STR_2284 :풍경/테마 @@ -1739,7 +1739,7 @@ STR_2386 :{BLACK}공원에 최소 {COMMA16}명 이상의 손님을 {MONTHYEAR STR_2387 :{BLACK}최소 {POP16}{POP16}{CURRENCY} 이상의 공원 가치를 {PUSH16}{PUSH16}{PUSH16}{MONTHYEAR}까지 달성하세요 STR_2388 :{BLACK}즐기세요! STR_2389 :{BLACK}최고의 {STRINGID}(을)를 건설하세요! -STR_2390 :{BLACK}흥미도가 최소 6.00을 넘는 10개의 다른 종류의 롤러코스터를 공원에 운용하세요 +STR_2390 :{BLACK}흥미도가 최소 6.00을 넘는 10종의 다른 롤러코스터를 공원에 운용하세요 STR_2391 :{BLACK}공원에 최소 {COMMA16}명 이상의 손님을 유치하세요. 단 한 순간이라도 공원 등급을 700 아래로 떨어뜨려서는 안 됩니다! STR_2392 :{BLACK}놀이기구 탑승 수익만으로 월 수익을 최소 {POP16}{POP16}{CURRENCY} 이상 달성하세요 STR_2393 :{BLACK}최소 길이가 {LENGTH} 이상이고 흥미도가 최소 7.00을 넘는 10개의 다른 종류의 롤러코스터를 공원에 운용하세요 @@ -1812,7 +1812,7 @@ STR_2469 :{SMALLFONT}{BLACK}연구 & 개발 수준을 선택합니다 STR_2470 :{SMALLFONT}{BLACK}새 운송용 놀이기구를 개발합니다 STR_2471 :{SMALLFONT}{BLACK}새 얌전한 놀이기구를 개발합니다 STR_2472 :{SMALLFONT}{BLACK}새 롤러코스터를 개발합니다 -STR_2473 :{SMALLFONT}{BLACK}새 스릴있는 놀이기구를 개발합니다 +STR_2473 :{SMALLFONT}{BLACK}새 스릴 있는 놀이기구를 개발합니다 STR_2474 :{SMALLFONT}{BLACK}새 물 놀이기구를 개발합니다 STR_2475 :{SMALLFONT}{BLACK}새 상점/매점을 개발합니다 STR_2476 :{SMALLFONT}{BLACK}새 풍경/테마를 개발합니다 @@ -2142,40 +2142,40 @@ STR_2810 :{RED}손님들이 목이 마르지만 음료수를 살 곳을 찾 STR_2811 :{RED}손님들이 공원에서 화장실을 찾을 수 없다고 불평하고 있습니다 STR_2812 :{RED}손님들이 길을 잃었거나 갇혔습니다{NEWLINE}보도의 구조를 손님들이 길을 더 쉽게 찾을 수 있도록 개선하세요 STR_2813 :{RED}공원 입장료가 너무 비쌉니다!{NEWLINE}손님을 더 유치하려면 공원 입장료를 내리거나 공원 가치를 올리세요 -STR_2814 :{WINDOW_COLOUR_2}가장 지저분한 공원 상 -STR_2815 :{WINDOW_COLOUR_2}가장 깔끔한 공원 상 -STR_2816 :{WINDOW_COLOUR_2}최고의 롤러코스터가 있는 공원 상 -STR_2817 :{WINDOW_COLOUR_2}최고의 공원 이용료 상 -STR_2818 :{WINDOW_COLOUR_2}가장 아름다운 공원 상 -STR_2819 :{WINDOW_COLOUR_2}최악의 공원 이용료 상 -STR_2820 :{WINDOW_COLOUR_2}가장 안전한 공원 상 -STR_2821 :{WINDOW_COLOUR_2}최고의 직원 상 -STR_2822 :{WINDOW_COLOUR_2}최고의 공원 음식 상 -STR_2823 :{WINDOW_COLOUR_2}최악의 공원 음식 상 -STR_2824 :{WINDOW_COLOUR_2}최고의 공원 화장실 상 -STR_2825 :{WINDOW_COLOUR_2}가장 실망스러운 공원 상 -STR_2826 :{WINDOW_COLOUR_2}최고의 물 놀이기구 상 -STR_2827 :{WINDOW_COLOUR_2}최고의 커스텀 디자인 놀이기구 상 -STR_2828 :{WINDOW_COLOUR_2}최고의 눈부신 놀이기구 색상 조합 상 -STR_2829 :{WINDOW_COLOUR_2}가장 복잡한 공원 구조 상 -STR_2830 :{WINDOW_COLOUR_2}최고의 얌전한 놀이기구 상 -STR_2831 :{TOPAZ}공원이 '우리나라에서 가장 지저분한 공원 상'을 받았습니다... -STR_2832 :{TOPAZ}공원이 '우리나라에서 가장 깔끔한 공원 상'을 받았습니다! -STR_2833 :{TOPAZ}공원이 '우리나라 최고의 롤러코스터가 있는 공원 상'을 받았습니다! -STR_2834 :{TOPAZ}공원이 '우리나라 최고의 공원 이용료 상'을 받았습니다! -STR_2835 :{TOPAZ}공원이 '우리나라에서 가장 아름다운 공원 상'을 받았습니다! -STR_2836 :{TOPAZ}공원이 '우리나라 최악의 공원 이용료 상'을 받았습니다... -STR_2837 :{TOPAZ}공원이 '우리나라에서 가장 안전한 공원 상'을 받았습니다! -STR_2838 :{TOPAZ}공원이 '우리나라 최고의 직원 상'을 받았습니다! -STR_2839 :{TOPAZ}공원이 '우리나라 최고의 공원 음식 상'을 받았습니다! -STR_2840 :{TOPAZ}공원이 '우리나라 최악의 공원 음식 상'을 받았습니다... -STR_2841 :{TOPAZ}공원이 '우리나라 최고의 공원 화장실 상'을 받았습니다! -STR_2842 :{TOPAZ}공원이 '우리나라에서 가장 실망스러운 공원 상'을 받았습니다... -STR_2843 :{TOPAZ}공원이 '우리나라 최고의 물 놀이기구 상'을 받았습니다! -STR_2844 :{TOPAZ}공원이 '우리나라 최고의 커스텀 디자인 놀이기구 상'을 받았습니다! -STR_2845 :{TOPAZ}공원이 '우리나라 최고의 눈부신 놀이기구 색상 조합 상'을 받았습니다! -STR_2846 :{TOPAZ}공원이 '우리나라에서 가장 복잡한 공원 구조 상'을 받았습니다... -STR_2847 :{TOPAZ}공원이 '우리나라 최고의 얌전한 놀이기구 상'을 받았습니다! +STR_2814 :{WINDOW_COLOUR_2}가장 지저분한 공원상 +STR_2815 :{WINDOW_COLOUR_2}가장 깔끔한 공원상 +STR_2816 :{WINDOW_COLOUR_2}최고의 롤러코스터가 있는 공원상 +STR_2817 :{WINDOW_COLOUR_2}최고의 공원 이용료상 +STR_2818 :{WINDOW_COLOUR_2}가장 아름다운 공원상 +STR_2819 :{WINDOW_COLOUR_2}최악의 공원 이용료상 +STR_2820 :{WINDOW_COLOUR_2}가장 안전한 공원상 +STR_2821 :{WINDOW_COLOUR_2}최고의 직원상 +STR_2822 :{WINDOW_COLOUR_2}최고의 공원 음식상 +STR_2823 :{WINDOW_COLOUR_2}최악의 공원 음식상 +STR_2824 :{WINDOW_COLOUR_2}최고의 공원 화장실상 +STR_2825 :{WINDOW_COLOUR_2}가장 실망스러운 공원상 +STR_2826 :{WINDOW_COLOUR_2}최고의 물 놀이기구상 +STR_2827 :{WINDOW_COLOUR_2}최고의 커스텀 디자인 놀이기구상 +STR_2828 :{WINDOW_COLOUR_2}최고의 눈부신 놀이기구 색상 조합상 +STR_2829 :{WINDOW_COLOUR_2}가장 복잡한 공원 구조상 +STR_2830 :{WINDOW_COLOUR_2}최고의 얌전한 놀이기구상 +STR_2831 :{TOPAZ}공원이 '우리나라에서 가장 지저분한 공원상'을 받았습니다... +STR_2832 :{TOPAZ}공원이 '우리나라에서 가장 깔끔한 공원상'을 받았습니다! +STR_2833 :{TOPAZ}공원이 '우리나라 최고의 롤러코스터가 있는 공원상'을 받았습니다! +STR_2834 :{TOPAZ}공원이 '우리나라 최고의 공원 이용료상'을 받았습니다! +STR_2835 :{TOPAZ}공원이 '우리나라에서 가장 아름다운 공원상'을 받았습니다! +STR_2836 :{TOPAZ}공원이 '우리나라 최악의 공원 이용료상'을 받았습니다... +STR_2837 :{TOPAZ}공원이 '우리나라에서 가장 안전한 공원상'을 받았습니다! +STR_2838 :{TOPAZ}공원이 '우리나라 최고의 직원상'을 받았습니다! +STR_2839 :{TOPAZ}공원이 '우리나라 최고의 공원 음식상'을 받았습니다! +STR_2840 :{TOPAZ}공원이 '우리나라 최악의 공원 음식상'을 받았습니다... +STR_2841 :{TOPAZ}공원이 '우리나라 최고의 공원 화장실상'을 받았습니다! +STR_2842 :{TOPAZ}공원이 '우리나라에서 가장 실망스러운 공원상'을 받았습니다... +STR_2843 :{TOPAZ}공원이 '우리나라 최고의 물 놀이기구상'을 받았습니다! +STR_2844 :{TOPAZ}공원이 '우리나라 최고의 커스텀 디자인 놀이기구상'을 받았습니다! +STR_2845 :{TOPAZ}공원이 '우리나라 최고의 눈부신 놀이기구 색상 조합상'을 받았습니다! +STR_2846 :{TOPAZ}공원이 '우리나라에서 가장 복잡한 공원 구조상'을 받았습니다... +STR_2847 :{TOPAZ}공원이 '우리나라 최고의 얌전한 놀이기구상'을 받았습니다! STR_2848 :{WINDOW_COLOUR_2}최근에 받은 상 없음 STR_2849 :새 시나리오 설치가 성공적으로 완료되었습니다 STR_2850 :새 트랙 디자인 설치가 성공적으로 완료되었습니다 @@ -2192,12 +2192,12 @@ STR_2864 :{WINDOW_COLOUR_2}March - Children of the Regiment: (푸치크) STR_2865 :{WINDOW_COLOUR_2}Heyken's Serenade: (J.Heyken) British Standard Music Coy; GEMA, BRITICO STR_2866 :{WINDOW_COLOUR_2}La Belle Espagnole: (Robert Vollstedt) 저작권 없음 STR_2867 :{WINDOW_COLOUR_2}Wedding Journey: (민요) -STR_2868 :{WINDOW_COLOUR_2}Tales from the Vienna Woods: (요한 스트라우스) 저작권 없음 +STR_2868 :{WINDOW_COLOUR_2}Tales from the Vienna Woods: (요한 슈트라우스) 저작권 없음 STR_2869 :{WINDOW_COLOUR_2}Slavonic Dance: (민요) STR_2870 :{WINDOW_COLOUR_2}Das Alpenhorn: (민요) STR_2871 :{WINDOW_COLOUR_2}The Blond Sailor: (민요) STR_2872 :{WINDOW_COLOUR_2}Overture - Poet and Peasant: (주페) 저작권 없음 -STR_2873 :{WINDOW_COLOUR_2}Waltz Medley: (요한 스트라우스) 저작권 없음 +STR_2873 :{WINDOW_COLOUR_2}Waltz Medley: (요한 슈트라우스) 저작권 없음 STR_2874 :{WINDOW_COLOUR_2}Bella Bella Bimba: (민요) STR_2875 :{WINDOW_COLOUR_2}Original recordings (P) 1976 C.J.Mears Organization, used with consent STR_2876 :{WINDOW_COLOUR_2}RollerCoaster Tycoon 2 타이틀 음악: (Allister Brimble) copyright © Chris Sawyer @@ -2393,7 +2393,7 @@ STR_3159 :목록 STR_3160 :{SMALLFONT}{BLACK}한 운행마다 트랙을 몇 번 돌지를 선택합니다. STR_3162 :충분한 메모리를 할당할 수 없습니다 STR_3163 :새 데이터 설치중: -STR_3164 :{BLACK}{COMMA16}개 선택 됨 (최대 {COMMA16}개) +STR_3164 :{BLACK}{COMMA16}개 선택됨 (최대 {COMMA16}개) STR_3167 :{WINDOW_COLOUR_2}{BLACK}{COMMA16}개의 오브젝트 포함 STR_3169 :다음 오브젝트에 대한 데이터를 찾을 수 없습니다: STR_3170 :그래픽을 저장할 공간이 충분하지 않습니다 @@ -2438,8 +2438,8 @@ STR_3209 :이전 단계로: STR_3210 :다음 단계로: STR_3211 :지도 크기: STR_3212 :{POP16}{COMMA16} x {PUSH16}{COMMA16} -STR_3213 :더 이상 맵 크기를 줄일 수 없습니다 -STR_3214 :더 이상 맵 크기를 늘릴 수 없습니다 +STR_3213 :맵 크기를 더 줄일 수 없습니다 +STR_3214 :맵 크기를 더 늘릴 수 없습니다 STR_3215 :지도 가장자리와 너무 가깝습니다 STR_3216 :{SMALLFONT}{BLACK}공원 소유지 등을 선택합니다 STR_3217 :소유한 땅 @@ -2448,8 +2448,8 @@ STR_3219 :판매 중인 땅 STR_3220 :판매 중인 건설권 STR_3221 :{SMALLFONT}{BLACK}공원이 이미 소유하고 있는 땅을 선택합니다 STR_3222 :{SMALLFONT}{BLACK}공원이 이미 소유하고 있는 건설권을 선택합니다 -STR_3223 :{SMALLFONT}{BLACK}공원이 향후 구입할 수 있는 땅을 선택합니다 -STR_3224 :{SMALLFONT}{BLACK}공원이 향후 구입할 수 있는 건설권을 선택합니다 +STR_3223 :{SMALLFONT}{BLACK}공원이 추가로 살 수 있는 땅을 선택합니다 +STR_3224 :{SMALLFONT}{BLACK}공원이 추가로 살 수 있는 건설권을 선택합니다 STR_3225 :{SMALLFONT}{BLACK}선택한 위치 주변에 오브젝트를 임의로 무리지어 설치하는 모드를 켜거나 끕니다 STR_3226 :{SMALLFONT}{BLACK}공원 입구 건설 STR_3227 :공원 입구가 너무 많습니다! @@ -2473,14 +2473,14 @@ STR_3244 :광고 이벤트를 금지 STR_3245 :{SMALLFONT}{BLACK}광고나 이벤트를 진행할 수 없도록 금지합니다 STR_3246 :{WINDOW_COLOUR_2}{CURRENCY} STR_3247 :{WINDOW_COLOUR_2}{COMMA16}% -STR_3248 :초기 보유 자금을 더 이상 늘릴 수 없습니다! -STR_3249 :초기 보유 자금을 더 이상 줄일 수 없습니다! -STR_3250 :초기 대출금을 더 이상 늘릴 수 없습니다! -STR_3251 :초기 대출금을 더 이상 줄일 수 없습니다! -STR_3252 :최대 대출금을 더 이상 늘릴 수 없습니다! -STR_3253 :최대 대출금을 더 이상 줄일 수 없습니다! -STR_3254 :이자율을 더 이상 늘릴 수 없습니다! -STR_3255 :이자율을 더 이상 줄일 수 없습니다! +STR_3248 :초기 보유 자금을 더 늘릴 수 없습니다! +STR_3249 :초기 보유 자금을 더 줄일 수 없습니다! +STR_3250 :초기 대출금을 더 늘릴 수 없습니다! +STR_3251 :초기 대출금을 더 줄일 수 없습니다! +STR_3252 :최대 대출금을 더 늘릴 수 없습니다! +STR_3253 :최대 대출금을 더 줄일 수 없습니다! +STR_3254 :이자율을 더 늘릴 수 없습니다! +STR_3255 :이자율을 더 줄일 수 없습니다! STR_3256 :손님들이 격렬하지 않은 놀이기구를 선호함 STR_3257 :{SMALLFONT}{BLACK}손님들이 일반적으로 덜 격렬한 놀이기구를 선호하게 만들지를 선택합니다 STR_3258 :손님들이 격렬한 놀이기구를 선호함 @@ -2489,8 +2489,8 @@ STR_3260 :{WINDOW_COLOUR_2}각 손님의 보유금 (평균): STR_3261 :{WINDOW_COLOUR_2}손님의 초기 행복도: STR_3262 :{WINDOW_COLOUR_2}손님의 초기 배고픔: STR_3263 :{WINDOW_COLOUR_2}손님의 초기 목마름: -STR_3264 :더 이상 늘릴 수 없습니다! -STR_3265 :더 이상 줄일 수 없습니다! +STR_3264 :더 늘릴 수 없습니다! +STR_3265 :더 줄일 수 없습니다! STR_3266 :{SMALLFONT}{BLACK}공원 수익을 입장료로 낼지 놀이기구 탑승료로 낼지를 선택하세요 STR_3267 :나무 제거 금지 STR_3268 :{SMALLFONT}{BLACK}키 큰 나무의 제거를 금지합니다 @@ -2607,7 +2607,7 @@ STR_3384 :같은 이름의 트랙 디자인이 이미 존재합니다 이 디 STR_3389 :추가 조형물 항목을 선택할 수 없습니다... STR_3390 :항목을 너무 많이 선택하였습니다 STR_3437 :{SMALLFONT}{BLACK}조형물을 한꺼번에 제거 -STR_3438 :여기에 있는 모든 조형물을 다 제거하지 못 하였습니다... +STR_3438 :여기에 있는 모든 조형물을 다 제거하지 못했습니다... STR_3439 :조형물 제거 STR_3440 :1쪽 STR_3441 :2쪽 @@ -2668,7 +2668,7 @@ STR_5168 :{SMALLFONT}{BLACK}채널의 트위치 팔로워 이름을 딴 손 STR_5169 :손님 이름을 트위치 채팅 접속자 이름을 따서 붙이기 STR_5170 :{SMALLFONT}{BLACK}트위치 채팅의 접속자 이름을 따서 손님 이름으로 사용합니다 STR_5171 :채팅 인원 추적 -STR_5172 :{SMALLFONT}{BLACK}트위치 채팅에 참가하고 있는 사람들의 이름을 딴 손님의 행적을 추적합니다 +STR_5172 :{SMALLFONT}{BLACK}트위치 채팅에 참여하고 있는 사람들의 이름을 딴 손님의 행적을 추적합니다 STR_5173 :트위치 채팅 내용을 뉴스로 전송 STR_5174 :{SMALLFONT}{BLACK}트위치의 채팅 메시지를 !news를 이용하여 게임 메시지로 알려줍니다 STR_5175 :트위치 채널 이름 입력 @@ -2866,7 +2866,7 @@ STR_5368 :충돌 이력 제거 STR_5369 :공원 설정... STR_5370 :{SMALLFONT}{BLACK}제한, 손님 생성, 재정 등의 공원과 관련된 설정을 수정하려면 이 버튼을 클릭하세요. STR_5371 :오브젝트 선택 -STR_5372 :마우스 오른쪽 드래그시 좌우 반전 +STR_5372 :마우스 오른쪽 드래그 시 좌우 반전 STR_5373 :이름 {STRINGID} STR_5374 :날짜 {STRINGID} STR_5375 :▲ @@ -2892,11 +2892,11 @@ STR_5394 :{SMALLFONT}{BLACK}선택한 게임 저장 파일 이름을 바꿉 STR_5395 :{SMALLFONT}{BLACK}선택한 게임 저장 파일을 게임에서 불러옵니다 STR_5396 :{SMALLFONT}{BLACK}게임 바깥에서 뭔가 변화가 생기면 타이틀 시퀀스를 다시 불러옵니다 STR_5397 :타이틀 화면에서만 사용할 수 있습니다 -STR_5398 :타이틀 시퀀스가 재생 중일 때에는 수정할 수 없습니다 +STR_5398 :타이틀 시퀀스가 재생 중일 때는 수정할 수 없습니다 STR_5399 :계속 수정하려면 중지 버튼을 누르세요 STR_5400 :타이틀 시퀀스를 변경할 수 없습니다 STR_5401 :다음으로 바꾸기 위해 타이틀 시퀀스를 생성합니다: -STR_5402 :타이틀 시퀀스를 불러오는데 실패하였습니다 +STR_5402 :타이틀 시퀀스를 불러오는 데 실패하였습니다 STR_5403 :불러오기나 기다리기 명령이 없거나 유효하지 않은 게임 저장 파일이 포함되었을 수 있습니다 STR_5404 :이미 존재하는 이름입니다 STR_5405 :세이브 파일의 이름을 입력하세요 @@ -3000,8 +3000,8 @@ STR_5503 :호스트네임이나 IP 주소를 입력하세요: STR_5504 :{SMALLFONT}{BLACK}접속자 목록 창을 엽니다 STR_5505 :서버에 접속할 수 없습니다 STR_5506 :손님이 격렬도를 무시하고 탐 -STR_5508 :올바르지 않은 검사합을 가진 파일 불러오기 허용 -STR_5509 :{SMALLFONT}{BLACK}데모에서 저장한 시나리오나 손상된 저장 파일과 같이 올바르지 않은 검사합을 가진 시나리오나 저장 파일을 불러오는 것을 허용합니다. +STR_5508 :올바르지 않은 검사 합을 가진 파일 불러오기 허용 +STR_5509 :{SMALLFONT}{BLACK}데모에서 저장한 시나리오나 손상된 저장 파일과 같이 올바르지 않은 검사 합을 가진 시나리오나 저장 파일을 불러오는 것을 허용합니다. STR_5510 :기본 사운드 장치 STR_5511 :(알 수 없음) STR_5512 :다른 이름으로 저장 @@ -3023,8 +3023,8 @@ STR_5527 :{SMALLFONT}{BLACK}짙은 녹색 STR_5528 :{SMALLFONT}{BLACK}어두운 녹색 STR_5529 :{SMALLFONT}{BLACK}모스 그린 STR_5530 :{SMALLFONT}{BLACK}밝은 녹색 -STR_5531 :{SMALLFONT}{BLACK}올리브 그린 -STR_5532 :{SMALLFONT}{BLACK}어두운 올리브 그린 +STR_5531 :{SMALLFONT}{BLACK}올리브그린 +STR_5532 :{SMALLFONT}{BLACK}어두운 올리브그린 STR_5533 :{SMALLFONT}{BLACK}밝은 노란색 STR_5534 :{SMALLFONT}{BLACK}노란색 STR_5535 :{SMALLFONT}{BLACK}어두운 노란색 @@ -3065,7 +3065,7 @@ STR_5569 :이 서버에 접속하려면 암호가 필요합니다 STR_5570 :서버 검색 STR_5571 :게임 참여 STR_5572 :즐겨찾기 등록 -STR_5573 :즐거찾기 제거 +STR_5573 :즐겨찾기 제거 STR_5574 :서버 이름: STR_5575 :최대 플레이어 수: STR_5576 :포트: @@ -3074,7 +3074,7 @@ STR_5578 :러시아 루블 (₽) STR_5579 :창 크기 조절 배수: STR_5580 :체코 코루나 (Kč) STR_5581 :FPS 보기 -STR_5582 :마우스 커서를 창 밖으로 나가지 못하게 +STR_5582 :마우스 커서를 창밖으로 나가지 못하게 STR_5583 :{COMMA1DP16}m/s STR_5584 :국제단위(SI)법 STR_5585 :{SMALLFONT}{BLACK}체인/발사 속력을 {VELOCITY}으로 만드는 등, 일부 놀이기구 운행 제한을 없애줍니다 @@ -3082,7 +3082,7 @@ STR_5586 :상점이나 가게를 자동으로 엶 STR_5587 :{SMALLFONT}{BLACK}상점이나 가게를 건설한 뒤에 자동으로 엽니다. STR_5588 :{SMALLFONT}{BLACK}다른 참가자와 함께 플레이합니다. STR_5589 :알림 설정 -STR_5590 :공원 수상 내역 +STR_5590 :공원 수상 기록 STR_5591 :광고 종료 STR_5592 :공원에 대한 경고 STR_5593 :공원 등급 경고 @@ -3093,7 +3093,7 @@ STR_5597 :놀이기구 / 풍경 연구 완료 STR_5598 :손님에 대한 경고 STR_5599 :손님의 길 잃음 STR_5600 :손님의 공원 퇴장 -STR_5601 :손님의 놀이기구 대기줄 진입 +STR_5601 :손님의 놀이기구 대기 줄 진입 STR_5602 :손님의 놀이기구 탑승 STR_5603 :손님의 놀이기구 하차 STR_5604 :손님의 물건 구입 @@ -3122,7 +3122,7 @@ STR_5626 :기타 공원 STR_5627 :시나리오 목록 분류 방식: STR_5628 :게임별 STR_5629 :난이도별 -STR_5630 :시나리오 클리어시 새 시나리오 열기 켜기 +STR_5630 :시나리오 클리어 시 새 시나리오 열기 켜기 STR_5631 :오리지널 다운로드 콘텐츠 공원 STR_5632 :직접 만들기... STR_5633 :CMD + @@ -3170,7 +3170,7 @@ STR_5708 :서버가 속한 그룹을 변경할 수 없습니다 STR_5709 :그룹 이름 변경 STR_5710 :그룹 이름 STR_5711 :이 그룹의 이름을 입력하세요: -STR_5712 :본인에게 없는 권한은 수정할 수 업습니다 +STR_5712 :본인에게 없는 권한은 수정할 수 없습니다 STR_5713 :플레이어 추방 STR_5714 :설정 창 보기 STR_5715 :새로운 게임 @@ -3314,14 +3314,14 @@ STR_5854 :{SMALLFONT}{BLACK}놀이기구 음악 켜기/끄기 STR_5855 :{SMALLFONT}{BLACK}전체화면, 창 모드, 전체화면 (창모드) 중에서 선택합니다. STR_5856 :{SMALLFONT}{BLACK}전체화면에서 사용할 게임 해상도를 설정합니다. STR_5857 :{SMALLFONT}{BLACK}게임 설정 -STR_5858 :{SMALLFONT}{BLACK}CPU 대신 GPU를 이용하여 화면을 표시합니다. 스크린 캡쳐 소프트웨어의 호환성을 향상시켜줍니다. 약간의 속도 저하가 발생할 수 있습니다. +STR_5858 :{SMALLFONT}{BLACK}CPU 대신 GPU를 이용하여 화면을 표시합니다. 스크린 캡처 소프트웨어의 호환성을 향상해줍니다. 약간의 속도 저하가 발생할 수 있습니다. STR_5859 :{SMALLFONT}{BLACK}시각적으로 더 부드러운 게임 플레이를 위해 프레임 제한을 해제합니다. 설정을 끄면 게임이 40 FPS로 실행됩니다. STR_5860 :오리지널 트랙 표시 방식 전환 STR_5861 :키 인증 실패 STR_5862 :알 수 없는 플레이어를 차단합니다. STR_5863 :{SMALLFONT}{BLACK}알려진 키를 가진 플레이어만 입장을 허용합니다. STR_5864 :이 서버는 알려진 키를 가진 플레이어의 입장만을 허용합니다. -STR_5865 :대화 내역 기록하기 +STR_5865 :대화 내용 기록하기 STR_5866 :{SMALLFONT}{BLACK}모든 대화 기록을 사용자 문서 폴더에 파일로 기록합니다. STR_5867 :{WINDOW_COLOUR_2}서버 운영자: {BLACK}{STRING} STR_5868 :{WINDOW_COLOUR_2}서버 전자우편: {BLACK}{STRING} @@ -3332,7 +3332,7 @@ STR_5872 :{SMALLFONT}{BLACK}꽃이 시들지 않게 만듭니다. STR_5873 :모든 트랙에 체인 걸기 허용 STR_5874 :{SMALLFONT}{BLACK}모든 트랙 조각에 체인 리프트를 걸 수 있도록 허용합니다. STR_5875 :드로잉 엔진: -STR_5876 :{SMALLFONT}{BLACK}게임 요소를 표시는데 사용할 엔진을 선택합니다. +STR_5876 :{SMALLFONT}{BLACK}게임 요소를 표시하는 데 사용할 엔진을 선택합니다. STR_5877 :소프트웨어 STR_5878 :소프트웨어 (하드웨어 디스플레이) STR_5879 :OpenGL (개발중) @@ -3443,9 +3443,9 @@ STR_5984 :막힌 보도: STR_5985 :새 폴더 STR_5986 :새 폴더의 이름을 입력하세요. STR_5987 :폴더를 만들 수 없습니다. -STR_5988 :{SMALLFONT}{BLACK}판매 중인 땅이 더 이상 없습니다. -STR_5989 :{SMALLFONT}{BLACK}판매 중인 건설권이 더 이상 없습니다. -STR_5990 :{SMALLFONT}{BLACK}판매 중인 땅이나 건설권이 더 이상 없습니다. +STR_5988 :{SMALLFONT}{BLACK}판매 중인 땅이 없습니다. +STR_5989 :{SMALLFONT}{BLACK}판매 중인 건설권이 없습니다. +STR_5990 :{SMALLFONT}{BLACK}판매 중인 땅이나 건설권이 없습니다. STR_5991 :붙여넣을 수 없습니다... STR_5992 :맵 요소 제한 개수를 초과했습니다 STR_5993 :{SMALLFONT}{BLACK}선택한 요소를 복사합니다. @@ -3543,7 +3543,7 @@ STR_6084 :{STRING}, '{STRING}' 놀이기구의 차량 설정을 변경함. STR_6085 :{STRING}, '{STRING}' 놀이기구의 설정을 변경함. STR_6086 :{STRING}, '{STRING}' 놀이기구의 이름을 '{STRING}'(으)로 변경. STR_6087 :{STRING}, '{STRING}' 놀이기구의 가격을 {STRING}(으)로 변경 -STR_6088 :{STRING}, '{STRING}' 놀이기구의 부가격을 {STRING}(으)로 변경 +STR_6088 :{STRING}, '{STRING}' 놀이기구의 두 번째 가격을 {STRING}(으)로 변경 STR_6089 :{STRING}, 공원 이름을 '{STRING}'에서 '{STRING}'(으)로 변경 STR_6090 :{STRING}, 공원 문을 엶 STR_6091 :{STRING}, 공원 문을 닫음 @@ -3574,9 +3574,9 @@ STR_6115 :급경사를 오를 수 있는 거대한 4 x 4 트럭 차량입니 STR_6116 :여러 가지 반전 트랙을 통과하면서 부드러운 강철 트랙을 따라서 활강하는, 폭이 넓은 롤러코스터입니다. STR_6117 :탑승객들은 한 바퀴를 운행하는 편안한 좌석에 앉아 언덕을 오르면서 느낄 수 있는 '무중력 시간'뿐만이 아니라 크고 부드러운 낙하와 꼬인 트랙의 느낌을 즐길 수 있습니다. STR_6118 :큰 놀이기구를 탈 용기가 없는 사람들을 위한 얌전한 롤러코스터입니다. -STR_6119 :높이 제한이 있지만 값 싸고 건설하기 쉬운 롤러코스터입니다. +STR_6119 :높이 제한이 있지만, 값싸고 건설하기 쉬운 롤러코스터입니다. STR_6120 :{BABYBLUE}{STRINGID}에 새로운 차량이 추가되었습니다:{NEWLINE}{STRINGID} -STR_6121 :{SMALLFONT}{BLACK}공원이 소유한 땅을 맵 끝까지 모든 방향으로 확장시켜줍니다. +STR_6121 :{SMALLFONT}{BLACK}공원이 소유한 땅을 맵 끝까지 모든 방향으로 확장해줍니다. STR_6122 :이 시나리오에 롤러코스터가 충분히 많이 있지 않습니다! STR_6123 :공원에 사용된 오브젝트 불러오기 오류 STR_6124 :오브젝트 이름 @@ -3602,11 +3602,11 @@ STR_6143 :{WINDOW_COLOUR_2}놀이기구 종류: {BLACK}{STRINGID} STR_6144 :시각적 업데이트 표시 STR_6145 :{SMALLFONT}{BLACK}부스터 속도 제한 설정 STR_6146 :모든 표시 가능한 트랙 조각 사용 -STR_6147 :{SMALLFONT}{BLACK}놀이기구 건설 창에서 해당 놀이기구가 지원하는 지의 여부와 관계 없이, 그 놀이기구에서 사용할 수 있는 모든 트랙 조각의 사용을 허용합니다. +STR_6147 :{SMALLFONT}{BLACK}놀이기구 건설 창에서 해당 놀이기구가 지원하는지의 여부와 관계없이, 그 놀이기구에서 사용할 수 있는 모든 트랙 조각의 사용을 허용합니다. STR_6148 :마스터 서버에 접속 중... STR_6149 :마스터 서버에 접속할 수 없습니다 STR_6150 :마스터 서버에서 잘못된 응답이 왔습니다 (JSON 숫자 데이터 없음) -STR_6151 :마스터 서버가 서버 목록을 보내주지 못 했습니다 +STR_6151 :마스터 서버가 서버 목록을 보내주지 못했습니다 STR_6152 :마스터 서버에서 잘못된 응답이 왔습니다 (JSON 배열 데이터 없음) STR_6153 :모두 받기 STR_6154 :보안상의 이유로, 높은 권한으로 OpenRCT2를 실행하는 것을 추천하지 않습니다 @@ -3645,7 +3645,7 @@ STR_6186 :선택된 스프라이트 없음 STR_6187 :{MEDIUMFONT}{OUTLINE}{WINDOW_COLOUR_2}{STRING} STR_6188 :구토 STR_6189 :오리 -STR_6190 :{SMALLFONT}{BLACK}메인 타이틀 시퀀스가 활성화되어 있을 때에는 스프라이트를 선택할 수 없습니다. +STR_6190 :{SMALLFONT}{BLACK}메인 타이틀 시퀀스가 활성화되어 있을 때는 스프라이트를 선택할 수 없습니다. STR_6191 :지면 STR_6192 :벽 STR_6193 :손님 {COMMA16}명 @@ -3809,12 +3809,12 @@ STR_DTLS :몇 개의 놀이기구와 확장할 공간이 있는 작은 놀이 STR_SCNR :Pokey Park STR_PARK :비좁은 공원 -STR_DTLS :대대적인 확장을 해야하는 비좁은 놀이공원입니다. +STR_DTLS :대대적인 확장을 해야 하는 비좁은 놀이공원입니다. STR_SCNR :White Water Park STR_PARK :맑은 물 공원 -STR_DTLS :훌륭한 물 놀이기구를 몇 개 갖고있지만 확장이 필요한 공원입니다. +STR_DTLS :훌륭한 물 놀이기구를 몇 개 갖고 있지만 확장이 필요한 공원입니다. STR_SCNR :Millennium Mines @@ -3824,12 +3824,12 @@ STR_DTLS :버려져있는 커다란 탄광을 관광시설에서 놀이공원 STR_SCNR :Karts & Coasters STR_PARK :카트 & 코스터 -STR_DTLS :몇 개의 고 카트 트랙과 우든 롤러코스터만이 숲 속에 숨겨져 있는 대형 놀이공원입니다. +STR_DTLS :몇 개의 고 카트 트랙과 우든 롤러코스터만이 숲속에 숨겨져 있는 대형 놀이공원입니다. STR_SCNR :Mel's World STR_PARK :멜의 세계 -STR_DTLS :이 놀이공원에는 잘 디자인된 현대식 놀이기구가 있지만 아직도 확장해야 할 곳이 많습니다. +STR_DTLS :이 놀이공원에는 잘 디자인된 현대식 놀이기구가 있지만, 아직도 확장해야 할 곳이 많습니다. STR_SCNR :Mystic Mountain @@ -3869,7 +3869,7 @@ STR_DTLS :무지개 계곡의 지역 당국은 풍경을 바꾸거나 큰 나 STR_SCNR :Thunder Rock STR_PARK :천둥 바위 -STR_DTLS :천둥 바위는 사막 한가운데에서 많은 관광객을 끌어 모으고 있습니다. 사용 가능한 공간을 이용해 놀이기구를 건설해서 더 많은 사람들을 끌어 보세요. +STR_DTLS :천둥 바위는 사막 한가운데에서 많은 관광객을 끌어모으고 있습니다. 사용 가능한 공간을 이용해 놀이기구를 건설해서 더 많은 사람을 끌어 보세요. STR_SCNR :Mega Park @@ -3880,12 +3880,12 @@ STR_DTLS :그냥 즐기세요! STR_SCNR :Whispering Cliffs STR_PARK :속삭이는 절벽 -STR_DTLS :해변의 절벽을 인기있는 놀이공원으로 발전시키세요. +STR_DTLS :해변의 절벽을 인기 있는 놀이공원으로 발전시키세요. STR_SCNR :Three Monkeys Park STR_PARK :세 원숭이 공원 -STR_DTLS :개발 중인 이 거대한 공원의 한 가운데에는 동시에 경주하는 거대한 세 쌍둥이 스틸 롤러코스터가 있습니다. +STR_DTLS :개발 중인 이 거대한 공원의 한 가운데에는 동시에 경주하는 거대한 세쌍둥이 스틸 롤러코스터가 있습니다. STR_SCNR :Canary Mines @@ -3990,7 +3990,7 @@ STR_DTLS :사막 한가운데의 오아시스에 놀이공원을 건설해보 STR_SCNR :Rotting Heights STR_PARK :썩어버린 언덕 -STR_DTLS :지나치게 성장해서 황폐화되어버린 이 곳을 다시 멋진 공원으로 바꿀 수 있습니까? +STR_DTLS :지나치게 성장해서 황폐화되어버린 이곳을 다시 멋진 공원으로 바꿀 수 있습니까? STR_SCNR :Fiasco Forest @@ -4042,7 +4042,7 @@ STR_DTLS :이번 롤러코스터 건설 도전에서는 휴화산이 무대 STR_SCNR :Arid Heights STR_PARK :건조한 언덕 -STR_DTLS :아무런 재정적 제한 없는 상황에서, 지속적으로 손님들을 행복하게 만들 수 있는 공원을 사막에 건설해보세요. +STR_DTLS :아무런 재정적 제한 없는 상황에서, 손님들을 언제나 행복하게 만들 수 있는 공원을 사막에 건설해보세요. STR_SCNR :Razor Rocks @@ -4057,12 +4057,12 @@ STR_DTLS :이 공원의 부지는 고대 분화구에 만들어진 커다란 STR_SCNR :Vertigo Views STR_PARK :어지러운 풍경 -STR_DTLS :이 거대한 공원에는 이미 훌륭한 하이퍼코스터가 있습니다. 여러분의 임무는 그 매출을 아주 극대화시키는 것입니다. +STR_DTLS :이 거대한 공원에는 이미 훌륭한 하이퍼코스터가 있습니다. 여러분의 임무는 그 매출을 아주 극대화하는 것입니다. STR_SCNR :Paradise Pier 2 STR_PARK :파라다이스 부두 2 -STR_DTLS :파라다이스 부두는 바다 위의 산책로를 확장했습니다. 여러분의 임무는 이 새로운 공간을 이용하여 공원을 확장하는 것 입니다. +STR_DTLS :파라다이스 부두는 바다 위의 산책로를 확장했습니다. 여러분의 임무는 이 새로운 공간을 이용하여 공원을 확장하는 것입니다. STR_SCNR :Dragon's Cove @@ -4259,12 +4259,12 @@ STR_DTLS :이 작은 시장에 고객들을 유치하기 위해 놀이기구 STR_SCNR :이상한 성 STR_PARK :이상한 성 -STR_DTLS :당신은 큰 성을 물려받았습니다. 이제 이 성을 작은 놀이공원으로 바꾸는 것이 당신이 해야할 일입니다. +STR_DTLS :당신은 큰 성을 물려받았습니다. 이제 이 성을 작은 놀이공원으로 바꾸는 것이 당신이 해야 할 일입니다. STR_SCNR :먼지투성이 그린 STR_PARK :먼지투성이 그린 -STR_DTLS :사막의 고속도로 교차로 근처에 있는 먼지투성이 그린을 작은 골프 리조트에서 번화한 놀이공원으로 개발할 수 있는 기회가 생겼습니다. +STR_DTLS :사막의 고속도로 교차로 근처에 있는 먼지투성이 그린을 작은 골프 리조트에서 번화한 놀이공원으로 개발할 기회가 생겼습니다. STR_SCNR :일렉트릭 농장 @@ -4309,7 +4309,7 @@ STR_DTLS :자본에는 제한이 없지만 호수가 있는 곳이기 때문 STR_SCNR :무지개 정상 STR_PARK :무지개 정상 -STR_DTLS :이 공원은 산 허리에 만들어야 하고, 높은 건물은 지을 수 없습니다. 공원을 확장하여 성공할 자신이 있습니까? +STR_DTLS :이 공원은 산허리에 만들어야 하고, 높은 건물은 지을 수 없습니다. 공원을 확장하여 성공할 자신이 있습니까? STR_SCNR :식스 플래그 벨기에 @@ -4382,7 +4382,7 @@ STR_DTLS :문화 인식 프로그램의 일환으로, 오스트레일리아 STR_SCNR :오스트레일리아 - 해변의 즐거움 STR_PARK :해변의 바베큐 파티 -STR_DTLS :근처 지역 사업가의 해안 공원이 파산해버렸습니다. 이미 작은 공원을 운영하고 있는 당신은 건설사로부터 그 공원을 구입하였습니다. 두 공원을 합쳐 크게 사업을 확장해보세요. +STR_DTLS :근처 지역 사업가의 해안 공원이 파산해버렸습니다. 이미 작은 공원을 운영하는 당신은 건설사로부터 그 공원을 구입하였습니다. 두 공원을 합쳐 크게 사업을 확장해보세요. STR_SCNR :유럽 - 유럽 문화 축제 @@ -4392,20 +4392,20 @@ STR_DTLS :유럽 문화 축제의 경영권을 확보한 당신은 이제 유 STR_SCNR :유럽 - 혁신 STR_PARK :잿더미를 딛고 -STR_DTLS :방치되어 있는 낡은 공원이 있습니다. 이 공원이 과거에 누렸던 영광을 재현하기 위해 유럽 연합의 허가를 받았습니다! 허가를 받은 만큼 공원을 혁신해서 보답하세요. +STR_DTLS :방치된 낡은 공원이 있습니다. 이 공원이 과거에 누렸던 영광을 재현하기 위해 유럽 연합의 허가를 받았습니다! 허가를 받은 만큼 공원을 혁신해서 보답하세요. -STR_SCNR :북 아메리카 - 최고의 하와이 섬 +STR_SCNR :북아메리카 - 최고의 하와이 섬 STR_PARK :왁자지껄 와이키키 -STR_DTLS :하와이 주민들이 이제 파도타기가 지겨워져서 좀 더 자극적인 뭔가를 원하고 있습니다. 주민들도 만족시키면서 이 지역의 관광객들이 찾아오고 싶어하는 공원을 만드세요. +STR_DTLS :하와이 주민들이 이제 파도타기가 지겨워져서 좀 더 자극적인 뭔가를 원하고 있습니다. 주민들도 만족시키면서 이 지역의 관광객들이 찾아오고 싶어 하는 공원을 만드세요. -STR_SCNR :북 아메리카 - 그랜드 캐니언 +STR_SCNR :북아메리카 - 그랜드 캐니언 STR_PARK :불행의 계곡 -STR_DTLS :이 아름답지만 제한적인 공간에 공원을 만들어야 합니다. 미국 원주민에게서 반대편 땅을 구입할 수 있습니다. 줄어들고 있는 마을 인구를 유지하기 위해서라도 목표를 달성해야 합니다. +STR_DTLS :이 아름답지만 제한적인 공간에 공원을 만들어야 합니다. 미국 원주민에게서 반대편 땅을 살 수 있습니다. 줄어들고 있는 마을 인구를 유지하기 위해서라도 목표를 달성해야 합니다. -STR_SCNR :북 아메리카 - 롤러코스터 천국 +STR_SCNR :북아메리카 - 롤러코스터 천국 STR_PARK :롤러코스터 천국 STR_DTLS :당신은 긴 휴식기를 가지는 동안 이 도시 공원을 롤러코스터 천국으로 바꾸고자 하는 성공한 사업 거물입니다. 돈은 문제가 되지 않는군요! @@ -4422,7 +4422,7 @@ STR_DTLS :소중한 열대우림 속의 제한된 공간만을 받았습니 STR_SCNR :남 아메리카 - 리오 축제 STR_PARK :슈거로프 해안 -STR_DTLS :리오 근처의 작은 공원을 운영하고 있는데 은행이 대출금을 조기 회수하려 합니다. 때이른 빚 독촉을 갚기 위해서 빨리 돈을 벌어야 합니다. +STR_DTLS :리오 근처의 작은 공원을 운영하고 있는데 은행이 대출금을 조기 회수하려 합니다. 때 이른 빚 독촉을 갚기 위해서 빨리 돈을 벌어야 합니다. ############################################################################### ## Time Twister Scenarios @@ -4433,14 +4433,14 @@ STR_PARK :클리프사이드 성 STR_DTLS :이 지역의 전투 재현 단체는 자신들의 취미를 진지하게 생각하고 있습니다. 그들은 당신에게 클리프사이드 성 부지에 암흑시대 테마파크를 건설해달라고 요청해왔습니다. -STR_SCNR :암흑 시대 - 로빈 후드 +STR_SCNR :암흑시대 - 로빈 후드 STR_PARK :셔우드 숲 STR_DTLS :부자들의 재산을 빼앗아 필요한 사람들에게 나누어주기 위해서 당신과 수하들은 셔우드 숲에 놀이공원을 만들기로 결정했습니다. STR_SCNR :미래 - 첫 만남 STR_PARK :외계인의 축제 -STR_DTLS :먼 행성에서 생명체가 발견되었습니다. 외계인을 주제로 한 놀이공원을 만들어서 전에 없던 뜨거운 관심을 받아 돈을 벌어보세요. +STR_DTLS :먼 행성에서 생명체가 발견되었습니다. 외계인을 주제로 한 놀이공원을 만들어서 전에 없던 관심을 받아 돈을 벌어보세요. STR_SCNR :미래 - 미래 세계 @@ -4470,7 +4470,7 @@ STR_DTLS :당신은 쥐라기 시대 놀이공원을 건설하는 임무를 STR_SCNR :선사시대 - 석기시대 STR_PARK :돌무더기 산책 -STR_DTLS :고속도로 개발자들을 막고 고대 열석을 보호하기 위해, 석기 시대 테마파크를 건설하여 수익을 내야 합니다. 하지만 사람이 살기 조금 힘든 곳인만큼 손님을 모으기가 어려울 것입니다. +STR_DTLS :고속도로 개발자들을 막고 고대 열석을 보호하기 위해, 석기 시대 테마파크를 건설하여 수익을 내야 합니다. 하지만 사람이 살기 조금 힘든 곳인 만큼 손님을 모으기가 어려울 것입니다. STR_SCNR :광란의 20년대 - 감옥 섬 From 0b41c0f9a1c68ee2c63f7882f17fdfb26b2a6c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 30 Mar 2019 13:50:49 -0700 Subject: [PATCH 145/506] Fix #8988: Improve lookups for codepoint offsets --- distribution/changelog.txt | 1 + src/openrct2/drawing/Font.cpp | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 8aa12f2c15..81f62d68f1 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -15,6 +15,7 @@ - Fix: [#8882] Submarine Ride does not count as indoors (original bug). - Fix: [#8900] Peep tracking is not synchronized. - Fix: [#8947] Detection of AVX2 support. +- Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) diff --git a/src/openrct2/drawing/Font.cpp b/src/openrct2/drawing/Font.cpp index 4700057ab9..41de488ae3 100644 --- a/src/openrct2/drawing/Font.cpp +++ b/src/openrct2/drawing/Font.cpp @@ -17,7 +17,7 @@ #include "TTF.h" #include -#include +#include static constexpr const int32_t SpriteFontLineHeight[FONT_SIZE_COUNT] = { 6, 10, 10 }; @@ -28,7 +28,7 @@ static uint8_t _additionalSpriteFontCharacterWidth[FONT_SIZE_COUNT][SPR_G2_GLYPH TTFFontSetDescriptor* gCurrentTTFFontSet; #endif // NO_TTF -static const std::map codepointOffsetMap = { +static const std::unordered_map codepointOffsetMap = { { UnicodeChar::ae_uc, SPR_G2_AE_UPPER - SPR_CHAR_START }, { UnicodeChar::o_stroke_uc, SPR_G2_O_STROKE_UPPER - SPR_CHAR_START }, { UnicodeChar::y_acute_uc, SPR_G2_Y_ACUTE_UPPER - SPR_CHAR_START }, @@ -197,12 +197,23 @@ static const std::map codepointOffsetMap = { { UnicodeChar::superscript_minus_one, CSChar::superscript_minus_one - CS_SPRITE_FONT_OFFSET }, }; +static char32_t _smallestCodepointValue = 0; +static char32_t _biggestCodepointValue = 0; + /** * * rct2: 0x006C19AC */ void font_sprite_initialise_characters() { + // Compute min and max that helps avoiding lookups for no reason. + _smallestCodepointValue = std::numeric_limits::max(); + for (const auto entry : codepointOffsetMap) + { + _smallestCodepointValue = std::min(_smallestCodepointValue, entry.first); + _biggestCodepointValue = std::max(_biggestCodepointValue, entry.first); + } + for (int32_t fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) { int32_t glyphOffset = fontSize * FONT_SPRITE_GLYPH_COUNT; @@ -243,9 +254,14 @@ void font_sprite_initialise_characters() int32_t font_sprite_get_codepoint_offset(int32_t codepoint) { - auto result = codepointOffsetMap.find(codepoint); - if (result != codepointOffsetMap.end()) - return result->second; + // Only search the table when its in range of the map. + if (static_cast(codepoint) >= _smallestCodepointValue + && static_cast(codepoint) <= _biggestCodepointValue) + { + auto result = codepointOffsetMap.find(codepoint); + if (result != codepointOffsetMap.end()) + return result->second; + } if (codepoint < 32 || codepoint >= 256) codepoint = '?'; From 6da2990bf12cd241a6db9554498860b62bc98828 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sun, 31 Mar 2019 04:00:40 +0000 Subject: [PATCH 146/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/fr-FR.txt | 1 - data/language/ko-KR.txt | 46 +++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/data/language/fr-FR.txt b/data/language/fr-FR.txt index 4dfafbbfe5..78c86021b2 100644 --- a/data/language/fr-FR.txt +++ b/data/language/fr-FR.txt @@ -2420,7 +2420,6 @@ STR_3190 :Suppléments allées STR_3191 :Groupes de décor STR_3192 :Entrée du parc STR_3193 :Etendue d'eau -STR_3194 :Description du scénario STR_3195 :Liste d'inventions STR_3196 :{WINDOW_COLOUR_2}Groupe de recherche : {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Eléments pré-inventés au début d'une partie : diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 3e0b80cb60..3f6697303f 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -95,22 +95,24 @@ STR_0090 :마인 라이드 STR_0091 :알 수 없는 놀이기구 (59) STR_0092 :LIM 발진 롤러코스터 STR_0512 :나선형 리프트 힐과 부드럽게 꼬인 낙하를 가진 알찬 구성의 롤러코스터입니다. -STR_0513 :손님들이 일어선 자세로 탑승하는 루핑 롤러코스터입니다. -STR_0514 :코너를 돌 때 롤러코스터 트랙 아래에 달린 차량이 흔들리는 열차입니다. -STR_0515 :복잡하고 꼬인 트랙 요소를 가진 트랙 아래를 달리는 스틸 롤러코스터 차량입니다. +STR_0513 :일어선 자세로 탑승하는 루핑 롤러코스터입니다. +STR_0514 :코너를 돌 때 롤러코스터 트랙 아래에 매달린 차량이 좌우로 흔들리는 열차입니다. +STR_0515 :트랙 아래에 매달려 복잡하고 꼬인 트랙을 달리는 철제 롤러코스터 차량입니다. STR_0516 :큰 놀이기구를 탈 용기가 없는 사람들을 위한 얌전한 롤러코스터입니다. -STR_0517 :손님들이 협궤 선로를 따라 달리는 모형 열차에 탑승하는 놀이기구입니다. -STR_0518 :손님들이 모노레일 트랙을 따라 달리는 전기 차량에 탑승하는 놀이기구입니다. -STR_0519 :손님들이 단선 트랙 아래에 달려서 코너를 돌 때마다 좌우로 흔들리는 작은 차량에 탑승하는 놀이기구입니다. -STR_0520 :손님들이 물 위를 다니는 배를 운전하거나 또는 저을 수 있는 선착장입니다. -STR_0521 :급커브와 급하강을 가진 빠르게 꼬인 롤러코스터입니다. 격렬도가 높게 나올 것입니다. -STR_0522 :탑승객이 차량 없이 트랙 위에 앉는 작은 롤러코스터입니다. +STR_0517 :협궤 선로를 따라 달리는 모형 열차에 탑승하는 놀이기구입니다. +STR_0518 :모노레일 트랙을 따라 달리는 전동 차량에 탑승하는 놀이기구입니다. +STR_0519 :단선 트랙 아래에 달려서 코너를 돌 때마다 좌우로 흔들리는 작은 차량에 탑승하는 놀이기구입니다. +STR_0520 :노를 젓거나 운전해서 물 위를 다니는 배가 있는 선착장입니다. +STR_0521 :급커브와 급하강 트랙을 빠르게 달리는 롤러코스터입니다. 격렬도가 높게 나올 것입니다. +STR_0522 :탑승객이 주변을 감싸는 차량 없이 트랙 위에 얹혀진 좌석에 앉는 작은 롤러코스터입니다. STR_0523 :정해진 트랙을 따라 천천히 움직이는 놀이기구입니다. -STR_0524 :자유낙하 차량은 공기 압축 방식으로 높은 철제 탑을 향해 차량을 쏘아올려 자유낙하하는 차량입니다. -STR_0525 :손님들이 반원형으로 휘어있고 꼬여있는 트랙을 따라 이동합니다. -STR_0526 :손님들이 높은 곳으로 회전하면서 올라가는 관망대 캐빈에 탑승하는 놀이기구입니다. +STR_0524 :공기 압축 방식으로 높은 철제 탑을 따라 차량을 쏘아 올려 자유낙하하는 놀이기구입니다. +STR_0525 :반원 모양의 트랙을 구불구불 커브를 돌며 내려오는 롤러코스터입니다. +STR_0526 :손님들이 회전하는 전망대 캐빈에 탑승해서 높은 곳을 구경하는 놀이기구입니다. STR_0527 :수직 루프를 사용할 수 있는 부드러운 철제 트랙의 롤러코스터입니다. -STR_0528 :손님들이 공기를 넣은 고무 보트를 타고 반원이나 원형의 튜브 트랙을 따라 이동하는 놀이기구입니다. +STR_0528 :고무보트를 타고 반원이나 원형 모양의 트랙을 따라 미끄러지는 놀이기구입니다. +손님들이 공기를 넣은 고무 보트를 타고 반원이나 원형의 튜브 트랙을 따라 이동하는 놀이기구입니다. +고무 보트를 타고 반원이나 원형의 모양의 트랙을 미끄러져 달리는 놀이기구입니다. STR_0529 :오래된 기차 선로처럼 보이게 만든 철제 트랙을 따라 움직이는 탄광 열차 테마를 한 롤러코스터 차량입니다. STR_0530 :철제 케이블에 달린 차량이 연속적으로 놀이기구의 한쪽 끝에서 다른 쪽 끝을 왕복 운행합니다. STR_0531 :차량이 나선 트랙과 루프를 통과하는 알찬 구성의 철제 트랙 롤러코스터입니다. @@ -118,7 +120,7 @@ STR_0532 : STR_0533 : STR_0534 :패트롤 엔진으로 움직이는 고 카트입니다. STR_0535 :통나무 모양의 보트가 수로를 따라 이동하고 낙하하면서 탑승객을 쫄딱 젖게 만듭니다. -STR_0536 :원형의 보트가 수로를 따라 요동치며, 폭포를 통과하며 물을 튀기고 탑승객들에게 거품 소용돌이를 통과하며 스릴을 선사합니다. +STR_0536 :원형의 보트가 수로를 따라 요동치면서, 폭포를 통과하고 물을 튀기며 거품 소용돌이를 통과하여 탑승객들에게 스릴을 선사합니다. STR_0537 : STR_0538 : STR_0539 : @@ -135,7 +137,7 @@ STR_0552 : STR_0553 : STR_0554 :차량이 선형 유도 모터에 의해 긴 평지 트랙을 따라 가속된 뒤, 수직 상승 트랙에 의해 위로 상승한 뒤 다시 뒤로 자유낙하하여 탑승장에 돌아옵니다. STR_0555 :손님은 엘리베이터에 탑승하여 한쪽에서 다른쪽으로 이동할 수 있습니다. -STR_0556 :폭이 넓은 차량이 수직으로 기울어진 트랙을 따라 내려오면서 극강의 자유 낙하 롤러코스터를 경험하게 해줍니다. +STR_0556 :폭이 넓은 차량이 수직으로 기울어진 트랙을 따라 내려오면서 최고의 자유 낙하를 경험하게 해줍니다. STR_0557 : STR_0558 : STR_0559 : @@ -145,12 +147,12 @@ STR_0562 :무서운 풍경과 특수 효과를 통과하며 여러 높이의 STR_0563 :탑승객들은 한 바퀴를 운행하는 편안한 좌석에 앉아 언덕을 오르면서 느낄 수 있는 '무중력 시간'뿐만이 아니라 크고 부드러운 낙하와 꼬인 트랙의 느낌을 즐길 수 있습니다. STR_0564 :목재 트랙 위를 움직이는 이 롤러코스터는 빠르고, 거칠고, 시끄럽고, 많은 '무중력 시간'과 함께 '제어 불가능할 것 같은' 탑승감을 선사합니다. STR_0565 :완만한 경사와 커브만을 가진 간단한 나무 롤러코스터로, 이 롤러코스터의 차량은 트랙 위에 얹힌 상태에서 오직 측면 마찰용 바퀴와 중력에 의해 운행됩니다. -STR_0566 :개별적인 롤러코스터 차량이 급커브와 짧고 급한 경사를 가진 지그재그 모양의 트랙을 어지럽게 돌아다닙니다. +STR_0566 :한 대의 롤러코스터 차량이 급커브와 짧고 급한 경사를 가진 지그재그 모양의 트랙을 어지럽게 돌아다닙니다. STR_0567 :트랙 반대편에 매달린 좌석에 앉아서, 탑승객들은 급강하와 여러 가지 반전 트랙을 통과하면서 거꾸러지는 동안 머리와 다리가 뒤집히게 됩니다. -STR_0569 :차량 밑에 달린 특별한 마차에 탑승하여, 탑승객들은 공중으로 급강하면서 하늘을 나는 기분을 느끼게 만듭니다. +STR_0569 :트랙에 매달린 특별한 차량에 탑승하여 공중으로 급강하면서, 하늘을 나는 기분을 느낄 수 있습니다. STR_0571 :원형의 차량이 나무 트랙을 지그재그로 이동하면서 회전하는 놀이기구입니다. STR_0572 :대형 보트가 넓은 수로를 따라 컨베이어 벨트에 의해 언덕을 올라간 뒤, 급강하하면서 큰 물보라를 일으켜 탑승객을 젖게 만듭니다. -STR_0573 :탑승객이 직접 페달을 밟아 이동하는, 철제 트랙을 달리는 헬리콥터 모양의 전동 차량입니다. +STR_0573 :탑승객이 직접 페달을 밟아 철제 트랙을 따라 이동하는 헬리콥터 모양의 전동 차량입니다. STR_0574 :탑승객은 특수한 마차에 누운 자세로 매달려, 이리 저리 꼬이고 뒤집히는 트랙을 땅을 등지거나 마주보는 자세로 탑승하게 됩니다. STR_0575 :공원 여기 저기로 사람들을 실어나르는, 단선 레일에 매달린 전동 열차입니다. STR_0577 :특수한 반전 섹션에서 앞뒤가 바뀌는 나무 트랙을 달리는 보우기 차입니다 @@ -160,11 +162,11 @@ STR_0580 :90m 이상의 언덕을 부드럽게 오르내리는 거대한 철 STR_0581 :원형 모양의 좌석이 맨 위까지 끌어올려진 다음, 자유 낙하하며, 자기장에 의해 부드럽게 바닥에 정지합니다. STR_0582 : STR_0583 : -STR_0584 :탑승객이 스스로 페달을 밟아 이동해야 하는, 특별한 철제 모노레일 트랙 위를 이동하는 자전거입니다. +STR_0584 :특별한 철제 모노레일 트랙 위에서 탑승객이 스스로 페달을 밟아 이동하는 자전거입니다. STR_0585 :탑승객은 트랙 밑에 매달린 좌석 한 쌍에 앉아 루프와 트위스트를 급격히 통과합니다. STR_0586 :보트 모양의 차량이 꼬인 커브와 급강하가 가능한 롤러코스터 트랙을 달리며, 강 섹션의 물에서는 물보라를 일으키며 감속합니다. -STR_0587 :아주 짜릿한 공기 압축 방식으로 발진하여 차량이 수직 트랙을 향해 속력을 높인 뒤, 꼭대기에 다다르면 다시 수직으로 하강하며 다시 탑승장에 도착합니다. -STR_0588 :개별적인 차량이 헤이펀 커브와 급강하를 포함한 지그재그 모양의 트랙 아래를 이동합니다. +STR_0587 :공기 압축 방식으로 아주 짜릿하게 발진하여 차량이 수직 트랙을 향해 속력을 높인 뒤, 꼭대기에서 다시 수직으로 하강하며 다시 탑승장에 도착합니다. +STR_0588 :한 대의 차량이 트랙에 매달려서 헤어핀 커브와 급강하 트랙을 지그재그 모양으로 달립니다. STR_0589 : STR_0590 :탑승객들은 잠수가 가능한 잠수함을 타고 수중 코스를 돕니다. STR_0591 :뗏목 모양의 보트가 강 모양의 트랙을 따라 얌전히 이동합니다. @@ -3567,7 +3569,7 @@ STR_6108 :스틸 트위스터 STR_6109 :하이퍼 트위스터 STR_6110 :주니어 롤러코스터 STR_6111 :클래식 미니 롤러코스터 -STR_6112 :차량이 나선 트랙과 루프를 통과하는 알찬 구성의 철제 트랙 롤러코스터입니다. +STR_6112 :나선 트랙과 루프를 통과하는 알찬 구성의 철제 트랙 롤러코스터입니다. STR_6113 :큰 낙하, 높은 속도, 그리고 무릎 안전바만 있는 편안한 차량을 가진 높고 뒤집어질 수 없는 롤러코스터입니다. STR_6114 :정해진 트랙을 따라 천천히 움직이는 놀이기구입니다. STR_6115 :급경사를 오를 수 있는 거대한 4 x 4 트럭 차량입니다. From 521b78390f591412946e59d41f0da4c485a7146e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 31 Mar 2019 05:42:47 -0700 Subject: [PATCH 147/506] Fix #8909: Potential crash when invoking game actions as server --- distribution/changelog.txt | 1 + src/openrct2/actions/GameAction.h | 4 ++-- src/openrct2/network/Network.cpp | 17 +++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 81f62d68f1..288939cb37 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -14,6 +14,7 @@ - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). - Fix: [#8900] Peep tracking is not synchronized. +- Fix: [#8909] Potential crash when invoking game actions as server. - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Improved: Allow the use of numpad enter key for console and chat. diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index 89cc8aa0db..6792c8c348 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -93,8 +93,8 @@ public: private: uint32_t const _type; - NetworkPlayerId_t _playerId = { 0 }; // Callee - uint32_t _flags = 0; // GAME_COMMAND_FLAGS + NetworkPlayerId_t _playerId = { -1 }; // Callee + uint32_t _flags = 0; // GAME_COMMAND_FLAGS uint32_t _networkId = 0; Callback_t _callback; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 90c27248ee..f99b9e0019 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -2031,16 +2031,13 @@ void Network::ProcessGameCommands() void Network::EnqueueGameAction(const GameAction* action) { - MemoryStream stream; - DataSerialiser dsOut(true, stream); - action->Serialise(dsOut); - - std::unique_ptr ga = GameActions::Create(action->GetType()); - ga->SetCallback(action->GetCallback()); - - stream.SetPosition(0); - DataSerialiser dsIn(false, stream); - ga->Serialise(dsIn); + std::unique_ptr ga = GameActions::Clone(action); + if (ga->GetPlayer() == -1 && GetMode() != NETWORK_MODE_NONE) + { + // Server can directly invoke actions and will have no player id assigned + // as that normally happens when receiving them over network. + ga->SetPlayer(network_get_current_player_id()); + } game_command_queue.emplace(gCurrentTicks, std::move(ga), _commandId++); } From 37c380974424fc2c4fedab4e59e1d2aef124f1bd Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 18 Dec 2018 16:40:28 +0100 Subject: [PATCH 148/506] Implement partial multicore rendering --- data/language/en-GB.txt | 2 + .../drawing/engines/opengl/TextureCache.cpp | 51 +++++--- .../drawing/engines/opengl/TextureCache.h | 2 + src/openrct2-ui/windows/Options.cpp | 11 +- src/openrct2/config/Config.cpp | 2 + src/openrct2/config/Config.h | 1 + src/openrct2/core/JobPool.hpp | 6 +- src/openrct2/drawing/ScrollingText.cpp | 2 +- src/openrct2/interface/Viewport.cpp | 123 ++++++++++-------- src/openrct2/localisation/Localisation.cpp | 6 +- src/openrct2/localisation/Localisation.h | 6 +- src/openrct2/localisation/StringIds.h | 2 + src/openrct2/paint/Paint.cpp | 37 +++--- src/openrct2/paint/Paint.h | 8 +- src/openrct2/paint/sprite/Paint.Litter.cpp | 2 +- src/openrct2/paint/sprite/Paint.Misc.cpp | 2 +- src/openrct2/paint/sprite/Paint.Peep.cpp | 2 +- src/openrct2/paint/sprite/Paint.Sprite.cpp | 4 +- .../paint/tile_element/Paint.Banner.cpp | 2 +- .../paint/tile_element/Paint.Entrance.cpp | 2 +- .../paint/tile_element/Paint.LargeScenery.cpp | 4 +- .../paint/tile_element/Paint.Path.cpp | 2 +- .../paint/tile_element/Paint.SmallScenery.cpp | 2 +- .../paint/tile_element/Paint.Surface.cpp | 2 +- .../paint/tile_element/Paint.TileElement.cpp | 4 +- src/openrct2/ride/TrackPaint.cpp | 2 +- src/openrct2/ride/VehiclePaint.cpp | 2 +- src/openrct2/ride/coaster/VirginiaReel.cpp | 2 +- src/openrct2/ride/gentle/HauntedHouse.cpp | 2 +- src/openrct2/ride/gentle/MerryGoRound.cpp | 2 +- src/openrct2/ride/gentle/MiniGolf.cpp | 4 +- src/openrct2/ride/gentle/SpiralSlide.cpp | 2 +- src/openrct2/ride/thrill/Enterprise.cpp | 2 +- src/openrct2/ride/thrill/LaunchedFreefall.cpp | 2 +- src/openrct2/ride/thrill/MagicCarpet.cpp | 2 +- src/openrct2/ride/thrill/PirateShip.cpp | 2 +- src/openrct2/ride/thrill/TopSpin.cpp | 2 +- src/openrct2/ride/thrill/Twist.cpp | 2 +- src/openrct2/ride/water/RiverRapids.cpp | 2 +- test/testpaint/TestPaint.cpp | 2 +- 40 files changed, 196 insertions(+), 123 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 0630b1c4cd..865637d53c 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3751,6 +3751,8 @@ STR_6301 :{SMALLFONT}{BLACK}Copy the selected object name to the clipboard. STR_6302 :{SMALLFONT}{BLACK}Copy the entire list of missing objects to the clipboard. STR_6303 :Downloading object ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Open scenery picker +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Use multiple threads to render ############# # Scenarios # diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index caf65149a0..117b188b0b 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -30,6 +30,8 @@ TextureCache::~TextureCache() void TextureCache::InvalidateImage(uint32_t image) { + std::unique_lock lock(_mutex); + uint32_t index = _indexMap[image]; if (index == UNUSED_INDEX) return; @@ -61,18 +63,28 @@ void TextureCache::InvalidateImage(uint32_t image) BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) { + uint32_t index; + image &= 0x7FFFF; - uint32_t index = _indexMap[image]; - if (index != UNUSED_INDEX) + // Try to read cached texture first. { - const auto& info = _textureCache[index]; - return { - info.index, - info.normalizedBounds, - }; + std::shared_lock lock(_mutex); + + index = _indexMap[image]; + if (index != UNUSED_INDEX) + { + const auto& info = _textureCache[index]; + return { + info.index, + info.normalizedBounds, + }; + } } + // Load new texture. + std::unique_lock lock(_mutex); + index = (uint32_t)_textureCache.size(); AtlasTextureInfo info = LoadImageTexture(image); @@ -87,18 +99,27 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa { GlyphId glyphId; glyphId.Image = image; - std::copy_n(palette, sizeof(glyphId.Palette), (uint8_t*)&glyphId.Palette); - auto kvp = _glyphTextureMap.find(glyphId); - if (kvp != _glyphTextureMap.end()) + // Try to read cached texture first. { - const auto& info = kvp->second; - return { - info.index, - info.normalizedBounds, - }; + std::shared_lock lock(_mutex); + + std::copy_n(palette, sizeof(glyphId.Palette), (uint8_t*)&glyphId.Palette); + + auto kvp = _glyphTextureMap.find(glyphId); + if (kvp != _glyphTextureMap.end()) + { + const auto& info = kvp->second; + return { + info.index, + info.normalizedBounds, + }; + } } + // Load new texture. + std::unique_lock lock(_mutex); + auto cacheInfo = LoadGlyphTexture(image, palette); auto it = _glyphTextureMap.insert(std::make_pair(glyphId, cacheInfo)); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index c763e5c448..bd3f8c6b42 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -198,6 +199,7 @@ private: std::array _indexMap; GLuint _paletteTexture = 0; + std::shared_mutex _mutex; public: TextureCache(); diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index d870dfa642..c41600f2fd 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -87,6 +87,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_STEAM_OVERLAY_PAUSE, WIDX_UNCAP_FPS_CHECKBOX, WIDX_SHOW_FPS_CHECKBOX, + WIDX_MULTITHREADING_CHECKBOX, WIDX_USE_VSYNC_CHECKBOX, WIDX_MINIMIZE_FOCUS_LOSS, @@ -236,7 +237,8 @@ static rct_widget window_options_display_widgets[] = { { WWT_CHECKBOX, 1, 25, 290, 144, 155, STR_STEAM_OVERLAY_PAUSE, STR_STEAM_OVERLAY_PAUSE_TIP }, // Pause on steam overlay { WWT_CHECKBOX, 1, 11, 153, 161, 172, STR_UNCAP_FPS, STR_UNCAP_FPS_TIP }, // Uncap fps { WWT_CHECKBOX, 1, 155, 290, 161, 172, STR_SHOW_FPS, STR_SHOW_FPS_TIP }, // Show fps - { WWT_CHECKBOX, 1, 11, 290, 176, 187, STR_USE_VSYNC, STR_USE_VSYNC_TIP }, // Use vsync + { WWT_CHECKBOX, 1, 155, 290, 176, 187, STR_MULTITHREADING, STR_MULTITHREADING_TIP }, // Multithreading + { WWT_CHECKBOX, 1, 11, 153, 176, 187, STR_USE_VSYNC, STR_USE_VSYNC_TIP }, // Use vsync { WWT_CHECKBOX, 1, 11, 290, 191, 202, STR_MINIMISE_FULLSCREEN_ON_FOCUS_LOSS, STR_MINIMISE_FULLSCREEN_ON_FOCUS_LOSS_TIP }, // Minimise fullscreen focus loss { WIDGETS_END }, }; @@ -522,6 +524,7 @@ static uint64_t window_options_page_enabled_widgets[] = { (1 << WIDX_UNCAP_FPS_CHECKBOX) | (1 << WIDX_USE_VSYNC_CHECKBOX) | (1 << WIDX_SHOW_FPS_CHECKBOX) | + (1 << WIDX_MULTITHREADING_CHECKBOX) | (1 << WIDX_MINIMIZE_FOCUS_LOSS) | (1 << WIDX_STEAM_OVERLAY_PAUSE) | (1 << WIDX_SCALE) | @@ -693,6 +696,11 @@ static void window_options_mouseup(rct_window* w, rct_widgetindex widgetIndex) config_save_default(); window_invalidate(w); break; + case WIDX_MULTITHREADING_CHECKBOX: + gConfigGeneral.multithreading ^= 1; + config_save_default(); + window_invalidate(w); + break; case WIDX_MINIMIZE_FOCUS_LOSS: gConfigGeneral.minimize_fullscreen_focus_loss ^= 1; platform_refresh_video(false); @@ -1711,6 +1719,7 @@ static void window_options_invalidate(rct_window* w) widget_set_checkbox_value(w, WIDX_UNCAP_FPS_CHECKBOX, gConfigGeneral.uncap_fps); widget_set_checkbox_value(w, WIDX_USE_VSYNC_CHECKBOX, gConfigGeneral.use_vsync); widget_set_checkbox_value(w, WIDX_SHOW_FPS_CHECKBOX, gConfigGeneral.show_fps); + widget_set_checkbox_value(w, WIDX_MULTITHREADING_CHECKBOX, gConfigGeneral.multithreading); widget_set_checkbox_value(w, WIDX_MINIMIZE_FOCUS_LOSS, gConfigGeneral.minimize_fullscreen_focus_loss); widget_set_checkbox_value(w, WIDX_STEAM_OVERLAY_PAUSE, gConfigGeneral.steam_overlay_pause); diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 15e31378f8..3eb02ff8b7 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -195,6 +195,7 @@ namespace Config model->window_scale = reader->GetFloat("window_scale", platform_get_default_scale()); model->scale_quality = reader->GetEnum("scale_quality", SCALE_QUALITY_SMOOTH_NN, Enum_ScaleQuality); model->show_fps = reader->GetBoolean("show_fps", false); + model->multithreading = reader->GetBoolean("multithreading", true); model->trap_cursor = reader->GetBoolean("trap_cursor", false); model->auto_open_shops = reader->GetBoolean("auto_open_shops", false); model->scenario_select_mode = reader->GetInt32("scenario_select_mode", SCENARIO_SELECT_MODE_ORIGIN); @@ -268,6 +269,7 @@ namespace Config writer->WriteFloat("window_scale", model->window_scale); writer->WriteEnum("scale_quality", model->scale_quality, Enum_ScaleQuality); writer->WriteBoolean("show_fps", model->show_fps); + writer->WriteBoolean("multithreading", model->multithreading); writer->WriteBoolean("trap_cursor", model->trap_cursor); writer->WriteBoolean("auto_open_shops", model->auto_open_shops); writer->WriteInt32("scenario_select_mode", model->scenario_select_mode); diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index e885512bf2..5d6ffc477e 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -32,6 +32,7 @@ struct GeneralConfiguration bool uncap_fps; bool use_vsync; bool show_fps; + bool multithreading; bool minimize_fullscreen_focus_loss; // Map rendering diff --git a/src/openrct2/core/JobPool.hpp b/src/openrct2/core/JobPool.hpp index 8dd6ec10af..f4a6f334ec 100644 --- a/src/openrct2/core/JobPool.hpp +++ b/src/openrct2/core/JobPool.hpp @@ -9,6 +9,7 @@ #pragma once +#include #include #include #include @@ -45,9 +46,10 @@ private: typedef std::unique_lock unique_lock; public: - JobPool() + JobPool(size_t maxThreads = 255) { - for (size_t n = 0; n < std::thread::hardware_concurrency(); n++) + maxThreads = std::min(maxThreads, std::thread::hardware_concurrency()); + for (size_t n = 0; n < maxThreads; n++) { _threads.emplace_back(&JobPool::ProcessQueue, this); } diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index e31abdc74b..0d35edea29 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -1474,7 +1474,7 @@ int32_t scrolling_text_setup(paint_session* session, rct_string_id stringId, uin { assert(scrollingMode < MAX_SCROLLING_TEXT_MODES); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level != 0) return SPR_SCROLLING_TEXT_DEFAULT; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 855f98a3d0..5ecf915dba 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -14,6 +14,7 @@ #include "../Input.h" #include "../OpenRCT2.h" #include "../config/Config.h" +#include "../core/JobPool.hpp" #include "../drawing/Drawing.h" #include "../paint/Paint.h" #include "../peep/Staff.h" @@ -42,6 +43,7 @@ rct_viewport g_viewport_list[MAX_VIEWPORT_COUNT]; rct_viewport* g_music_tracking_viewport; static TileElement* _interaction_element = nullptr; +static std::unique_ptr _paintJobs; int16_t gSavedViewX; int16_t gSavedViewY; @@ -60,7 +62,6 @@ static int16_t _interactionMapX; static int16_t _interactionMapY; static uint16_t _unk9AC154; -static void viewport_paint_column(rct_drawpixelinfo* dpi, uint32_t viewFlags, std::vector* sessions); static void viewport_paint_weather_gloom(rct_drawpixelinfo* dpi); /** @@ -833,6 +834,41 @@ void viewport_render( #endif } +static void viewport_fill_column(paint_session* session) +{ + paint_session_generate(session); + paint_session_arrange(session); +} + +static void viewport_paint_column(paint_session* session) +{ + if (session->ViewFlags + & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_CLIP_VIEW)) + { + uint8_t colour = 10; + if (session->ViewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) + { + colour = 0; + } + gfx_clear(&session->DPI, colour); + } + + paint_draw_structs(session); + + if (gConfigGeneral.render_weather_gloom && !gTrackDesignSaveMode && !(session->ViewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) + && !(session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) + { + viewport_paint_weather_gloom(&session->DPI); + } + + if (session->PSStringHead != nullptr) + { + paint_draw_money_structs(&session->DPI, session->PSStringHead); + } + + paint_session_free(session); +} + /** * * rct2: 0x00685CBF @@ -880,82 +916,65 @@ void viewport_paint( // this as well as the [x += 32] in the loop causes signed integer overflow -> undefined behaviour. int16_t rightBorder = dpi1.x + dpi1.width; - // Splits the area into 32 pixel columns and renders them - int16_t start_x = floor2(dpi1.x, 32); - if (sessions != nullptr) + std::vector columns; + + bool useMultithreading = gConfigGeneral.multithreading; + if (window_get_main() != nullptr && viewport != window_get_main()->viewport) + useMultithreading = false; + + if (useMultithreading == true && _paintJobs == nullptr) { - sessions->reserve((rightBorder - start_x) / 32); + _paintJobs = std::make_unique(); } - for (int16_t columnx = start_x; columnx < rightBorder; columnx += 32) + else if (useMultithreading == false && _paintJobs != nullptr) { - rct_drawpixelinfo dpi2 = dpi1; - if (columnx >= dpi2.x) + _paintJobs.reset(); + } + + // Splits the area into 32 pixel columns and renders them + size_t index = 0; + for (x = floor2(dpi1.x, 32); x < rightBorder; x += 32, index++) + { + paint_session* session = paint_session_alloc(&dpi1, viewFlags); + columns.push_back(session); + + rct_drawpixelinfo& dpi2 = session->DPI; + if (x >= dpi2.x) { - int16_t leftPitch = columnx - dpi2.x; + int16_t leftPitch = x - dpi2.x; dpi2.width -= leftPitch; dpi2.bits += leftPitch >> dpi2.zoom_level; dpi2.pitch += leftPitch >> dpi2.zoom_level; - dpi2.x = columnx; + dpi2.x = x; } int16_t paintRight = dpi2.x + dpi2.width; - if (paintRight >= columnx + 32) + if (paintRight >= x + 32) { - int16_t rightPitch = paintRight - columnx - 32; + int16_t rightPitch = paintRight - x - 32; paintRight -= rightPitch; dpi2.pitch += rightPitch >> dpi2.zoom_level; } dpi2.width = paintRight - dpi2.x; - viewport_paint_column(&dpi2, viewFlags, sessions); - } -} - -static void viewport_paint_column(rct_drawpixelinfo* dpi, uint32_t viewFlags, std::vector* sessions) -{ - if (viewFlags - & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_CLIP_VIEW)) - { - uint8_t colour = 10; - if (viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) + if (useMultithreading) { - colour = 0; + _paintJobs->AddTask([session]() -> void { viewport_fill_column(session); }); } - gfx_clear(dpi, colour); - } - - paint_session* session = paint_session_alloc(dpi, viewFlags); - paint_session_generate(session); - // Perform a deep copy of the paint session, use relative offsets. - // This is done to extract the session for benchmark. - if (sessions != nullptr) - { - sessions->push_back(*session); - paint_session* session_copy = &sessions->at(sessions->size() - 1); - - // Mind the offset needs to be calculated against the original `session`, not `session_copy` - for (auto& ps : session_copy->PaintStructs) + else { - ps.basic.next_quadrant_ps = (paint_struct*)(ps.basic.next_quadrant_ps ? int(ps.basic.next_quadrant_ps - &session->PaintStructs[0].basic) : std::size(session->PaintStructs)); - } - for (auto& quad : session_copy->Quadrants) - { - quad = (paint_struct*)(quad ? int(quad - &session->PaintStructs[0].basic) : std::size(session->Quadrants)); + viewport_fill_column(session); } } - paint_session_arrange(session); - paint_draw_structs(session); - paint_session_free(session); - if (gConfigGeneral.render_weather_gloom && !gTrackDesignSaveMode && !(viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) - && !(viewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) + if (useMultithreading) { - viewport_paint_weather_gloom(dpi); + _paintJobs->Join(); } - if (session->PSStringHead != nullptr) + for (auto&& column : columns) { - paint_draw_money_structs(dpi, session->PSStringHead); + viewport_paint_column(column); } } @@ -1590,7 +1609,7 @@ static bool sub_679023(rct_drawpixelinfo* dpi, int32_t imageId, int32_t x, int32 static void sub_68862C(paint_session* session) { paint_struct* ps = &session->PaintHead; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; while ((ps = ps->next_quadrant_ps) != nullptr) { diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index 99ae0930be..d62b5de7d8 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -35,9 +35,9 @@ #include #include -char gCommonStringFormatBuffer[512]; -uint8_t gCommonFormatArgs[80]; -uint8_t gMapTooltipFormatArgs[40]; +thread_local char gCommonStringFormatBuffer[512]; +thread_local uint8_t gCommonFormatArgs[80]; +thread_local uint8_t gMapTooltipFormatArgs[40]; #ifdef DEBUG // Set to true before a string format call to see details of the formatting. diff --git a/src/openrct2/localisation/Localisation.h b/src/openrct2/localisation/Localisation.h index 6039265b77..ef848aec28 100644 --- a/src/openrct2/localisation/Localisation.h +++ b/src/openrct2/localisation/Localisation.h @@ -74,9 +74,9 @@ extern const char real_name_initials[16]; extern const char* real_names[1024]; extern utf8 gUserStrings[MAX_USER_STRINGS][USER_STRING_MAX_LENGTH]; -extern char gCommonStringFormatBuffer[512]; -extern uint8_t gCommonFormatArgs[80]; -extern uint8_t gMapTooltipFormatArgs[40]; +extern thread_local char gCommonStringFormatBuffer[512]; +extern thread_local uint8_t gCommonFormatArgs[80]; +extern thread_local uint8_t gMapTooltipFormatArgs[40]; extern bool gDebugStringFormatting; extern const rct_string_id SpeedNames[5]; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 9395aa69ee..6a03538327 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3934,6 +3934,8 @@ enum STR_DOWNLOADING_OBJECTS = 6303, STR_SHORTCUT_OPEN_SCENERY_PICKER = 6304, + STR_MULTITHREADING = 6305, + STR_MULTITHREADING_TIP = 6306, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index d66483f260..853c5090d4 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -18,14 +18,15 @@ #include "tile_element/Paint.TileElement.h" #include +#include +#include // Globals for paint clipping uint8_t gClipHeight = 128; // Default to middle value LocationXY8 gClipSelectionA = { 0, 0 }; LocationXY8 gClipSelectionB = { MAXIMUM_MAP_SIZE_TECHNICAL - 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1 }; -paint_session gPaintSession; -static bool _paintSessionInUse; +static std::vector _freePaintSessions; static constexpr const uint8_t BoundBoxDebugColours[] = { 0, // NONE @@ -56,7 +57,7 @@ static uint32_t paint_ps_colourify_image(uint32_t imageId, uint8_t spriteType, u static void paint_session_init(paint_session* session, rct_drawpixelinfo* dpi, uint32_t viewFlags) { - session->DPI = dpi; + session->DPI = *dpi; session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; session->NextFreePaintStruct = session->PaintStructs; session->LastRootPS = nullptr; @@ -132,7 +133,7 @@ static paint_struct* sub_9819_c( int32_t right = left + g1->width; int32_t top = bottom + g1->height; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (right <= dpi->x) return nullptr; @@ -192,7 +193,7 @@ static paint_struct* sub_9819_c( */ void paint_session_generate(paint_session* session) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; LocationXY16 mapTile = { (int16_t)(dpi->x & 0xFFE0), (int16_t)((dpi->y - 16) & 0xFFE0) }; int16_t half_x = mapTile.x >> 1; @@ -458,7 +459,6 @@ void paint_session_arrange(paint_session* session) ps->next_quadrant_ps = nullptr; uint32_t quadrantIndex = session->QuadrantBackIndex; - const uint8_t rotation = get_current_rotation(); if (quadrantIndex != UINT32_MAX) { do @@ -477,19 +477,19 @@ void paint_session_arrange(paint_session* session) } while (++quadrantIndex <= session->QuadrantFrontIndex); paint_struct* ps_cache = paint_arrange_structs_helper( - psHead, session->QuadrantBackIndex & 0xFFFF, PAINT_QUADRANT_FLAG_NEXT, rotation); + psHead, session->QuadrantBackIndex & 0xFFFF, PAINT_QUADRANT_FLAG_NEXT, session->CurrentRotation); quadrantIndex = session->QuadrantBackIndex; while (++quadrantIndex < session->QuadrantFrontIndex) { - ps_cache = paint_arrange_structs_helper(ps_cache, quadrantIndex & 0xFFFF, 0, rotation); + ps_cache = paint_arrange_structs_helper(ps_cache, quadrantIndex & 0xFFFF, 0, session->CurrentRotation); } } } static void paint_draw_struct(paint_session* session, paint_struct* ps) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; int16_t x = ps->x; int16_t y = ps->y; @@ -732,10 +732,17 @@ static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo* dpi) paint_session* paint_session_alloc(rct_drawpixelinfo* dpi, uint32_t viewFlags) { - // Currently limited to just one session at a time - assert(!_paintSessionInUse); - _paintSessionInUse = true; - paint_session* session = &gPaintSession; + paint_session* session = nullptr; + + if (_freePaintSessions.empty()) + { + session = new paint_session(); + } + else + { + session = _freePaintSessions[_freePaintSessions.size() - 1]; + _freePaintSessions.resize(_freePaintSessions.size() - 1); + } paint_session_init(session, dpi, viewFlags); return session; @@ -743,7 +750,7 @@ paint_session* paint_session_alloc(rct_drawpixelinfo* dpi, uint32_t viewFlags) void paint_session_free([[maybe_unused]] paint_session* session) { - _paintSessionInUse = false; + _freePaintSessions.push_back(session); } /** @@ -845,7 +852,7 @@ paint_struct* sub_98196C( int16_t right = left + g1Element->width; int16_t top = bottom + g1Element->height; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (right <= dpi->x) return nullptr; diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 85796488bf..039245c955 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -137,9 +137,15 @@ struct tunnel_entry #define MAX_PAINT_QUADRANTS 512 #define TUNNEL_MAX_COUNT 65 +struct paint_pending +{ + rct_drawpixelinfo dpi; + uint32_t viewFlags; +}; + struct paint_session { - rct_drawpixelinfo* DPI; + rct_drawpixelinfo DPI; paint_entry PaintStructs[4000]; paint_struct* Quadrants[MAX_PAINT_QUADRANTS]; paint_struct PaintHead; diff --git a/src/openrct2/paint/sprite/Paint.Litter.cpp b/src/openrct2/paint/sprite/Paint.Litter.cpp index 0c37d0840b..ece57eb724 100644 --- a/src/openrct2/paint/sprite/Paint.Litter.cpp +++ b/src/openrct2/paint/sprite/Paint.Litter.cpp @@ -69,7 +69,7 @@ void litter_paint(paint_session* session, const rct_litter* litter, int32_t imag { rct_drawpixelinfo* dpi; - dpi = session->DPI; + dpi = &session->DPI; if (dpi->zoom_level != 0) return; // If zoomed at all no litter drawn diff --git a/src/openrct2/paint/sprite/Paint.Misc.cpp b/src/openrct2/paint/sprite/Paint.Misc.cpp index b4e668e11a..2e598049f6 100644 --- a/src/openrct2/paint/sprite/Paint.Misc.cpp +++ b/src/openrct2/paint/sprite/Paint.Misc.cpp @@ -30,7 +30,7 @@ const uint32_t vehicle_particle_base_sprites[] = { */ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDirection) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; switch (misc->steam_particle.type) { diff --git a/src/openrct2/paint/sprite/Paint.Peep.cpp b/src/openrct2/paint/sprite/Paint.Peep.cpp index ea7586fb40..69d33e5d4a 100644 --- a/src/openrct2/paint/sprite/Paint.Peep.cpp +++ b/src/openrct2/paint/sprite/Paint.Peep.cpp @@ -56,7 +56,7 @@ void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection } #endif - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level > 2) { return; diff --git a/src/openrct2/paint/sprite/Paint.Sprite.cpp b/src/openrct2/paint/sprite/Paint.Sprite.cpp index 6944c91d65..6e5f3a9185 100644 --- a/src/openrct2/paint/sprite/Paint.Sprite.cpp +++ b/src/openrct2/paint/sprite/Paint.Sprite.cpp @@ -40,7 +40,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t return; } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level > 2) { return; @@ -89,7 +89,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t } } - dpi = session->DPI; + dpi = &session->DPI; if (dpi->y + dpi->height <= spr->generic.sprite_top || spr->generic.sprite_bottom <= dpi->y || dpi->x + dpi->width <= spr->generic.sprite_left || spr->generic.sprite_right <= dpi->x) diff --git a/src/openrct2/paint/tile_element/Paint.Banner.cpp b/src/openrct2/paint/tile_element/Paint.Banner.cpp index 35378767e3..2471f8c287 100644 --- a/src/openrct2/paint/tile_element/Paint.Banner.cpp +++ b/src/openrct2/paint/tile_element/Paint.Banner.cpp @@ -34,7 +34,7 @@ const LocationXY16 BannerBoundBoxes[][2] = { void banner_paint(paint_session* session, uint8_t direction, int32_t height, const TileElement* tile_element) { uint16_t boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; session->InteractionType = VIEWPORT_INTERACTION_ITEM_BANNER; diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 406db6e812..edcb400de9 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -334,7 +334,7 @@ void entrance_paint(paint_session* session, uint8_t direction, int32_t height, c { session->InteractionType = VIEWPORT_INTERACTION_ITEM_LABEL; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (session->ViewFlags & VIEWPORT_FLAG_PATH_HEIGHTS && dpi->zoom_level == 0) { diff --git a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp index b5f9677c74..ea8fd3f599 100644 --- a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp @@ -293,7 +293,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei return; } } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level > 1) { large_scenery_paint_supports(session, direction, height, tileElement, dword_F4387C, tile); @@ -400,7 +400,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei } return; } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level > 0) { large_scenery_paint_supports(session, direction, height, tileElement, dword_F4387C, tile); diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 061d3d84dc..26d0b8d3aa 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -682,7 +682,7 @@ static void sub_6A3F61( // Probably drawing benches etc. - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level <= 1) { diff --git a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp index c2728279b4..5c204c352f 100644 --- a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp @@ -176,7 +176,7 @@ void scenery_paint(paint_session* session, uint8_t direction, int32_t height, co if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_ANIMATED)) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if ((scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_VISIBLE_WHEN_ZOOMED)) || (dpi->zoom_level <= 1)) { // 6E01A9: diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 0ec039b1a3..8833f7b3da 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -907,7 +907,7 @@ static void viewport_surface_draw_water_side_top( */ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, const TileElement* tileElement) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; session->InteractionType = VIEWPORT_INTERACTION_ITEM_TERRAIN; session->DidPassSurface = true; session->SurfaceElement = tileElement; diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index ac3098f802..0632f8f7c0 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -114,7 +114,7 @@ static void blank_tiles_paint(paint_session* session, int32_t x, int32_t y) dx -= 16; int32_t bx = dx + 32; - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (bx <= dpi->y) return; dx -= 20; @@ -136,7 +136,7 @@ bool gShowSupportSegmentHeights = false; */ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y) { - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if ((session->ViewFlags & VIEWPORT_FLAG_CLIP_VIEW)) { diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index 7e839aa8c0..b95f39c0e3 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -2164,7 +2164,7 @@ void track_paint(paint_session* session, uint8_t direction, int32_t height, cons return; } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if ((!gTrackDesignSaveMode || rideIndex == gTrackDesignSaveRideIndex) && !(session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 20016dd01f..e1d91f78ac 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -915,7 +915,7 @@ static void vehicle_sprite_paint( { ps->tertiary_colour = vehicle->colours_extended; } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level < 2 && vehicle->num_peeps > 0 && vehicleEntry->no_seating_rows > 0) { baseImage_id += vehicleEntry->no_vehicle_images; diff --git a/src/openrct2/ride/coaster/VirginiaReel.cpp b/src/openrct2/ride/coaster/VirginiaReel.cpp index 68370e32de..3336da22c3 100644 --- a/src/openrct2/ride/coaster/VirginiaReel.cpp +++ b/src/openrct2/ride/coaster/VirginiaReel.cpp @@ -199,7 +199,7 @@ void vehicle_visual_virginia_reel( sub_98197C( session, image_id, 0, 0, bb->length_x, bb->length_y, bb->length_z, z, bb->offset_x, bb->offset_y, bb->offset_z + z); - if (session->DPI->zoom_level < 2 && vehicle->num_peeps > 0) + if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0) { uint8_t riding_peep_sprites[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; for (int32_t i = 0; i < vehicle->num_peeps; i++) diff --git a/src/openrct2/ride/gentle/HauntedHouse.cpp b/src/openrct2/ride/gentle/HauntedHouse.cpp index 568021a629..569e10faf0 100644 --- a/src/openrct2/ride/gentle/HauntedHouse.cpp +++ b/src/openrct2/ride/gentle/HauntedHouse.cpp @@ -62,7 +62,7 @@ static void paint_haunted_house_structure( session, imageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level == 0 && frameNum != 0) { switch (direction) diff --git a/src/openrct2/ride/gentle/MerryGoRound.cpp b/src/openrct2/ride/gentle/MerryGoRound.cpp index 3b4ff34d4d..fb3db1cc96 100644 --- a/src/openrct2/ride/gentle/MerryGoRound.cpp +++ b/src/openrct2/ride/gentle/MerryGoRound.cpp @@ -71,7 +71,7 @@ static void paint_merry_go_round_structure( uint32_t imageId = (baseImageId + imageOffset) | imageColourFlags; sub_98197C(session, imageId, xOffset, yOffset, 24, 24, 48, height, xOffset + 16, yOffset + 16, height); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level == 0 && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr) { for (int32_t peep = 0; peep <= 14; peep += 2) diff --git a/src/openrct2/ride/gentle/MiniGolf.cpp b/src/openrct2/ride/gentle/MiniGolf.cpp index febe16ec0e..4c0152393e 100644 --- a/src/openrct2/ride/gentle/MiniGolf.cpp +++ b/src/openrct2/ride/gentle/MiniGolf.cpp @@ -1193,7 +1193,7 @@ void vehicle_visual_mini_golf_player( return; } - rct_drawpixelinfo* edi = session->DPI; + rct_drawpixelinfo* edi = &session->DPI; if (edi->zoom_level >= 2) { return; @@ -1226,7 +1226,7 @@ void vehicle_visual_mini_golf_ball( return; } - rct_drawpixelinfo* edi = session->DPI; + rct_drawpixelinfo* edi = &session->DPI; if (edi->zoom_level >= 1) { return; diff --git a/src/openrct2/ride/gentle/SpiralSlide.cpp b/src/openrct2/ride/gentle/SpiralSlide.cpp index 693351001b..4101cb5e96 100644 --- a/src/openrct2/ride/gentle/SpiralSlide.cpp +++ b/src/openrct2/ride/gentle/SpiralSlide.cpp @@ -121,7 +121,7 @@ static void spiral_slide_paint_tile_front( sub_98197C(session, image_id, 16, 16, 8, 16, 108, height, 8, 0, height + 3); } - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level == 0 && ride->slide_in_use != 0) { uint8_t slide_progress = ride->spiral_slide_progress; diff --git a/src/openrct2/ride/thrill/Enterprise.cpp b/src/openrct2/ride/thrill/Enterprise.cpp index 2ee2a68f88..0a8cb47c50 100644 --- a/src/openrct2/ride/thrill/Enterprise.cpp +++ b/src/openrct2/ride/thrill/Enterprise.cpp @@ -54,7 +54,7 @@ static void paint_enterprise_structure( uint32_t imageId = (baseImageId + imageOffset) | imageColourFlags; sub_98197C(session, imageId, xOffset, yOffset, 24, 24, 48, height, 0, 0, height); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level == 0 && imageOffset < 12 && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr) { diff --git a/src/openrct2/ride/thrill/LaunchedFreefall.cpp b/src/openrct2/ride/thrill/LaunchedFreefall.cpp index d516982cbf..39e9aa980e 100644 --- a/src/openrct2/ride/thrill/LaunchedFreefall.cpp +++ b/src/openrct2/ride/thrill/LaunchedFreefall.cpp @@ -47,7 +47,7 @@ void vehicle_visual_launched_freefall( sub_98197C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); // Draw peeps: - if (session->DPI->zoom_level < 2) + if (session->DPI.zoom_level < 2) { if (vehicle->num_peeps > 0) { diff --git a/src/openrct2/ride/thrill/MagicCarpet.cpp b/src/openrct2/ride/thrill/MagicCarpet.cpp index 8d4673fa44..390ebdfdf2 100644 --- a/src/openrct2/ride/thrill/MagicCarpet.cpp +++ b/src/openrct2/ride/thrill/MagicCarpet.cpp @@ -155,7 +155,7 @@ static void paint_magic_carpet_vehicle( bbOffset.x, bbOffset.y, bbOffset.z); // Riders - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level <= 1 && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) { rct_vehicle* vehicle = get_first_vehicle(ride); diff --git a/src/openrct2/ride/thrill/PirateShip.cpp b/src/openrct2/ride/thrill/PirateShip.cpp index b9c22faf2e..4c20195a2a 100644 --- a/src/openrct2/ride/thrill/PirateShip.cpp +++ b/src/openrct2/ride/thrill/PirateShip.cpp @@ -115,7 +115,7 @@ static void paint_pirate_ship_structure( session, imageId, xOffset, yOffset, bounds.length_x, bounds.length_y, 80, height, bounds.offset_x, bounds.offset_y, height); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level <= 1 && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr) { diff --git a/src/openrct2/ride/thrill/TopSpin.cpp b/src/openrct2/ride/thrill/TopSpin.cpp index 3c65e3ff37..f3527ce196 100644 --- a/src/openrct2/ride/thrill/TopSpin.cpp +++ b/src/openrct2/ride/thrill/TopSpin.cpp @@ -167,7 +167,7 @@ static void top_spin_paint_vehicle( session, image_id, (int8_t)seatCoords.x, (int8_t)seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level < 2 && vehicle != nullptr && vehicle->num_peeps != 0) { image_id = (seatImageId + (1 * 76)) diff --git a/src/openrct2/ride/thrill/Twist.cpp b/src/openrct2/ride/thrill/Twist.cpp index 53c2925586..a3e0ac979a 100644 --- a/src/openrct2/ride/thrill/Twist.cpp +++ b/src/openrct2/ride/thrill/Twist.cpp @@ -58,7 +58,7 @@ static void paint_twist_structure( uint32_t imageId = (baseImageId + structureFrameNum) | imageColourFlags; sub_98197C(session, imageId, xOffset, yOffset, 24, 24, 48, height, xOffset + 16, yOffset + 16, height); - rct_drawpixelinfo* dpi = session->DPI; + rct_drawpixelinfo* dpi = &session->DPI; if (dpi->zoom_level < 1 && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr) { diff --git a/src/openrct2/ride/water/RiverRapids.cpp b/src/openrct2/ride/water/RiverRapids.cpp index 1e72267cb0..b6886dc5bf 100644 --- a/src/openrct2/ride/water/RiverRapids.cpp +++ b/src/openrct2/ride/water/RiverRapids.cpp @@ -226,7 +226,7 @@ void vehicle_visual_river_rapids( sub_98197C( session, image_id, 0, 0, bb->length_x, bb->length_y, bb->length_z, z, bb->offset_x, bb->offset_y, bb->offset_z + z); - if (session->DPI->zoom_level < 2 && vehicle->num_peeps > 0) + if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0) { // Draw peeps: (this particular vehicle doesn't sort them back to front like others so the back ones sometimes clip, but // that's how the original does it...) diff --git a/test/testpaint/TestPaint.cpp b/test/testpaint/TestPaint.cpp index 97c72195d5..a78a808f31 100644 --- a/test/testpaint/TestPaint.cpp +++ b/test/testpaint/TestPaint.cpp @@ -43,7 +43,7 @@ namespace TestPaint rct_drawpixelinfo dpi = {}; dpi.zoom_level = 1; RCT2_Unk140E9A8 = &dpi; - gPaintSession.DPI = &dpi; + gPaintSession.DPI = dpi; { Ride ride = {}; From db96df010fa00e9e2af7518d90b6e8a481372fea Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 19 Feb 2019 16:03:08 +0100 Subject: [PATCH 149/506] Expose Painter in Context --- src/openrct2/Context.cpp | 5 +++++ src/openrct2/Context.h | 6 ++++++ src/openrct2/paint/Painter.h | 8 ++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 5a6b48ec72..a8770c749f 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -220,6 +220,11 @@ namespace OpenRCT2 return _drawingEngine.get(); } + virtual Paint::Painter* GetPainter() override + { + return _painter.get(); + } + int32_t RunOpenRCT2(int argc, const char** argv) override { if (Initialise()) diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index 902bf87293..dfe2479034 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -88,6 +88,11 @@ namespace OpenRCT2 interface IUiContext; } + namespace Paint + { + interface Painter; + } + /** * Represents an instance of OpenRCT2 and can be used to get various services. */ @@ -107,6 +112,7 @@ namespace OpenRCT2 virtual IReplayManager* GetReplayManager() abstract; virtual int32_t GetDrawingEngineType() abstract; virtual Drawing::IDrawingEngine* GetDrawingEngine() abstract; + virtual Paint::Painter* GetPainter() abstract; virtual int32_t RunOpenRCT2(int argc, const char** argv) abstract; diff --git a/src/openrct2/paint/Painter.h b/src/openrct2/paint/Painter.h index 4302713867..cb338a0cfd 100644 --- a/src/openrct2/paint/Painter.h +++ b/src/openrct2/paint/Painter.h @@ -30,7 +30,7 @@ namespace OpenRCT2 namespace Paint { - class Painter final + interface Painter final { private: std::shared_ptr const _uiContext; @@ -41,11 +41,11 @@ namespace OpenRCT2 public: explicit Painter(const std::shared_ptr& uiContext); - void Paint(Drawing::IDrawingEngine& de); + void Paint(Drawing::IDrawingEngine & de); private: - void PaintReplayNotice(rct_drawpixelinfo* dpi, const char* text); - void PaintFPS(rct_drawpixelinfo* dpi); + void PaintReplayNotice(rct_drawpixelinfo * dpi, const char* text); + void PaintFPS(rct_drawpixelinfo * dpi); void MeasureFPS(); }; } // namespace Paint From 65ef018e4ebfcd8ce65401bd97332faf28808940 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 19 Feb 2019 16:26:11 +0100 Subject: [PATCH 150/506] Move paint_session_alloc and paint_session_free into Painter. --- .../drawing/engines/opengl/TextureCache.cpp | 10 ++-- .../drawing/engines/opengl/TextureCache.h | 12 ++++- src/openrct2/Context.cpp | 6 +-- src/openrct2/paint/Paint.cpp | 43 +++-------------- src/openrct2/paint/Painter.cpp | 47 +++++++++++++++++++ src/openrct2/paint/Painter.h | 8 +++- 6 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 117b188b0b..8272b1a4ba 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -30,7 +30,7 @@ TextureCache::~TextureCache() void TextureCache::InvalidateImage(uint32_t image) { - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); uint32_t index = _indexMap[image]; if (index == UNUSED_INDEX) @@ -69,7 +69,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) // Try to read cached texture first. { - std::shared_lock lock(_mutex); + shared_lock lock(_mutex); index = _indexMap[image]; if (index != UNUSED_INDEX) @@ -83,7 +83,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) } // Load new texture. - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); index = (uint32_t)_textureCache.size(); @@ -102,7 +102,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa // Try to read cached texture first. { - std::shared_lock lock(_mutex); + shared_lock lock(_mutex); std::copy_n(palette, sizeof(glyphId.Palette), (uint8_t*)&glyphId.Palette); @@ -118,7 +118,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa } // Load new texture. - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); auto cacheInfo = LoadGlyphTexture(image, palette); auto it = _glyphTextureMap.insert(std::make_pair(glyphId, cacheInfo)); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index bd3f8c6b42..c9cebd2e73 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -15,8 +15,11 @@ #include #include #include +#include #include -#include +#ifndef __MACOSX__ +# include +#endif #include #include @@ -199,7 +202,14 @@ private: std::array _indexMap; GLuint _paletteTexture = 0; + +#ifndef __MACOSX__ std::shared_mutex _mutex; + typedef std::shared_lock shared_lock; +#else + std::mutex _mutex; + typedef std::unique_lock shared_lock; +#endif public: TextureCache(); diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index a8770c749f..7a39417afc 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -133,6 +133,7 @@ namespace OpenRCT2 , _audioContext(audioContext) , _uiContext(uiContext) , _localisationService(std::make_unique(env)) + , _painter(std::make_unique(uiContext)) { // Can't have more than one context currently. Guard::Assert(Instance == nullptr); @@ -415,6 +416,7 @@ namespace OpenRCT2 lightfx_init(); #endif } + gScenarioTicks = 0; util_srand((uint32_t)time(nullptr)); input_reset_place_obj_modifier(); @@ -430,7 +432,6 @@ namespace OpenRCT2 void InitialiseDrawingEngine() final override { assert(_drawingEngine == nullptr); - assert(_painter == nullptr); _drawingEngineType = gConfigGeneral.drawing_engine; @@ -457,7 +458,6 @@ namespace OpenRCT2 } else { - _painter = std::make_unique(_uiContext); try { drawingEngine->Initialise(); @@ -466,7 +466,6 @@ namespace OpenRCT2 } catch (const std::exception& ex) { - _painter = nullptr; if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) { _drawingEngineType = DRAWING_ENGINE_NONE; @@ -491,7 +490,6 @@ namespace OpenRCT2 void DisposeDrawingEngine() final override { _drawingEngine = nullptr; - _painter = nullptr; } bool LoadParkFromFile(const std::string& path, bool loadTitleScreenOnFail) final override diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 853c5090d4..477e7a3aa0 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -9,11 +9,13 @@ #include "Paint.h" +#include "../Context.h" #include "../config/Config.h" #include "../drawing/Drawing.h" #include "../interface/Viewport.h" #include "../localisation/Localisation.h" #include "../localisation/LocalisationService.h" +#include "../paint/Painter.h" #include "sprite/Paint.Sprite.h" #include "tile_element/Paint.TileElement.h" @@ -21,6 +23,8 @@ #include #include +using namespace OpenRCT2; + // Globals for paint clipping uint8_t gClipHeight = 128; // Default to middle value LocationXY8 gClipSelectionA = { 0, 0 }; @@ -48,34 +52,12 @@ bool gShowDirtyVisuals; bool gPaintBoundingBoxes; bool gPaintBlockedTiles; -static void paint_session_init(paint_session* session, rct_drawpixelinfo* dpi, uint32_t viewFlags); static void paint_attached_ps(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t viewFlags); static void paint_ps_image_with_bounding_boxes( rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int16_t x, int16_t y); static void paint_ps_image(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int16_t x, int16_t y); static uint32_t paint_ps_colourify_image(uint32_t imageId, uint8_t spriteType, uint32_t viewFlags); -static void paint_session_init(paint_session* session, rct_drawpixelinfo* dpi, uint32_t viewFlags) -{ - session->DPI = *dpi; - session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; - session->NextFreePaintStruct = session->PaintStructs; - session->LastRootPS = nullptr; - session->UnkF1AD2C = nullptr; - session->ViewFlags = viewFlags; - for (auto& quadrant : session->Quadrants) - { - quadrant = nullptr; - } - session->QuadrantBackIndex = std::numeric_limits::max(); - session->QuadrantFrontIndex = 0; - session->PSStringHead = nullptr; - session->LastPSString = nullptr; - session->WoodenSupportsPrependTo = nullptr; - session->CurrentlyDrawnItem = nullptr; - session->SurfaceElement = nullptr; -} - static void paint_session_add_ps_to_quadrant(paint_session* session, paint_struct* ps, int32_t positionHash) { uint32_t paintQuadrantIndex = std::clamp(positionHash / 32, 0, MAX_PAINT_QUADRANTS - 1); @@ -732,25 +714,12 @@ static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo* dpi) paint_session* paint_session_alloc(rct_drawpixelinfo* dpi, uint32_t viewFlags) { - paint_session* session = nullptr; - - if (_freePaintSessions.empty()) - { - session = new paint_session(); - } - else - { - session = _freePaintSessions[_freePaintSessions.size() - 1]; - _freePaintSessions.resize(_freePaintSessions.size() - 1); - } - - paint_session_init(session, dpi, viewFlags); - return session; + return GetContext()->GetPainter()->CreateSession(dpi, viewFlags); } void paint_session_free([[maybe_unused]] paint_session* session) { - _freePaintSessions.push_back(session); + GetContext()->GetPainter()->ReleaseSession(session); } /** diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 888a84190f..e9498eff9e 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -20,6 +20,7 @@ #include "../interface/InteractiveConsole.h" #include "../localisation/FormatCodes.h" #include "../localisation/Language.h" +#include "../paint/Paint.h" #include "../title/TitleScreen.h" #include "../ui/UiContext.h" @@ -140,3 +141,49 @@ void Painter::MeasureFPS() } _lastSecond = currentTime; } + +paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags) +{ + paint_session* session = nullptr; + + if (_freePaintSessions.empty() == false) + { + // Re-use. + const size_t idx = _freePaintSessions.size() - 1; + session = _freePaintSessions[idx]; + + // Shrink by one. + _freePaintSessions.pop_back(); + } + else + { + // Create new one in pool. + _paintSessionPool.emplace_back(std::make_unique()); + session = _paintSessionPool.back().get(); + } + + session->DPI = *dpi; + session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; + session->NextFreePaintStruct = session->PaintStructs; + session->LastRootPS = nullptr; + session->UnkF1AD2C = nullptr; + session->ViewFlags = viewFlags; + for (auto& quadrant : session->Quadrants) + { + quadrant = nullptr; + } + session->QuadrantBackIndex = std::numeric_limits::max(); + session->QuadrantFrontIndex = 0; + session->PSStringHead = nullptr; + session->LastPSString = nullptr; + session->WoodenSupportsPrependTo = nullptr; + session->CurrentlyDrawnItem = nullptr; + session->SurfaceElement = nullptr; + + return session; +} + +void Painter::ReleaseSession(paint_session* session) +{ + _freePaintSessions.push_back(session); +} diff --git a/src/openrct2/paint/Painter.h b/src/openrct2/paint/Painter.h index cb338a0cfd..c2b81e6b4b 100644 --- a/src/openrct2/paint/Painter.h +++ b/src/openrct2/paint/Painter.h @@ -10,9 +10,11 @@ #pragma once #include "../common.h" +#include "Paint.h" #include #include +#include struct rct_drawpixelinfo; @@ -34,7 +36,8 @@ namespace OpenRCT2 { private: std::shared_ptr const _uiContext; - + std::vector> _paintSessionPool; + std::vector _freePaintSessions; time_t _lastSecond = 0; int32_t _currentFPS = 0; int32_t _frames = 0; @@ -43,6 +46,9 @@ namespace OpenRCT2 explicit Painter(const std::shared_ptr& uiContext); void Paint(Drawing::IDrawingEngine & de); + paint_session* CreateSession(rct_drawpixelinfo * dpi, uint32_t viewFlags); + void ReleaseSession(paint_session * session); + private: void PaintReplayNotice(rct_drawpixelinfo * dpi, const char* text); void PaintFPS(rct_drawpixelinfo * dpi); From ce9d252ce51134bc8ce985445ab6fd107f76dcbd Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 27 Feb 2019 10:44:02 +0100 Subject: [PATCH 151/506] Use correct lock. --- src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp | 6 +++--- src/openrct2-ui/drawing/engines/opengl/TextureCache.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 8272b1a4ba..3c9eb8d86c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -30,7 +30,7 @@ TextureCache::~TextureCache() void TextureCache::InvalidateImage(uint32_t image) { - std::unique_lock lock(_mutex); + unique_lock lock(_mutex); uint32_t index = _indexMap[image]; if (index == UNUSED_INDEX) @@ -83,7 +83,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) } // Load new texture. - std::unique_lock lock(_mutex); + unique_lock lock(_mutex); index = (uint32_t)_textureCache.size(); @@ -118,7 +118,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa } // Load new texture. - std::unique_lock lock(_mutex); + unique_lock lock(_mutex); auto cacheInfo = LoadGlyphTexture(image, palette); auto it = _glyphTextureMap.insert(std::make_pair(glyphId, cacheInfo)); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index c9cebd2e73..c8fc9d584c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -206,9 +206,11 @@ private: #ifndef __MACOSX__ std::shared_mutex _mutex; typedef std::shared_lock shared_lock; + typedef std::unique_lock unique_lock; #else std::mutex _mutex; typedef std::unique_lock shared_lock; + typedef std::unique_lock unique_lock; #endif public: From 383ded68e9840e21f8a3d178ea12e74c7f3c3759 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 27 Feb 2019 11:41:51 +0100 Subject: [PATCH 152/506] Cleanup --- src/openrct2/paint/Paint.cpp | 2 -- src/openrct2/paint/Paint.h | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 477e7a3aa0..a8e01cd343 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -30,8 +30,6 @@ uint8_t gClipHeight = 128; // Default to middle value LocationXY8 gClipSelectionA = { 0, 0 }; LocationXY8 gClipSelectionB = { MAXIMUM_MAP_SIZE_TECHNICAL - 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1 }; -static std::vector _freePaintSessions; - static constexpr const uint8_t BoundBoxDebugColours[] = { 0, // NONE 102, // TERRAIN diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 039245c955..6128bc14c1 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -137,12 +137,6 @@ struct tunnel_entry #define MAX_PAINT_QUADRANTS 512 #define TUNNEL_MAX_COUNT 65 -struct paint_pending -{ - rct_drawpixelinfo dpi; - uint32_t viewFlags; -}; - struct paint_session { rct_drawpixelinfo DPI; From e38efcbec470248dd3e189cc393ac79b103a0d56 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 31 Mar 2019 16:24:18 +0200 Subject: [PATCH 153/506] Remove duplicate options in Cheats window --- src/openrct2-ui/windows/Cheats.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index b3d9e75757..6a8f2d6e0f 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -121,8 +121,6 @@ enum WINDOW_CHEATS_WIDGET_IDX WIDX_GENERAL_GROUP = WIDX_TAB_CONTENT, WIDX_OPEN_CLOSE_PARK, WIDX_PARK_PARAMETERS, - WIDX_SANDBOX_MODE, - WIDX_RESET_DATE, WIDX_OWN_ALL_LAND, WIDX_FORCE_PARK_RATING, WIDX_PARK_RATING_SPINNER, @@ -266,8 +264,6 @@ static rct_widget window_cheats_misc_widgets[] = { WWT_GROUPBOX, 1, XPL(0) - GROUP_SPACE, WPL(1) + GROUP_SPACE, YPL(0), HPL(7.25), STR_CHEAT_GENERAL_GROUP, STR_NONE }, // General group { WWT_BUTTON, 1, XPL(0), WPL(0), YPL(1), HPL(1), STR_CHEAT_OPEN_PARK, STR_CHEAT_OPEN_PARK_TIP }, // open / close park { WWT_BUTTON, 1, XPL(1), WPL(1), YPL(1), HPL(1), STR_CHEAT_PARK_PARAMETERS, STR_CHEAT_PARK_PARAMETERS_TIP }, // Park parameters - { WWT_BUTTON, 1, XPL(0), WPL(0), YPL(2), HPL(2), STR_CHEAT_SANDBOX_MODE, STR_CHEAT_SANDBOX_MODE_TIP }, // Sandbox mode (edit land ownership in-game) - { WWT_BUTTON, 1, XPL(1), WPL(1), YPL(2), HPL(2), STR_CHEAT_RESET_DATE, STR_NONE }, // Reset date { WWT_BUTTON, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_CHEAT_OWN_ALL_LAND, STR_CHEAT_OWN_ALL_LAND_TIP }, // Own all land { WWT_CHECKBOX, 1, XPL(0), WPL(0), YPL(5), HPL(5), STR_FORCE_PARK_RATING, STR_NONE }, // Force park rating SPINNER_WIDGETS (1, XPL(1), WPL(1) - 10, YPL(5) + 2, HPL(5) - 3, STR_NONE, STR_NONE), // park rating (3 widgets) @@ -545,8 +541,6 @@ static uint64_t window_cheats_page_enabled_widgets[] = { (1ULL << WIDX_HAVE_FUN) | (1ULL << WIDX_OWN_ALL_LAND) | (1ULL << WIDX_NEVERENDING_MARKETING) | - (1ULL << WIDX_SANDBOX_MODE) | - (1ULL << WIDX_RESET_DATE) | (1ULL << WIDX_STAFF_SPEED) | (1ULL << WIDX_STAFF_SPEED_DROPDOWN_BUTTON) | (1ULL << WIDX_PARK_PARAMETERS) | @@ -975,14 +969,6 @@ static void window_cheats_misc_mouseup(rct_window* w, rct_widgetindex widgetInde game_do_command( 0, GAME_COMMAND_FLAG_APPLY, CHEAT_NEVERENDINGMARKETING, !gCheatsNeverendingMarketing, GAME_COMMAND_CHEAT, 0, 0); break; - case WIDX_SANDBOX_MODE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, !gCheatsSandboxMode, GAME_COMMAND_CHEAT, 0, 0); - // To prevent tools from staying active after disabling cheat - // tool_cancel(); - break; - case WIDX_RESET_DATE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_RESETDATE, 0, GAME_COMMAND_CHEAT, 0, 0); - break; case WIDX_PARK_PARAMETERS: context_open_window(WC_EDITOR_SCENARIO_OPTIONS); break; @@ -1174,7 +1160,6 @@ static void window_cheats_invalidate(rct_window* w) w->widgets[WIDX_OPEN_CLOSE_PARK].text = (gParkFlags & PARK_FLAGS_PARK_OPEN) ? STR_CHEAT_CLOSE_PARK : STR_CHEAT_OPEN_PARK; widget_set_checkbox_value(w, WIDX_FORCE_PARK_RATING, get_forced_park_rating() >= 0); - w->widgets[WIDX_SANDBOX_MODE].text = gCheatsSandboxMode ? STR_CHEAT_SANDBOX_MODE_DISABLE : STR_CHEAT_SANDBOX_MODE; w->widgets[WIDX_FREEZE_WEATHER].text = gCheatsFreezeWeather ? STR_CHEAT_UNFREEZE_WEATHER : STR_CHEAT_FREEZE_WEATHER; widget_set_checkbox_value(w, WIDX_NEVERENDING_MARKETING, gCheatsNeverendingMarketing); widget_set_checkbox_value(w, WIDX_DISABLE_PLANT_AGING, gCheatsDisablePlantAging); From 4b1e7c3dd2d8f7ec9d31757679490f9bc7482536 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 31 Mar 2019 16:01:05 +0200 Subject: [PATCH 154/506] Remove _unk9E32BC from global scope and make it local --- src/openrct2/paint/tile_element/Paint.Entrance.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index edcb400de9..d98643341e 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -23,8 +23,6 @@ #include "../Supports.h" #include "Paint.TileElement.h" -static uint32_t _unk9E32BC; - /** * * rct2: 0x0066508C, 0x00665540 @@ -89,13 +87,13 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, image_id = (colour_1 << 19) | (colour_2 << 24) | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS; session->InteractionType = VIEWPORT_INTERACTION_ITEM_RIDE; - _unk9E32BC = 0; + uint32_t entranceImageId = 0; if (tile_element->IsGhost()) { session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; image_id = CONSTRUCTION_MARKER; - _unk9E32BC = image_id; + entranceImageId = image_id; if (transparant_image_id) transparant_image_id = image_id; } @@ -193,7 +191,7 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, height + stationObj->Height, 2, 2, height + stationObj->Height); } - image_id = _unk9E32BC; + image_id = entranceImageId; if (image_id == 0) { image_id = SPRITE_ID_PALETTE_COLOUR_1(COLOUR_SATURATED_BROWN); @@ -223,13 +221,11 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32 #endif session->InteractionType = VIEWPORT_INTERACTION_ITEM_PARK; - _unk9E32BC = 0; uint32_t image_id, ghost_id = 0; if (tile_element->IsGhost()) { session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; ghost_id = CONSTRUCTION_MARKER; - _unk9E32BC = ghost_id; } // Index to which part of the entrance From 1153b97ace78afe69979d6aa0545486a5b01bb78 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 31 Mar 2019 16:51:55 +0200 Subject: [PATCH 155/506] Use thread_local to protect globals from data race --- src/openrct2/drawing/Drawing.cpp | 8 ++++---- src/openrct2/drawing/Drawing.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 30f9dda4a0..a2caf9e958 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -19,11 +19,11 @@ #include "../world/Water.h" // HACK These were originally passed back through registers -int32_t gLastDrawStringX; -int32_t gLastDrawStringY; +thread_local int32_t gLastDrawStringX; +thread_local int32_t gLastDrawStringY; -int16_t gCurrentFontSpriteBase; -uint16_t gCurrentFontFlags; +thread_local int16_t gCurrentFontSpriteBase; +thread_local uint16_t gCurrentFontFlags; uint8_t gGamePalette[256 * 4]; uint32_t gPaletteEffectFrame; diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index d56404fd90..0e98f3358c 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -237,8 +237,8 @@ struct rct_size16 #define MAX_SCROLLING_TEXT_MODES 38 -extern int16_t gCurrentFontSpriteBase; -extern uint16_t gCurrentFontFlags; +extern thread_local int16_t gCurrentFontSpriteBase; +extern thread_local uint16_t gCurrentFontFlags; extern rct_palette_entry gPalette[256]; extern uint8_t gGamePalette[256 * 4]; @@ -250,8 +250,8 @@ extern uint8_t gOtherPalette[256]; extern uint8_t text_palette[]; extern const translucent_window_palette TranslucentWindowPalettes[COLOUR_COUNT]; -extern int32_t gLastDrawStringX; -extern int32_t gLastDrawStringY; +extern thread_local int32_t gLastDrawStringX; +extern thread_local int32_t gLastDrawStringY; extern uint32_t gPickupPeepImage; extern int32_t gPickupPeepX; From 7ed35dea707080bf3d54a942b1f82f7de85e070a Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 31 Mar 2019 19:00:05 +0200 Subject: [PATCH 156/506] Fix #9000: Show correct error message if not enough money available --- src/openrct2-ui/windows/RideConstruction.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index c7b10b604c..c34145b3e9 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1801,7 +1801,16 @@ static void window_ride_construction_construct(rct_window* w) } auto res = GameActions::Execute(&trackPlaceAction); // Used by some functions - _trackPlaceCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; + if (res->Error != GA_ERROR::OK) + { + gGameCommandErrorText = res->ErrorMessage; + _trackPlaceCost = MONEY32_UNDEFINED; + } + else + { + gGameCommandErrorText = STR_NONE; + _trackPlaceCost = res->Cost; + } if (res->Error != GA_ERROR::OK) { From 03e417550d6f972331df12f5fd3e114b208a3163 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 31 Mar 2019 19:00:37 +0200 Subject: [PATCH 157/506] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 288939cb37..c1c67aaa9a 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -17,6 +17,7 @@ - Fix: [#8909] Potential crash when invoking game actions as server. - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. +- Fix: [#9000] Show correct error message if not enough money available. - Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) From b618bbdcd4f573ee431221c2d41fe7b0139104b8 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 31 Mar 2019 19:48:51 +0200 Subject: [PATCH 158/506] Implement GameAction for setting date --- src/openrct2-ui/windows/Cheats.cpp | 15 +++-- src/openrct2/Cheats.cpp | 6 -- src/openrct2/Cheats.h | 2 - src/openrct2/Game.h | 1 + .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/ParkSetDateAction.hpp | 65 +++++++++++++++++++ src/openrct2/localisation/Date.h | 2 + .../localisation/Localisation.Date.cpp | 2 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkAction.cpp | 1 + 10 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 src/openrct2/actions/ParkSetDateAction.hpp diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 6a8f2d6e0f..4755f98376 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -636,12 +637,12 @@ static void window_cheats_money_mousedown(rct_window* w, rct_widgetindex widgetI break; case WIDX_YEAR_UP: year_spinner_value++; - year_spinner_value = std::clamp(year_spinner_value, 1, 8192); + year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_YEAR_DOWN: year_spinner_value--; - year_spinner_value = std::clamp(year_spinner_value, 1, 8192); + year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_MONTH_UP: @@ -669,16 +670,22 @@ static void window_cheats_money_mousedown(rct_window* w, rct_widgetindex widgetI widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DATE_SET: - date_set(year_spinner_value, month_spinner_value, day_spinner_value); + { + auto setDateAction = ParkSetDateAction(year_spinner_value, month_spinner_value, day_spinner_value); + GameActions::Execute(&setDateAction); window_invalidate_by_class(WC_BOTTOM_TOOLBAR); break; + } case WIDX_DATE_RESET: - date_set(1, 1, 1); + { + auto setDateAction = ParkSetDateAction(1, 1, 1); + GameActions::Execute(&setDateAction); window_invalidate_by_class(WC_BOTTOM_TOOLBAR); widget_invalidate(w, WIDX_YEAR_BOX); widget_invalidate(w, WIDX_MONTH_BOX); widget_invalidate(w, WIDX_DAY_BOX); break; + } } } diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index ba69293988..d1b1025e61 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -632,10 +632,6 @@ void game_command_cheat( } set_forced_park_rating(*edx); break; - case CHEAT_RESETDATE: - date_reset(); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); - break; case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: gCheatsAllowArbitraryRideTypeChanges = *edx != 0; window_invalidate_by_class(WC_RIDE); @@ -975,8 +971,6 @@ const char* cheats_get_cheat_string(int cheat, int edx, int edi) return cheat_string; } - case CHEAT_RESETDATE: - return language_get_string(STR_CHEAT_RESET_DATE); case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: return language_get_string(STR_CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES); case CHEAT_SETMONEY: diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index 9adb950882..b690ba18c1 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -78,13 +78,11 @@ enum CHEAT_HAVEFUN, CHEAT_SETFORCEDPARKRATING, CHEAT_NEVERENDINGMARKETING, - CHEAT_RESETDATE, CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES, CHEAT_OWNALLLAND, CHEAT_DISABLERIDEVALUEAGING, CHEAT_IGNORERESEARCHSTATUS, CHEAT_ENABLEALLDRAWABLETRACKPIECES, - CHEAT_DATE_SET, }; enum diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index b944b2a875..4700b2ecd9 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -97,6 +97,7 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_FOOTPATH_SCENERY, // GA GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA GAME_COMMAND_GUEST_SET_FLAGS, // GA + GAME_COMMAND_SET_DATE, // GA GAME_COMMAND_COUNT, }; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index f13264d1d8..54937b3c56 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -27,6 +27,7 @@ #include "MazeSetTrackAction.hpp" #include "ParkEntranceRemoveAction.hpp" #include "ParkMarketingAction.hpp" +#include "ParkSetDateAction.hpp" #include "ParkSetLoanAction.hpp" #include "ParkSetNameAction.hpp" #include "ParkSetParameterAction.hpp" @@ -127,5 +128,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/ParkSetDateAction.hpp b/src/openrct2/actions/ParkSetDateAction.hpp new file mode 100644 index 0000000000..72d776c7e5 --- /dev/null +++ b/src/openrct2/actions/ParkSetDateAction.hpp @@ -0,0 +1,65 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../core/MemoryStream.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ui/UiContext.h" +#include "../ui/WindowManager.h" +#include "../windows/Intent.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(ParkSetDateAction, GAME_COMMAND_SET_DATE, GameActionResult) +{ +private: + int32_t _year = 0; + int32_t _month = 0; + int32_t _day = 0; + +public: + ParkSetDateAction() + { + } + ParkSetDateAction(int32_t year, int32_t month, int32_t day) + : _year(year) + , _month(month) + , _day(day) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_year) << DS_TAG(_month) << DS_TAG(_day); + } + + GameActionResult::Ptr Query() const override + { + if (_year <= 0 || _year > MAX_YEAR || _month <= 0 || _month > MONTH_COUNT || _day <= 0 || _day > 31) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + date_set(_year, _month, _day); + return MakeResult(); + } +}; diff --git a/src/openrct2/localisation/Date.h b/src/openrct2/localisation/Date.h index 4930c413bd..52eb12a1ed 100644 --- a/src/openrct2/localisation/Date.h +++ b/src/openrct2/localisation/Date.h @@ -12,6 +12,8 @@ #include "../common.h" +constexpr int32_t MAX_YEAR = 8192; + enum { MONTH_MARCH, diff --git a/src/openrct2/localisation/Localisation.Date.cpp b/src/openrct2/localisation/Localisation.Date.cpp index 7df295312d..6507a9afdd 100644 --- a/src/openrct2/localisation/Localisation.Date.cpp +++ b/src/openrct2/localisation/Localisation.Date.cpp @@ -67,7 +67,7 @@ void date_reset() void date_set(int32_t year, int32_t month, int32_t day) { - year = std::clamp(year, 1, 8192); + year = std::clamp(year, 1, MAX_YEAR); month = std::clamp(month, 1, (int)MONTH_COUNT); day = std::clamp(day, 1, (int)days_in_month[month - 1]); gDateMonthsElapsed = (year - 1) * MONTH_COUNT + month - 1; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index f99b9e0019..84da62b965 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 "13" +#define NETWORK_STREAM_VERSION "14" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/network/NetworkAction.cpp b/src/openrct2/network/NetworkAction.cpp index 531be704eb..368b506f96 100644 --- a/src/openrct2/network/NetworkAction.cpp +++ b/src/openrct2/network/NetworkAction.cpp @@ -237,6 +237,7 @@ const std::array NetworkActions::Action "PERMISSION_CHEAT", { GAME_COMMAND_CHEAT, + GAME_COMMAND_SET_DATE, }, }, NetworkAction{ From 2677ad67fc61537259052b80ebcf7646900f59b2 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 31 Mar 2019 19:51:42 +0200 Subject: [PATCH 159/506] Update changelog [ci skip] --- distribution/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 288939cb37..61419b3970 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -11,6 +11,7 @@ - Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. +- Fix: [#8649] Setting date does not work in multiplayer. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). - Fix: [#8900] Peep tracking is not synchronized. @@ -52,6 +53,7 @@ - Fix: [#6191] OpenRCT2 fails to run when the path has an emoji in it. - Fix: [#7439] Placement messages have mixed strings - Fix: [#7473] Disabling sound effects also disables "Disable audio on focus loss". +- Fix: [#7476] Trying to Change Park Name During MP Session Instantly Crashes Host Game. - Fix: [#7536] Android builds fail to start. - Fix: [#7689] Deleting 0-tile maze gives a MONEY32_UNDEFINED (negative) refund. - Fix: [#7828] Copied entrances and exits stay when demolishing ride. From e34e06db4ceb48ff4d0a104e7d299b097ea91365 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 1 Apr 2019 04:00:34 +0000 Subject: [PATCH 160/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 2 +- data/language/da-DK.txt | 1 + data/language/ko-KR.txt | 1 + data/language/nl-NL.txt | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index d45d00f869..ab49468871 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -2433,7 +2433,6 @@ STR_3190 :Doplňky cest STR_3191 :Skupiny kulis STR_3192 :Vstup do parku STR_3193 :Voda -STR_3194 :Popis scénáře STR_3195 :Seznam výzkumů STR_3196 :{WINDOW_COLOUR_2}Skupina výzkumu: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Položky vyzkoumané před začátkem hry: @@ -3772,6 +3771,7 @@ STR_6300 :{SMALLFONT}{BLACK}Stáhnout všechny chybějící objekty dostupné STR_6301 :{SMALLFONT}{BLACK}Kopírovat název vybraného objektu do schránky. STR_6302 :{SMALLFONT}{BLACK}Kopírovat seznam objektů do schránky STR_6303 :Stahování objektu ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Otevřít výběr kulis ############################################################################### ## RCT2 Scenarios diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 62006072f7..6fb08c954b 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3774,6 +3774,7 @@ STR_6300 :{SMALLFONT}{BLACK}Hent alle manglende objekter hvis de er tilgænge STR_6301 :{SMALLFONT}{BLACK}Kopier det valgte objekt til udklipsholder. STR_6302 :{SMALLFONT}{BLACK}Kopier hele listen af manglende objekter til udklipsholderen. STR_6303 :Henter objekt ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Åben scenarie vælger ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 3f6697303f..123aa8036e 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3761,6 +3761,7 @@ STR_6300 :{SMALLFONT}{BLACK}빠진 오브젝트를 온라인에서 다운로 STR_6301 :{SMALLFONT}{BLACK}선택한 오브젝트의 이름을 클립보드에 복사합니다. STR_6302 :{SMALLFONT}{BLACK}빠진 오브젝트의 전체 목록을 클립보드에 복사합니다. STR_6303 :오브젝트 다운로드 중 ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :오브젝트 스포이드 ############# diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index bb0d625519..08736eaa11 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -3766,6 +3766,7 @@ STR_6300 :{SMALLFONT}{BLACK}Download alle ontbrekende objecten, mits ze onlin STR_6301 :{SMALLFONT}{BLACK}Kopieert de naam van het geselecteerde object naar het klembord. STR_6302 :{SMALLFONT}{BLACK}Kopieert de lijst van ontbrekende objecten naar het klembord. STR_6303 :Bezig met downloaden van object ({COMMA16} van {COMMA16}): [{STRING}] +STR_6304 :Decorselector openen ############# # Scenarios # From 9839bb7bba21f19cfbdb43750a39896019cb3e6a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 1 Apr 2019 21:58:57 +0200 Subject: [PATCH 161/506] Fix path preview More work is needed to properly split the paths, but this will do for now. --- src/openrct2-ui/windows/Footpath.cpp | 2 +- src/openrct2/world/Footpath.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index e6c92f9b86..52de8443fb 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -611,7 +611,7 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) } int32_t image = ConstructionPreviewImages[slope][direction]; - int32_t selectedPath = gFootpathSelectedId; + int32_t selectedPath = gFootpathSelectedId + (MAX_PATH_OBJECTS * gFootpathSelectedType); PathSurfaceEntry* pathType = get_path_surface_entry(selectedPath); image += pathType->image; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index df175c8f18..a0dca55acf 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1571,7 +1571,7 @@ PathSurfaceEntry* PathElement::GetPathEntry() const if (!IsQueue()) return get_path_surface_entry(GetPathEntryIndex()); else - return get_path_surface_entry(GetPathEntryIndex() + 32); + return get_path_surface_entry(GetPathEntryIndex() + MAX_PATH_OBJECTS); } PathRailingsEntry* PathElement::GetRailingEntry() const From 29f5018bd1982ee0166bd9e9520f24d768d6aea4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 25 Mar 2019 19:20:31 +0000 Subject: [PATCH 162/506] Implement wall place game action --- src/openrct2-ui/windows/TopToolbar.cpp | 71 +- src/openrct2/Game.cpp | 7 +- src/openrct2/Game.h | 4 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/WallPlaceAction.hpp | 649 ++++++++++++++++++ src/openrct2/rct1/S4Importer.cpp | 10 +- src/openrct2/ride/TrackDesign.cpp | 18 +- src/openrct2/world/Map.h | 4 - src/openrct2/world/Wall.cpp | 553 --------------- 9 files changed, 716 insertions(+), 602 deletions(-) create mode 100644 src/openrct2/actions/WallPlaceAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index a1a02ab3b9..2d18b041df 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -1805,24 +1806,19 @@ 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 >> 8) & 0xFF; + auto edges = parameter_2 & 0xFF; + auto type = (parameter_1 >> 8) & 0xFF; + auto wallPlaceAction = WallPlaceAction( + type, { gridX, gridY, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); - gDisableErrorWindowSound = true; - gGameCommandErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; - int32_t cost = game_do_command( - gridX, flags, gridY, parameter_2, GAME_COMMAND_PLACE_WALL, gSceneryPlaceZ, - _secondaryColour | (_tertiaryColour << 8)); - gDisableErrorWindowSound = false; - - if (cost != MONEY32_UNDEFINED) + auto res = GameActions::Query(&wallPlaceAction); + if (res->Error == GA_ERROR::OK) { - window_close_by_class(WC_ERROR); - audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); - return; + break; } - if (gGameCommandErrorText == STR_NOT_ENOUGH_CASH_REQUIRES - || gGameCommandErrorText == STR_CAN_ONLY_BUILD_THIS_ON_WATER) + if (res->ErrorMessage == STR_NOT_ENOUGH_CASH_REQUIRES || res->ErrorMessage == STR_CAN_ONLY_BUILD_THIS_ON_WATER) { break; } @@ -1830,7 +1826,19 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo gSceneryPlaceZ += 8; } - audio_play_sound_at_location(SOUND_ERROR, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); + auto primaryColour = (parameter_2 >> 8) & 0xFF; + auto edges = parameter_2 & 0xFF; + auto type = (parameter_1 >> 8) & 0xFF; + auto wallPlaceAction = WallPlaceAction( + type, { gridX, gridY, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); + + wallPlaceAction.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); + } + }); + auto res = GameActions::Execute(&wallPlaceAction); break; } case SCENERY_TYPE_LARGE: @@ -2495,24 +2503,33 @@ static money32 try_place_ghost_scenery( break; } case 2: + { // Walls // 6e26b0 - cost = game_do_command( - map_tile.x, parameter_1 | 0x69, map_tile.y, parameter_2, GAME_COMMAND_PLACE_WALL, gSceneryPlaceZ, - _secondaryColour | (_tertiaryColour << 8)); + auto primaryColour = (parameter_2 >> 8) & 0xFF; + auto edges = parameter_2 & 0xFF; + auto type = (parameter_1 >> 8) & 0xFF; + auto wallPlaceAction = WallPlaceAction( + type, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); + wallPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); + wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result){ + if (result->Error != GA_ERROR::OK) + return; - if (cost == MONEY32_UNDEFINED) - return cost; + gSceneryGhostPosition.x = map_tile.x; + gSceneryGhostPosition.y = map_tile.y; + gSceneryGhostWallRotation = edges; + gSceneryGhostPosition.z = gSceneryTileElement->base_height; - gSceneryGhostPosition.x = map_tile.x; - gSceneryGhostPosition.y = map_tile.y; - gSceneryGhostWallRotation = (parameter_2 & 0xFF); + gSceneryGhostType |= SCENERY_GHOST_FLAG_2; + }); - tileElement = gSceneryTileElement; - gSceneryGhostPosition.z = tileElement->base_height; - - gSceneryGhostType |= SCENERY_GHOST_FLAG_2; + auto res = GameActions::Execute(&wallPlaceAction); + if (res->Error != GA_ERROR::OK) + return MONEY32_UNDEFINED; + cost = res->Cost; break; + } case 3: // Large Scenery // 6e25a7 diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 996f430970..bc25685b6a 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -409,7 +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_WALL || command == GAME_COMMAND_PLACE_SCENERY + && (command == GAME_COMMAND_PLACE_SCENERY || command == GAME_COMMAND_PLACE_LARGE_SCENERY || command == GAME_COMMAND_PLACE_BANNER || command == GAME_COMMAND_PLACE_PATH)) { @@ -611,8 +611,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_WALL || command == GAME_COMMAND_PLACE_LARGE_SCENERY + else if (command == GAME_COMMAND_PLACE_LARGE_SCENERY || command == GAME_COMMAND_PLACE_BANNER) { uint8_t flags = *ebx & 0xFF; @@ -1284,7 +1283,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_set_maze_track, game_command_set_park_entrance_fee, nullptr, - game_command_place_wall, + nullptr, nullptr, game_command_place_large_scenery, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 4700b2ecd9..0034c6119a 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -60,8 +60,8 @@ enum GAME_COMMAND GAME_COMMAND_SET_MAZE_TRACK, // GA GAME_COMMAND_SET_PARK_ENTRANCE_FEE, // GA GAME_COMMAND_SET_STAFF_COLOUR, // GA - GAME_COMMAND_PLACE_WALL, - GAME_COMMAND_REMOVE_WALL, // 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 diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 54937b3c56..cda9214e33 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -62,6 +62,7 @@ #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "TrackSetBrakeSpeedAction.hpp" +#include "WallPlaceAction.hpp" #include "WallRemoveAction.hpp" #include "WaterLowerAction.hpp" #include "WaterRaiseAction.hpp" @@ -110,6 +111,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp new file mode 100644 index 0000000000..5a42ddc354 --- /dev/null +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -0,0 +1,649 @@ +/***************************************************************************** + * 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 "../OpenRCT2.h" +#include "../management/Finance.h" +#include "../ride/RideGroupManager.h" +#include "../ride/Track.h" +#include "../ride/TrackData.h" +#include "../world/Banner.h" +#include "../world/LargeScenery.h" +#include "../world/MapAnimation.h" +#include "../world/Scenery.h" +#include "../world/SmallScenery.h" +#include "../world/Surface.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(WallPlaceAction, GAME_COMMAND_PLACE_WALL, GameActionResult) +{ +private: + int32_t _wallType; + CoordsXYZ _loc; + uint8_t _edge; + int32_t _primaryColour; + int32_t _secondaryColour; + int32_t _tertiaryColour; + +public: + WallPlaceAction() + { + } + + WallPlaceAction( + int32_t wallType, CoordsXYZ loc, uint8_t edge, int32_t primaryColour, int32_t secondaryColour, int32_t tertiaryColour) + : _wallType(wallType) + , _loc(loc) + , _edge(edge) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + , _tertiaryColour(tertiaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_wallType) << DS_TAG(_loc) << DS_TAG(_edge) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour) + << DS_TAG(_tertiaryColour); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; + res->Position = _loc; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x += 16; + res->Position.y += 16; + + if (res->Position.z == 0) + { + res->Position.z = tile_element_height(res->Position.x, res->Position.y) & 0xFFFF; + } + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(GetFlags() & GAME_COMMAND_FLAG_PATH_SCENERY) + && !gCheatsSandboxMode) + { + if (_loc.z == 0) + { + if (!map_is_location_in_park({ _loc.x, _loc.y })) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + } + else if (!map_is_location_owned(_loc.x, _loc.y, _loc.z)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + } + + uint8_t edgeSlope = 0; + auto targetHeight = _loc.z; + if (targetHeight == 0) + { + TileElement* surfaceElement = map_get_surface_element_at({ _loc.x, _loc.y }); + if (surfaceElement == nullptr) + { + log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + targetHeight = surfaceElement->base_height * 8; + + uint8_t slope = surfaceElement->AsSurface()->GetSlope(); + edgeSlope = EdgeSlopes[slope][_edge & 3]; + if (edgeSlope & EDGE_SLOPE_ELEVATED) + { + targetHeight += 16; + edgeSlope &= ~EDGE_SLOPE_ELEVATED; + } + } + + TileElement* surfaceElement = map_get_surface_element_at({ _loc.x, _loc.y }); + if (surfaceElement == nullptr) + { + log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + if (surfaceElement->AsSurface()->GetWaterHeight() > 0) + { + uint16_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight() * 16; + + if (targetHeight < waterHeight && !gCheatsDisableClearanceChecks) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + } + } + + if (targetHeight / 8 < surfaceElement->base_height && !gCheatsDisableClearanceChecks) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + } + + if (!(edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS))) + { + uint8_t newEdge = (_edge + 2) & 3; + uint8_t newBaseHeight = surfaceElement->base_height; + newBaseHeight += 2; + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + if (targetHeight / 8 < newBaseHeight) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + } + + if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) + { + newEdge = (newEdge - 1) & 3; + + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + newEdge = (newEdge + 2) & 3; + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + newBaseHeight += 2; + if (targetHeight / 8 < newBaseHeight) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, + STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + } + newBaseHeight -= 2; + } + } + } + } + + newEdge = (_edge + 3) & 3; + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + if (targetHeight / 8 < newBaseHeight) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + } + + if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) + { + newEdge = (newEdge - 1) & 3; + + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + newEdge = (newEdge + 2) & 3; + if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) + { + newBaseHeight += 2; + if (targetHeight / 8 < newBaseHeight) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, + STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + } + } + } + } + } + } + + rct_scenery_entry* wallEntry = get_wall_entry(_wallType); + + if (wallEntry == nullptr) + { + log_error("Wall Type not found %d", _wallType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) + { + auto bannerIndex = create_new_banner(0); + + if (bannerIndex == 0xFF) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + } + } + + uint8_t clearanceHeight = targetHeight / 8; + if (edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS)) + { + if (wallEntry->wall.flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE); + } + clearanceHeight += 2; + } + clearanceHeight += wallEntry->wall.height; + + bool wallAcrossTrack = false; + if (!(GetFlags() & GAME_COMMAND_FLAG_PATH_SCENERY) && !gCheatsDisableClearanceChecks) + { + if (!WallCheckObstruction(wallEntry, targetHeight / 8, clearanceHeight, &wallAcrossTrack)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText, gCommonFormatArgs); + } + } + + if (!map_check_free_elements_and_reorganise(1)) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText); + } + + res->Cost = wallEntry->wall.price; + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; + res->Position = _loc; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x += 16; + res->Position.y += 16; + + if (res->Position.z == 0) + { + res->Position.z = tile_element_height(res->Position.x, res->Position.y) & 0xFFFF; + } + + uint8_t edgeSlope = 0; + auto targetHeight = _loc.z; + if (targetHeight == 0) + { + TileElement* surfaceElement = map_get_surface_element_at({ _loc.x, _loc.y }); + if (surfaceElement == nullptr) + { + log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + targetHeight = surfaceElement->base_height * 8; + + uint8_t slope = surfaceElement->AsSurface()->GetSlope(); + edgeSlope = EdgeSlopes[slope][_edge & 3]; + if (edgeSlope & EDGE_SLOPE_ELEVATED) + { + targetHeight += 16; + edgeSlope &= ~EDGE_SLOPE_ELEVATED; + } + } + + BannerIndex bannerIndex = BANNER_INDEX_NULL; + rct_scenery_entry* wallEntry = get_wall_entry(_wallType); + + if (wallEntry == nullptr) + { + log_error("Wall Type not found %d", _wallType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) + { + bannerIndex = create_new_banner(GAME_COMMAND_FLAG_APPLY); + + if (bannerIndex == 0xFF) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + } + + rct_banner* banner = &gBanners[bannerIndex]; + banner->flags |= BANNER_FLAG_IS_WALL; + 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, targetHeight); + if (rideIndex != RIDE_ID_NULL) + { + banner->ride_index = rideIndex; + banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; + } + } + + uint8_t clearanceHeight = targetHeight / 8; + if (edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS)) + { + clearanceHeight += 2; + } + clearanceHeight += wallEntry->wall.height; + + bool wallAcrossTrack = false; + if (!(GetFlags() & GAME_COMMAND_FLAG_PATH_SCENERY) && !gCheatsDisableClearanceChecks) + { + if (!WallCheckObstruction(wallEntry, targetHeight / 8, clearanceHeight, &wallAcrossTrack)) + { + return MakeResult( + GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText, gCommonFormatArgs); + } + } + + if (!map_check_free_elements_and_reorganise(1)) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText); + } + + TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, targetHeight / 8, 0); + assert(tileElement != nullptr); + + map_animation_create(MAP_ANIMATION_TYPE_WALL, _loc.x, _loc.y, targetHeight / 8); + + tileElement->SetType(TILE_ELEMENT_TYPE_WALL); + WallElement* wallElement = tileElement->AsWall(); + wallElement->clearance_height = clearanceHeight; + wallElement->SetDirection(_edge); + // TODO: Normalise the edge slope code. + wallElement->SetSlope(edgeSlope >> 6); + + wallElement->SetPrimaryColour(_primaryColour); + wallElement->SetSecondaryColour(_secondaryColour); + + if (wallAcrossTrack) + { + wallElement->SetAcrossTrack(true); + } + + wallElement->SetEntryIndex(_wallType); + if (bannerIndex != 0xFF) + { + wallElement->SetBannerIndex(bannerIndex); + } + + if (wallEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) + { + wallElement->SetTertiaryColour(_tertiaryColour); + } + + if (GetFlags() & GAME_COMMAND_FLAG_GHOST) + { + wallElement->SetGhost(true); + } + + gSceneryTileElement = tileElement; + map_invalidate_tile_zoom1(_loc.x, _loc.y, wallElement->base_height * 8, wallElement->base_height * 8 + 72); + + res->Cost = wallEntry->wall.price; + return res; + } + +private: +#pragma region Edge Slopes Table + + // clang-format off + enum EDGE_SLOPE + { + EDGE_SLOPE_ELEVATED = (1 << 0), // 0x01 + EDGE_SLOPE_UPWARDS = (1 << 6), // 0x40 + EDGE_SLOPE_DOWNWARDS = (1 << 7), // 0x80 + + EDGE_SLOPE_UPWARDS_ELEVATED = EDGE_SLOPE_UPWARDS | EDGE_SLOPE_ELEVATED, + EDGE_SLOPE_DOWNWARDS_ELEVATED = EDGE_SLOPE_DOWNWARDS | EDGE_SLOPE_ELEVATED, + }; + + /** rct2: 0x009A3FEC */ + static constexpr const uint8_t EdgeSlopes[][4] = { + // Top right Bottom right Bottom left Top left + { 0, 0, 0, 0 }, + { 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, 0 }, + { 0, 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS }, + { 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS }, + { EDGE_SLOPE_DOWNWARDS, 0, 0, EDGE_SLOPE_UPWARDS }, + { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, + { EDGE_SLOPE_DOWNWARDS, 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED }, + { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED }, + { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, 0, 0 }, + { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, 0 }, + { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS }, + { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS }, + { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, 0, EDGE_SLOPE_UPWARDS }, + { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, + { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED }, + { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS }, + { 0, 0, 0, 0 }, + { EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, + { EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED }, + { 0, 0, 0, 0 }, + }; + // clang-format on + +#pragma endregion + + /** + * + * rct2: 0x006E5CBA + */ + bool WallCheckObstructionWithTrack(rct_scenery_entry * wall, int32_t z0, TrackElement * trackElement, bool* wallAcrossTrack) + const + { + int32_t trackType = trackElement->GetTrackType(); + int32_t sequence = trackElement->GetSequenceIndex(); + int32_t direction = (_edge - trackElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK; + Ride* ride = get_ride(trackElement->GetRideIndex()); + + if (TrackIsAllowedWallEdges(ride->type, trackType, sequence, direction)) + { + return true; + } + + if (!(wall->wall.flags & WALL_SCENERY_IS_DOOR)) + { + return false; + } + + if (RideGroupManager::RideTypeHasRideGroups(ride->type)) + { + auto rideGroup = RideGroupManager::GetRideGroup(ride->type, get_ride_entry(ride->subtype)); + if (!(rideGroup->Flags & RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK)) + { + return false; + } + } + else if (!(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_DOORS_ON_TRACK)) + { + return false; + } + + *wallAcrossTrack = true; + if (z0 & 1) + { + return false; + } + + int32_t z; + if (sequence == 0) + { + if (TrackSequenceProperties[trackType][0] & TRACK_SEQUENCE_FLAG_DISALLOW_DOORS) + { + return false; + } + + if (TrackDefinitions[trackType].bank_start == 0) + { + if (!(TrackCoordinates[trackType].rotation_begin & 4)) + { + direction = trackElement->GetDirectionWithOffset(2); + if (direction == _edge) + { + const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence]; + z = TrackCoordinates[trackType].z_begin; + z = trackElement->base_height + ((z - trackBlock->z) * 8); + if (z == z0) + { + return true; + } + } + } + } + } + + const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence + 1]; + if (trackBlock->index != 0xFF) + { + return false; + } + + if (TrackDefinitions[trackType].bank_end != 0) + { + return false; + } + + direction = TrackCoordinates[trackType].rotation_end; + if (direction & 4) + { + return false; + } + + direction = trackElement->GetDirection(); + if (direction != _edge) + { + return false; + } + + trackBlock = &TrackBlocks[trackType][sequence]; + z = TrackCoordinates[trackType].z_end; + z = trackElement->base_height + ((z - trackBlock->z) * 8); + return z == z0; + } + + /** + * + * rct2: 0x006E5C1A + */ + bool WallCheckObstruction(rct_scenery_entry * wall, int32_t z0, int32_t z1, bool* wallAcrossTrack) const + { + int32_t entryType, sequence; + rct_scenery_entry* entry; + rct_large_scenery_tile* tile; + + *wallAcrossTrack = false; + gMapGroundFlags = ELEMENT_IS_ABOVE_GROUND; + if (map_is_location_at_edge(_loc.x, _loc.y)) + { + gGameCommandErrorText = STR_OFF_EDGE_OF_MAP; + return false; + } + + TileElement* tileElement = map_get_first_element_at(_loc.x / 32, _loc.y / 32); + do + { + int32_t elementType = tileElement->GetType(); + if (elementType == TILE_ELEMENT_TYPE_SURFACE) + continue; + if (z0 >= tileElement->clearance_height) + continue; + if (z1 <= tileElement->base_height) + continue; + if (elementType == TILE_ELEMENT_TYPE_WALL) + { + int32_t direction = tileElement->GetDirection(); + if (_edge == direction) + { + map_obstruction_set_error_text(tileElement); + return false; + } + continue; + } + if ((tileElement->flags & 0x0F) == 0) + continue; + + switch (elementType) + { + case TILE_ELEMENT_TYPE_ENTRANCE: + map_obstruction_set_error_text(tileElement); + return false; + case TILE_ELEMENT_TYPE_PATH: + if (tileElement->AsPath()->GetEdges() & (1 << _edge)) + { + map_obstruction_set_error_text(tileElement); + return false; + } + break; + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + entryType = tileElement->AsLargeScenery()->GetEntryIndex(); + sequence = tileElement->AsLargeScenery()->GetSequenceIndex(); + entry = get_large_scenery_entry(entryType); + tile = &entry->large_scenery.tiles[sequence]; + { + int32_t direction = ((_edge - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK) + 8; + if (!(tile->flags & (1 << direction))) + { + map_obstruction_set_error_text(tileElement); + return false; + } + } + break; + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + entry = tileElement->AsSmallScenery()->GetEntry(); + if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_NO_WALLS)) + { + map_obstruction_set_error_text(tileElement); + return false; + } + break; + case TILE_ELEMENT_TYPE_TRACK: + if (!WallCheckObstructionWithTrack(wall, z0, tileElement->AsTrack(), wallAcrossTrack)) + { + return false; + } + break; + } + } while (!(tileElement++)->IsLastForTile()); + + return true; + } + + /** + * Gets whether the given track type can have a wall placed on the edge of the given direction. + * Some thin tracks for example are allowed to have walls either side of the track, but wider tracks can not. + */ + static bool TrackIsAllowedWallEdges(uint8_t rideType, uint8_t trackType, uint8_t trackSequence, uint8_t direction) + { + if (!ride_type_has_flag(rideType, RIDE_TYPE_FLAG_TRACK_NO_WALLS)) + { + if (ride_type_has_flag(rideType, RIDE_TYPE_FLAG_FLAT_RIDE)) + { + if (FlatRideTrackSequenceElementAllowedWallEdges[trackType][trackSequence] & (1 << direction)) + { + return true; + } + } + else + { + if (TrackSequenceElementAllowedWallEdges[trackType][trackSequence] & (1 << direction)) + { + return true; + } + } + } + return false; + } +}; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 84cf8d0073..af6cf9d4c8 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -13,6 +13,7 @@ #include "../Game.h" #include "../GameState.h" #include "../ParkImporter.h" +#include "../actions/WallPlaceAction.hpp" #include "../audio/audio.h" #include "../core/Collections.hpp" #include "../core/Console.hpp" @@ -2773,10 +2774,13 @@ private: ConvertWall(&type, &colourA, &colourB); type = _wallTypeToEntryMap[type]; - const uint8_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_PATH_SCENERY; - wall_place(type, x * 32, y * 32, 0, edge, colourA, colourB, colourC, flags); + auto wallPlaceAction = WallPlaceAction( + type, { x * 32, y * 32, 0 }, edge, colourA, colourB, colourC); + wallPlaceAction.SetFlags( + GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + | GAME_COMMAND_FLAG_PATH_SCENERY); + GameActions::Execute(&wallPlaceAction); } } break; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index ba3d69aa1f..59229bc8be 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -21,6 +21,7 @@ #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/TrackPlaceAction.hpp" #include "../actions/TrackRemoveAction.hpp" +#include "../actions/WallPlaceAction.hpp" #include "../actions/WallRemoveAction.hpp" #include "../audio/audio.h" #include "../core/File.h" @@ -1021,6 +1022,7 @@ static int32_t track_design_place_scenery( } break; case OBJECT_TYPE_WALLS: + { if (mode != 0) { continue; @@ -1050,17 +1052,15 @@ static int32_t track_design_place_scenery( flags = 0; } - gGameCommandErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; + auto wallPlaceAction = WallPlaceAction( + entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, + scenery->secondary_colour, scenery->flags & 0xFC); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction) + : GameActions::Query(&wallPlaceAction); - cost = game_do_command( - mapCoord.x, flags | (entry_index << 8), mapCoord.y, rotation | (scenery->primary_colour << 8), - GAME_COMMAND_PLACE_WALL, z, scenery->secondary_colour | ((scenery->flags & 0xFC) << 6)); - - if (cost == MONEY32_UNDEFINED) - { - cost = 0; - } + cost = res->Cost; break; + } case OBJECT_TYPE_PATHS: if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) { diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 64660ef626..3328e74d56 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -186,9 +186,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); money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t clear, int32_t flags); -money32 wall_place( - int32_t type, int32_t x, int32_t y, int32_t z, int32_t edge, int32_t primaryColour, int32_t secondaryColour, - int32_t tertiaryColour, int32_t flags); void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); @@ -204,7 +201,6 @@ void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_place_wall(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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( diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 230e1ddebd..137c26ca9e 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -29,532 +29,6 @@ #include "Surface.h" #include "Wall.h" -/** - * Gets whether the given track type can have a wall placed on the edge of the given direction. - * Some thin tracks for example are allowed to have walls either side of the track, but wider tracks can not. - */ -static bool TrackIsAllowedWallEdges(uint8_t rideType, uint8_t trackType, uint8_t trackSequence, uint8_t direction) -{ - if (!ride_type_has_flag(rideType, RIDE_TYPE_FLAG_TRACK_NO_WALLS)) - { - if (ride_type_has_flag(rideType, RIDE_TYPE_FLAG_FLAT_RIDE)) - { - if (FlatRideTrackSequenceElementAllowedWallEdges[trackType][trackSequence] & (1 << direction)) - { - return true; - } - } - else - { - if (TrackSequenceElementAllowedWallEdges[trackType][trackSequence] & (1 << direction)) - { - return true; - } - } - } - return false; -} - -/** - * - * rct2: 0x006E5CBA - */ -static bool WallCheckObstructionWithTrack( - rct_scenery_entry* wall, int32_t z0, int32_t edge, TileElement* trackElement, bool* wallAcrossTrack) -{ - int32_t trackType = trackElement->AsTrack()->GetTrackType(); - int32_t sequence = trackElement->AsTrack()->GetSequenceIndex(); - int32_t direction = (edge - trackElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK; - Ride* ride = get_ride(trackElement->AsTrack()->GetRideIndex()); - - if (TrackIsAllowedWallEdges(ride->type, trackType, sequence, direction)) - { - return true; - } - - if (!(wall->wall.flags & WALL_SCENERY_IS_DOOR)) - { - return false; - } - - if (RideGroupManager::RideTypeHasRideGroups(ride->type)) - { - auto rideGroup = RideGroupManager::GetRideGroup(ride->type, get_ride_entry(ride->subtype)); - if (!(rideGroup->Flags & RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK)) - { - return false; - } - } - else if (!(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_DOORS_ON_TRACK)) - { - return false; - } - - *wallAcrossTrack = true; - if (z0 & 1) - { - return false; - } - - int32_t z; - if (sequence == 0) - { - if (TrackSequenceProperties[trackType][0] & TRACK_SEQUENCE_FLAG_DISALLOW_DOORS) - { - return false; - } - - if (TrackDefinitions[trackType].bank_start == 0) - { - if (!(TrackCoordinates[trackType].rotation_begin & 4)) - { - direction = trackElement->GetDirectionWithOffset(2); - if (direction == edge) - { - const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence]; - z = TrackCoordinates[trackType].z_begin; - z = trackElement->base_height + ((z - trackBlock->z) * 8); - if (z == z0) - { - return true; - } - } - } - } - } - - const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence + 1]; - if (trackBlock->index != 0xFF) - { - return false; - } - - if (TrackDefinitions[trackType].bank_end != 0) - { - return false; - } - - direction = TrackCoordinates[trackType].rotation_end; - if (direction & 4) - { - return false; - } - - direction = trackElement->GetDirection(); - if (direction != edge) - { - return false; - } - - trackBlock = &TrackBlocks[trackType][sequence]; - z = TrackCoordinates[trackType].z_end; - z = trackElement->base_height + ((z - trackBlock->z) * 8); - return z == z0; -} - -/** - * - * rct2: 0x006E5C1A - */ -static bool WallCheckObstruction( - rct_scenery_entry* wall, int32_t x, int32_t y, int32_t z0, int32_t z1, int32_t edge, bool* wallAcrossTrack) -{ - int32_t entryType, sequence; - rct_scenery_entry* entry; - rct_large_scenery_tile* tile; - - *wallAcrossTrack = false; - gMapGroundFlags = ELEMENT_IS_ABOVE_GROUND; - if (map_is_location_at_edge(x, y)) - { - gGameCommandErrorText = STR_OFF_EDGE_OF_MAP; - return false; - } - - TileElement* tileElement = map_get_first_element_at(x / 32, y / 32); - do - { - int32_t elementType = tileElement->GetType(); - if (elementType == TILE_ELEMENT_TYPE_SURFACE) - continue; - if (z0 >= tileElement->clearance_height) - continue; - if (z1 <= tileElement->base_height) - continue; - if (elementType == TILE_ELEMENT_TYPE_WALL) - { - int32_t direction = tileElement->GetDirection(); - if (edge == direction) - { - map_obstruction_set_error_text(tileElement); - return false; - } - continue; - } - if ((tileElement->flags & 0x0F) == 0) - continue; - - switch (elementType) - { - case TILE_ELEMENT_TYPE_ENTRANCE: - map_obstruction_set_error_text(tileElement); - return false; - case TILE_ELEMENT_TYPE_PATH: - if (tileElement->AsPath()->GetEdges() & (1 << edge)) - { - map_obstruction_set_error_text(tileElement); - return false; - } - break; - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - entryType = tileElement->AsLargeScenery()->GetEntryIndex(); - sequence = tileElement->AsLargeScenery()->GetSequenceIndex(); - entry = get_large_scenery_entry(entryType); - tile = &entry->large_scenery.tiles[sequence]; - { - int32_t direction = ((edge - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK) + 8; - if (!(tile->flags & (1 << direction))) - { - map_obstruction_set_error_text(tileElement); - return false; - } - } - break; - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - entry = tileElement->AsSmallScenery()->GetEntry(); - if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_NO_WALLS)) - { - map_obstruction_set_error_text(tileElement); - return false; - } - break; - case TILE_ELEMENT_TYPE_TRACK: - if (!WallCheckObstructionWithTrack(wall, z0, edge, tileElement, wallAcrossTrack)) - { - return false; - } - break; - } - } while (!(tileElement++)->IsLastForTile()); - - return true; -} - -#pragma region Edge Slopes Table - -// clang-format off -enum EDGE_SLOPE -{ - EDGE_SLOPE_ELEVATED = (1 << 0), // 0x01 - EDGE_SLOPE_UPWARDS = (1 << 6), // 0x40 - EDGE_SLOPE_DOWNWARDS = (1 << 7), // 0x80 - - EDGE_SLOPE_UPWARDS_ELEVATED = EDGE_SLOPE_UPWARDS | EDGE_SLOPE_ELEVATED, - EDGE_SLOPE_DOWNWARDS_ELEVATED = EDGE_SLOPE_DOWNWARDS | EDGE_SLOPE_ELEVATED, -}; - -/** rct2: 0x009A3FEC */ -static constexpr const uint8_t EdgeSlopes[][4] = { -// Top right Bottom right Bottom left Top left - { 0, 0, 0, 0 }, - { 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, 0 }, - { 0, 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS }, - { 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS }, - { EDGE_SLOPE_DOWNWARDS, 0, 0, EDGE_SLOPE_UPWARDS }, - { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, - { EDGE_SLOPE_DOWNWARDS, 0, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED }, - { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED }, - { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, 0, 0 }, - { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, 0 }, - { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_DOWNWARDS }, - { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS }, - { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, 0, EDGE_SLOPE_UPWARDS }, - { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, - { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_ELEVATED }, - { EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED, EDGE_SLOPE_ELEVATED }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS }, - { 0, 0, 0, 0 }, - { EDGE_SLOPE_UPWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS }, - { EDGE_SLOPE_DOWNWARDS_ELEVATED, EDGE_SLOPE_DOWNWARDS, EDGE_SLOPE_UPWARDS, EDGE_SLOPE_UPWARDS_ELEVATED }, - { 0, 0, 0, 0 }, -}; -// clang-format on - -#pragma endregion - -static money32 WallPlace( - uint8_t wallType, int16_t x, int16_t y, int16_t z, uint8_t edge, uint8_t primaryColour, uint8_t secondaryColour, - uint8_t tertiaryColour, uint8_t flags) -{ - LocationXYZ16 position = { x, y, z }; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = position.x + 16; - gCommandPosition.y = position.y + 16; - gCommandPosition.z = position.z; - - if (position.z == 0) - { - gCommandPosition.z = tile_element_height(position.x, position.y) & 0xFFFF; - } - - if (game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - return MONEY32_UNDEFINED; - } - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(flags & GAME_COMMAND_FLAG_PATH_SCENERY) && !gCheatsSandboxMode) - { - if (position.z == 0) - { - if (!map_is_location_in_park({ position.x, position.y })) - { - return MONEY32_UNDEFINED; - } - } - else if (!map_is_location_owned(position.x, position.y, position.z)) - { - return MONEY32_UNDEFINED; - } - } - - uint8_t edgeSlope = 0; - if (position.z == 0) - { - TileElement* surfaceElement = map_get_surface_element_at({ position.x, position.y }); - if (surfaceElement == nullptr) - { - return MONEY32_UNDEFINED; - } - position.z = surfaceElement->base_height * 8; - - uint8_t slope = surfaceElement->AsSurface()->GetSlope(); - edgeSlope = EdgeSlopes[slope][edge & 3]; - if (edgeSlope & EDGE_SLOPE_ELEVATED) - { - position.z += 16; - edgeSlope &= ~EDGE_SLOPE_ELEVATED; - } - } - - TileElement* surfaceElement = map_get_surface_element_at({ position.x, position.y }); - if (surfaceElement == nullptr) - { - return MONEY32_UNDEFINED; - } - - if (surfaceElement->AsSurface()->GetWaterHeight() > 0) - { - uint16_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight() * 16; - - if (position.z < waterHeight && !gCheatsDisableClearanceChecks) - { - gGameCommandErrorText = STR_CANT_BUILD_THIS_UNDERWATER; - return MONEY32_UNDEFINED; - } - } - - if (position.z / 8 < surfaceElement->base_height && !gCheatsDisableClearanceChecks) - { - gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND; - return MONEY32_UNDEFINED; - } - - if (!(edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS))) - { - uint8_t newEdge = (edge + 2) & 3; - uint8_t newBaseHeight = surfaceElement->base_height; - newBaseHeight += 2; - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - if (position.z / 8 < newBaseHeight) - { - gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND; - return MONEY32_UNDEFINED; - } - - if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) - { - newEdge = (newEdge - 1) & 3; - - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - newEdge = (newEdge + 2) & 3; - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - newBaseHeight += 2; - if (position.z / 8 < newBaseHeight) - { - gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND; - return MONEY32_UNDEFINED; - } - newBaseHeight -= 2; - } - } - } - } - - newEdge = (edge + 3) & 3; - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - if (position.z / 8 < newBaseHeight) - { - gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND; - return MONEY32_UNDEFINED; - } - - if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) - { - newEdge = (newEdge - 1) & 3; - - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - newEdge = (newEdge + 2) & 3; - if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge)) - { - newBaseHeight += 2; - if (position.z / 8 < newBaseHeight) - { - gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND; - return MONEY32_UNDEFINED; - } - } - } - } - } - } - BannerIndex bannerIndex = BANNER_INDEX_NULL; - rct_scenery_entry* wallEntry = get_wall_entry(wallType); - - if (wallEntry == nullptr) - { - return MONEY32_UNDEFINED; - } - - if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) - { - bannerIndex = create_new_banner(flags); - - if (bannerIndex == 0xFF) - { - return MONEY32_UNDEFINED; - } - - rct_banner* banner = &gBanners[bannerIndex]; - if (flags & GAME_COMMAND_FLAG_APPLY) - { - banner->flags |= BANNER_FLAG_IS_WALL; - banner->type = 0; - banner->x = position.x / 32; - banner->y = position.y / 32; - - ride_id_t rideIndex = banner_get_closest_ride_index(position.x, position.y, position.z); - if (rideIndex != RIDE_ID_NULL) - { - banner->ride_index = rideIndex; - banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; - } - } - } - - uint8_t clearanceHeight = position.z / 8; - if (edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS)) - { - if (wallEntry->wall.flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE) - { - gGameCommandErrorText = STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE; - return MONEY32_UNDEFINED; - } - clearanceHeight += 2; - } - clearanceHeight += wallEntry->wall.height; - - bool wallAcrossTrack = false; - if (!(flags & GAME_COMMAND_FLAG_PATH_SCENERY) && !gCheatsDisableClearanceChecks) - { - if (!WallCheckObstruction(wallEntry, position.x, position.y, position.z / 8, clearanceHeight, edge, &wallAcrossTrack)) - { - return MONEY32_UNDEFINED; - } - } - - if (!map_check_free_elements_and_reorganise(1)) - { - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) - { - LocationXYZ16 coord; - coord.x = position.x + 16; - coord.y = position.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* tileElement = tile_element_insert(position.x / 32, position.y / 32, position.z / 8, 0); - assert(tileElement != nullptr); - - map_animation_create(MAP_ANIMATION_TYPE_WALL, position.x, position.y, position.z / 8); - - tileElement->clearance_height = clearanceHeight; - tileElement->SetType(TILE_ELEMENT_TYPE_WALL); - tileElement->SetDirection(edge); - // TODO: Normalise the edge slope code. - tileElement->AsWall()->SetSlope(edgeSlope >> 6); - - tileElement->AsWall()->SetPrimaryColour(primaryColour); - tileElement->AsWall()->SetSecondaryColour(secondaryColour); - - if (wallAcrossTrack) - { - tileElement->AsWall()->SetAcrossTrack(true); - } - - tileElement->AsWall()->SetEntryIndex(wallType); - if (bannerIndex != 0xFF) - { - tileElement->AsWall()->SetBannerIndex(bannerIndex); - } - - if (wallEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) - { - tileElement->AsWall()->SetTertiaryColour(tertiaryColour); - } - - if (flags & GAME_COMMAND_FLAG_GHOST) - { - tileElement->SetGhost(true); - } - - gSceneryTileElement = tileElement; - map_invalidate_tile_zoom1(position.x, position.y, tileElement->base_height * 8, tileElement->base_height * 8 + 72); - } - - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - return 0; - } - else - { - return wallEntry->wall.price; - } -} - static money32 WallSetColour( int16_t x, int16_t y, uint8_t baseHeight, uint8_t direction, uint8_t primaryColour, uint8_t secondaryColour, uint8_t tertiaryColour, uint8_t flags) @@ -662,33 +136,6 @@ void wall_remove_intersecting_walls(int32_t x, int32_t y, int32_t z0, int32_t z1 } while (!(tileElement++)->IsLastForTile()); } -/** - * - * rct2: 0x006E519A - */ -void game_command_place_wall( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - *ebx = WallPlace( - (*ebx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edi & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebp & 0xFF, - (*ebp >> 8) & 0xFF, *ebx & 0xFF); -} - -money32 wall_place( - int32_t type, int32_t x, int32_t y, int32_t z, int32_t edge, int32_t primaryColour, int32_t secondaryColour, - int32_t tertiaryColour, int32_t flags) -{ - int32_t eax = x; - int32_t ebx = flags | (type << 8); - int32_t ecx = y; - int32_t edx = edge | (primaryColour << 8); - int32_t esi = 0; - int32_t edi = z; - int32_t ebp = secondaryColour | (tertiaryColour << 8); - game_command_place_wall(&eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return ebx; -} - /** * * rct2: 0x006E56B5 From 7e6254f30c4e387b207e761fc5b2a0971445025a Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 28 Mar 2019 17:45:39 +0000 Subject: [PATCH 163/506] Fix function. --- src/openrct2-ui/windows/TopToolbar.cpp | 10 +++++++--- src/openrct2/Game.cpp | 8 +++----- src/openrct2/actions/WallPlaceAction.hpp | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 2d18b041df..b1c8fddf82 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1823,7 +1823,10 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo break; } - gSceneryPlaceZ += 8; + if (zAttemptRange != 1) + { + gSceneryPlaceZ += 8; + } } auto primaryColour = (parameter_2 >> 8) & 0xFF; @@ -2511,8 +2514,9 @@ static money32 try_place_ghost_scenery( auto type = (parameter_1 >> 8) & 0xFF; auto wallPlaceAction = WallPlaceAction( type, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); - wallPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); - wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result){ + wallPlaceAction.SetFlags( + GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_PATH_SCENERY); + wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { if (result->Error != GA_ERROR::OK) return; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index bc25685b6a..4aab2a6511 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -409,9 +409,8 @@ 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_SCENERY || command == GAME_COMMAND_PLACE_LARGE_SCENERY + || command == GAME_COMMAND_PLACE_BANNER || command == GAME_COMMAND_PLACE_PATH)) { scenery_remove_ghost_tool_placement(); } @@ -611,8 +610,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_LARGE_SCENERY || command == GAME_COMMAND_PLACE_BANNER) { uint8_t flags = *ebx & 0xFF; if (flags & GAME_COMMAND_FLAG_GHOST) diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 5a42ddc354..78a0744804 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -558,6 +558,8 @@ private: int32_t elementType = tileElement->GetType(); if (elementType == TILE_ELEMENT_TYPE_SURFACE) continue; + if (tileElement->IsGhost()) + continue; if (z0 >= tileElement->clearance_height) continue; if (z1 <= tileElement->base_height) From 09875311b3d7849d1884ea5153d36aacd7f2a34d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 1 Apr 2019 17:39:48 +0100 Subject: [PATCH 164/506] 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 84da62b965..21bda33c66 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 "14" +#define NETWORK_STREAM_VERSION "15" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 78527f7af42d6993e98cf4238d5aa47772133137 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 2 Apr 2019 18:52:52 +0100 Subject: [PATCH 165/506] Extra checks for nullptrs and bad values --- src/openrct2/actions/WallPlaceAction.hpp | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 78a0744804..4697f9529a 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -25,9 +25,9 @@ DEFINE_GAME_ACTION(WallPlaceAction, GAME_COMMAND_PLACE_WALL, GameActionResult) { private: - int32_t _wallType; + int32_t _wallType{ -1 }; CoordsXYZ _loc; - uint8_t _edge; + uint8_t _edge{ std::numeric_limits::max() }; int32_t _primaryColour; int32_t _secondaryColour; int32_t _tertiaryColour; @@ -91,6 +91,16 @@ public: return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); } } + else if ((_loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)) + { + log_error("Invalid x/y coordinates. x = %d y = %d", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + if (_edge > 3) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } uint8_t edgeSlope = 0; auto targetHeight = _loc.z; @@ -448,6 +458,10 @@ private: int32_t sequence = trackElement->GetSequenceIndex(); int32_t direction = (_edge - trackElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK; Ride* ride = get_ride(trackElement->GetRideIndex()); + if (ride == nullptr) + { + return false; + } if (TrackIsAllowedWallEdges(ride->type, trackType, sequence, direction)) { @@ -461,7 +475,16 @@ private: if (RideGroupManager::RideTypeHasRideGroups(ride->type)) { - auto rideGroup = RideGroupManager::GetRideGroup(ride->type, get_ride_entry(ride->subtype)); + auto rideEntry = get_ride_entry(ride->subtype); + if (rideEntry == nullptr) + { + return false; + } + auto rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry); + if (rideGroup == nullptr) + { + return false; + } if (!(rideGroup->Flags & RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK)) { return false; From c8523b18b9e4213f25ce59e74252b209794a307d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 2 Apr 2019 19:08:06 +0100 Subject: [PATCH 166/506] One more null check --- src/openrct2/actions/WallPlaceAction.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 4697f9529a..62bb6835bf 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -578,6 +578,8 @@ private: TileElement* tileElement = map_get_first_element_at(_loc.x / 32, _loc.y / 32); do { + if (tileElement == nullptr) + break; int32_t elementType = tileElement->GetType(); if (elementType == TILE_ELEMENT_TYPE_SURFACE) continue; From 4e264bd45d6cd7fa7d0d1e93a4aeef55a9cc2371 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 31 Mar 2019 16:52:16 +0200 Subject: [PATCH 167/506] Use mutex to protect scrolling banner cache from data race --- src/openrct2/drawing/ScrollingText.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index 0d35edea29..a054247a43 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -17,6 +17,7 @@ #include "TTF.h" #include +#include #pragma pack(push, 1) /* size: 0xA12 */ @@ -38,6 +39,7 @@ assert_struct_size(rct_draw_scroll_text, 0xA12); static rct_draw_scroll_text _drawScrollTextList[MAX_SCROLLING_TEXT_ENTRIES]; static uint8_t _characterBitmaps[FONT_SPRITE_GLYPH_COUNT + SPR_G2_GLYPH_COUNT][8]; static uint32_t _drawSCrollNextIndex = 0; +static std::mutex _scrollingTextMutex; static void scrolling_text_set_bitmap_for_sprite( utf8* text, int32_t scroll, uint8_t* bitmap, const int16_t* scrollPositionOffsets); @@ -1472,6 +1474,8 @@ void scrolling_text_invalidate() */ int32_t scrolling_text_setup(paint_session* session, rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode) { + std::scoped_lock lock(_scrollingTextMutex); + assert(scrollingMode < MAX_SCROLLING_TEXT_MODES); rct_drawpixelinfo* dpi = &session->DPI; From c520b0061eecf93e5b4b5f5d122a3adb51b2e33a Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 2 Apr 2019 06:20:46 +0200 Subject: [PATCH 168/506] Refactor large_scenery_sign_fit_text to not return static local. --- .../paint/tile_element/Paint.LargeScenery.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp index ea8fd3f599..3ee465040b 100644 --- a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp @@ -97,11 +97,10 @@ static int32_t large_scenery_sign_text_height(const utf8* str, rct_large_scenery return height; } -static const utf8* large_scenery_sign_fit_text(const utf8* str, rct_large_scenery_text* text, bool height) +static void large_scenery_sign_fit_text(const utf8* str, rct_large_scenery_text* text, bool height, utf8* fitStr, size_t bufLen) { - static utf8 fitStr[32]; utf8* fitStrEnd = fitStr; - safe_strcpy(fitStr, str, sizeof(fitStr)); + safe_strcpy(fitStr, str, bufLen); int32_t w = 0; uint32_t codepoint; while (w <= text->max_width && (codepoint = utf8_get_next(fitStrEnd, (const utf8**)&fitStrEnd)) != 0) @@ -116,7 +115,6 @@ static const utf8* large_scenery_sign_fit_text(const utf8* str, rct_large_scener } } *fitStrEnd = 0; - return fitStr; } static int32_t div_to_minus_infinity(int32_t a, int32_t b) @@ -128,7 +126,8 @@ static void large_scenery_sign_paint_line( paint_session* session, const utf8* str, rct_large_scenery_text* text, int32_t textImage, int32_t textColour, uint8_t direction, int32_t y_offset) { - const utf8* fitStr = large_scenery_sign_fit_text(str, text, false); + utf8 fitStr[32]; + large_scenery_sign_fit_text(str, text, false, fitStr, sizeof(fitStr)); int32_t width = large_scenery_sign_text_width(fitStr, text); int32_t x_offset = text->offset[(direction & 1)].x; int32_t acc = y_offset * ((direction & 1) ? -1 : 1); @@ -139,7 +138,8 @@ static void large_scenery_sign_paint_line( acc -= (width / 2); } uint32_t codepoint; - while ((codepoint = utf8_get_next(fitStr, &fitStr)) != 0) + const utf8* fitStrPtr = fitStr; + while ((codepoint = utf8_get_next(fitStrPtr, &fitStrPtr)) != 0) { int32_t glyph_offset = large_scenery_sign_get_glyph(text, codepoint)->image_offset; uint8_t glyph_type = direction & 1; @@ -327,8 +327,9 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei // Draw vertical sign: y_offset += 1; utf8 fitStr[32]; + large_scenery_sign_fit_text(signString, text, true, fitStr, sizeof(fitStr)); + safe_strcpy(fitStr, fitStr, sizeof(fitStr)); const utf8* fitStrPtr = fitStr; - safe_strcpy(fitStr, large_scenery_sign_fit_text(signString, text, true), sizeof(fitStr)); int32_t height2 = large_scenery_sign_text_height(fitStr, text); uint32_t codepoint; while ((codepoint = utf8_get_next(fitStrPtr, &fitStrPtr)) != 0) From 313117f2661fd70c2652c263076c9bd38e727f4d Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 2 Apr 2019 18:59:40 +0200 Subject: [PATCH 169/506] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 288939cb37..757f941019 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. +- Feature: [#8481] Multi-threaded rendering. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Change: [#8688] Move common actions from debug menu into cheats menu. From 1ff1f6d126f2daf6d2ad1c009081e2ffdb84b4ab Mon Sep 17 00:00:00 2001 From: hokasha2016 <46494088+hokasha2016@users.noreply.github.com> Date: Tue, 2 Apr 2019 18:04:22 -0400 Subject: [PATCH 170/506] Add the Hungarian Forint (HUF) to the list of available currencies. (#9017) --- data/language/en-GB.txt | 1 + distribution/changelog.txt | 1 + src/openrct2/localisation/Currency.cpp | 1 + src/openrct2/localisation/Currency.h | 1 + src/openrct2/localisation/StringIds.h | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 865637d53c..3e9f57b7d1 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3214,6 +3214,7 @@ STR_5762 :Chinese Yuan (CN¥) STR_5763 :All files STR_5764 :Invalid ride type STR_5765 :Cannot edit rides of invalid type +STR_5766 :Hungarian Forint (Ft) STR_5767 :Income STR_5768 :Total customers STR_5769 :Total profit diff --git a/distribution/changelog.txt b/distribution/changelog.txt index fb7f62e5ed..1053d9e35d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. +- Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. - Feature: [#8481] Multi-threaded rendering. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. diff --git a/src/openrct2/localisation/Currency.cpp b/src/openrct2/localisation/Currency.cpp index 71de644fff..0858222b71 100644 --- a/src/openrct2/localisation/Currency.cpp +++ b/src/openrct2/localisation/Currency.cpp @@ -31,6 +31,7 @@ currency_descriptor CurrencyDescriptors[CURRENCY_END] = { { "HKD", 100, CURRENCY_PREFIX, "$", CURRENCY_PREFIX, "HKD", STR_HONG_KONG_DOLLAR}, // Hong Kong Dollar { "TWD", 1000, CURRENCY_PREFIX, "NT$", CURRENCY_PREFIX, "NT$", STR_NEW_TAIWAN_DOLLAR}, // New Taiwan Dollar { "CNY", 100, CURRENCY_PREFIX, "CN\xC2\xA5", CURRENCY_PREFIX, "CNY", STR_CHINESE_YUAN }, // Chinese Yuan + { "HUF", 1000, CURRENCY_PREFIX, "Ft", CURRENCY_PREFIX, "Ft", STR_HUNGARIAN_FORINT}, // Hungarian Forint { "CTM", 10, CURRENCY_PREFIX, "Ctm", CURRENCY_PREFIX, "Ctm", STR_CUSTOM_CURRENCY }, // Customizable currency }; // clang-format on diff --git a/src/openrct2/localisation/Currency.h b/src/openrct2/localisation/Currency.h index 4a12692be0..2b186f1508 100644 --- a/src/openrct2/localisation/Currency.h +++ b/src/openrct2/localisation/Currency.h @@ -31,6 +31,7 @@ enum CURRENCY_TYPE CURRENCY_HKD, // Hong Kong Dollar CURRENCY_TWD, // New Taiwan Dollar CURRENCY_YUAN, // Chinese Yuan + CURRENCY_FORINT, // Hungarian Forint CURRENCY_CUSTOM, // Custom currency diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 6a03538327..7213d4d08c 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3311,7 +3311,7 @@ enum STR_ALL_FILES = 5763, STR_INVALID_RIDE_TYPE = 5764, STR_CANT_EDIT_INVALID_RIDE_TYPE = 5765, - + STR_HUNGARIAN_FORINT = 5766, STR_RIDE_LIST_INCOME = 5767, STR_RIDE_LIST_TOTAL_CUSTOMERS = 5768, STR_RIDE_LIST_TOTAL_PROFIT = 5769, From dc90b2873aecf00ae7d3e5aae511f6a2aff61f85 Mon Sep 17 00:00:00 2001 From: hokasha2016 <46494088+hokasha2016@users.noreply.github.com> Date: Tue, 2 Apr 2019 18:16:47 -0400 Subject: [PATCH 171/506] Sort files in logical rather than dictionary order (#9012) --- contributors.md | 4 ++++ distribution/changelog.txt | 1 + src/openrct2-ui/windows/LoadSave.cpp | 6 +++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/contributors.md b/contributors.md index 3d0a468e0c..2aa925ae12 100644 --- a/contributors.md +++ b/contributors.md @@ -121,6 +121,10 @@ The following people are not part of the development team, but have been contrib * Jason Myre (jmyre1999) * Nicole Wright (nicolewright) * Josh Tucker (joshtucker132) +* Hussein Okasha (Hokasha2016) +* Brandon Dupree (Bdupree5) +* Zetao Ye (ZbrettonYe) +* Jordan Arevalos (Jarevalos2017) ## Toolchain * (Balletie) - macOS diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 1053d9e35d..db6780ec30 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Feature: [#8481] Multi-threaded rendering. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. +- Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 2432414cfa..5328622c8d 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -786,15 +786,15 @@ static bool list_item_sort(LoadSaveListItem& a, LoadSaveListItem& b) switch (gConfigGeneral.load_save_sort) { case SORT_NAME_ASCENDING: - return strcicmp(a.name.c_str(), b.name.c_str()) < 0; + return strlogicalcmp(a.name.c_str(), b.name.c_str()) < 0; case SORT_NAME_DESCENDING: - return -strcicmp(a.name.c_str(), b.name.c_str()) < 0; + return -strlogicalcmp(a.name.c_str(), b.name.c_str()) < 0; case SORT_DATE_DESCENDING: return -difftime(a.date_modified, b.date_modified) < 0; case SORT_DATE_ASCENDING: return difftime(a.date_modified, b.date_modified) < 0; default: - return strcicmp(a.name.c_str(), b.name.c_str()) < 0; + return strlogicalcmp(a.name.c_str(), b.name.c_str()) < 0; } } From 3efdcdef43335bcb7ed63f58896b08d3e53185e6 Mon Sep 17 00:00:00 2001 From: anon569 <42820802+anon569@users.noreply.github.com> Date: Thu, 4 Apr 2019 09:01:21 +0200 Subject: [PATCH 172/506] Hungarian Forint fix (#9043) https://en.wikipedia.org/wiki/Hungarian_forint "The Hungarian abbreviation for forint is Ft, which is written after the number with a space between." --- src/openrct2/localisation/Currency.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/localisation/Currency.cpp b/src/openrct2/localisation/Currency.cpp index 0858222b71..9f2332adc7 100644 --- a/src/openrct2/localisation/Currency.cpp +++ b/src/openrct2/localisation/Currency.cpp @@ -31,7 +31,7 @@ currency_descriptor CurrencyDescriptors[CURRENCY_END] = { { "HKD", 100, CURRENCY_PREFIX, "$", CURRENCY_PREFIX, "HKD", STR_HONG_KONG_DOLLAR}, // Hong Kong Dollar { "TWD", 1000, CURRENCY_PREFIX, "NT$", CURRENCY_PREFIX, "NT$", STR_NEW_TAIWAN_DOLLAR}, // New Taiwan Dollar { "CNY", 100, CURRENCY_PREFIX, "CN\xC2\xA5", CURRENCY_PREFIX, "CNY", STR_CHINESE_YUAN }, // Chinese Yuan - { "HUF", 1000, CURRENCY_PREFIX, "Ft", CURRENCY_PREFIX, "Ft", STR_HUNGARIAN_FORINT}, // Hungarian Forint + { "HUF", 1000, CURRENCY_SUFFIX, " Ft", CURRENCY_SUFFIX, " Ft", STR_HUNGARIAN_FORINT}, // Hungarian Forint { "CTM", 10, CURRENCY_PREFIX, "Ctm", CURRENCY_PREFIX, "Ctm", STR_CUSTOM_CURRENCY }, // Customizable currency }; // clang-format on From 62f163a67db4858a112f7cd5f13cff8d4a734052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 4 Apr 2019 12:11:37 +0200 Subject: [PATCH 173/506] Don't enable multithreading option by default. (#9039) --- data/language/en-GB.txt | 2 +- src/openrct2/config/Config.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 3e9f57b7d1..9e57c493b8 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3753,7 +3753,7 @@ STR_6302 :{SMALLFONT}{BLACK}Copy the entire list of missing objects to the cl STR_6303 :Downloading object ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Open scenery picker STR_6305 :Multithreading -STR_6306 :{SMALLFONT}{BLACK}Use multiple threads to render +STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to render, may cause instability. ############# # Scenarios # diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 3eb02ff8b7..c34aaa9f0a 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -195,7 +195,7 @@ namespace Config model->window_scale = reader->GetFloat("window_scale", platform_get_default_scale()); model->scale_quality = reader->GetEnum("scale_quality", SCALE_QUALITY_SMOOTH_NN, Enum_ScaleQuality); model->show_fps = reader->GetBoolean("show_fps", false); - model->multithreading = reader->GetBoolean("multithreading", true); + model->multithreading = reader->GetBoolean("multi_threading", false); model->trap_cursor = reader->GetBoolean("trap_cursor", false); model->auto_open_shops = reader->GetBoolean("auto_open_shops", false); model->scenario_select_mode = reader->GetInt32("scenario_select_mode", SCENARIO_SELECT_MODE_ORIGIN); @@ -269,7 +269,7 @@ namespace Config writer->WriteFloat("window_scale", model->window_scale); writer->WriteEnum("scale_quality", model->scale_quality, Enum_ScaleQuality); writer->WriteBoolean("show_fps", model->show_fps); - writer->WriteBoolean("multithreading", model->multithreading); + writer->WriteBoolean("multi_threading", model->multithreading); writer->WriteBoolean("trap_cursor", model->trap_cursor); writer->WriteBoolean("auto_open_shops", model->auto_open_shops); writer->WriteInt32("scenario_select_mode", model->scenario_select_mode); From 2320cd169f5ca8535ac3d38a6b987fc027bcfe43 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 27 Mar 2019 19:21:13 +0000 Subject: [PATCH 174/506] Rename PTD enum --- src/openrct2/ride/TrackDesign.cpp | 102 +++++++++++++++--------------- src/openrct2/ride/TrackDesign.h | 8 +-- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 59229bc8be..ca2893e73b 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -886,9 +886,9 @@ static int32_t track_design_place_scenery( } } - if (_trackDesignPlaceOperation == PTD_OPERATION_1 || _trackDesignPlaceOperation == PTD_OPERATION_2 - || _trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z || _trackDesignPlaceOperation == PTD_OPERATION_4 - || _trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE + || _trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { uint8_t entry_type, entry_index; if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) @@ -952,17 +952,17 @@ static int32_t track_design_place_scenery( quadrant = ((scenery->flags >> 2) + _currentTrackPieceDirection) & 3; flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_1) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = GAME_COMMAND_FLAG_PATH_SCENERY; } @@ -996,17 +996,17 @@ static int32_t track_design_place_scenery( z = scenery->z * 8 + originZ; flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_1) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = GAME_COMMAND_FLAG_PATH_SCENERY; } @@ -1037,17 +1037,17 @@ static int32_t track_design_place_scenery( rotation &= 3; flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_1) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = 0; } @@ -1085,16 +1085,16 @@ static int32_t track_design_place_scenery( bh |= scenery->flags & 0x90; flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - if (_trackDesignPlaceOperation == PTD_OPERATION_4) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; } - if (_trackDesignPlaceOperation == PTD_OPERATION_1) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = 0; } @@ -1111,7 +1111,7 @@ static int32_t track_design_place_scenery( } else { - if (_trackDesignPlaceOperation == PTD_OPERATION_1) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { continue; } @@ -1127,11 +1127,11 @@ static int32_t track_design_place_scenery( footpath_remove_edges_at(mapCoord.x, mapCoord.y, tile_element); flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - if (_trackDesignPlaceOperation == PTD_OPERATION_4) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; @@ -1147,7 +1147,7 @@ static int32_t track_design_place_scenery( continue; } _trackDesignPlaceCost = add_clamp_money32(_trackDesignPlaceCost, cost); - if (_trackDesignPlaceOperation != PTD_OPERATION_2) + if (_trackDesignPlaceOperation != PTD_OPERATION_PLACE) { if (cost == MONEY32_UNDEFINED) { @@ -1158,7 +1158,7 @@ static int32_t track_design_place_scenery( { continue; } - if (_trackDesignPlaceOperation == PTD_OPERATION_2) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE) { continue; } @@ -1201,8 +1201,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, track_design_add_selection_tile(mapCoord.x, mapCoord.y); } - if (_trackDesignPlaceOperation == PTD_OPERATION_1 || _trackDesignPlaceOperation == PTD_OPERATION_2 - || _trackDesignPlaceOperation == PTD_OPERATION_4 || _trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { uint8_t flags; money32 cost = 0; @@ -1217,18 +1217,18 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, flags = GAME_COMMAND_FLAG_APPLY; gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; - if (_trackDesignPlaceOperation == PTD_OPERATION_1) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { auto res = RideEntranceExitPlaceAction::TrackPlaceQuery({ mapCoord.x, mapCoord.y, z }, false); cost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } else { - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; @@ -1251,18 +1251,18 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, flags = GAME_COMMAND_FLAG_APPLY; gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; - if (_trackDesignPlaceOperation == PTD_OPERATION_1) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { auto res = RideEntranceExitPlaceAction::TrackPlaceQuery({ mapCoord.x, mapCoord.y, z }, true); cost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } else { - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; @@ -1280,16 +1280,16 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, default: maze_entry = rol16(maze_element->maze_entry, rotation * 4); - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_1) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = 0; } @@ -1431,10 +1431,10 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in GameActions::ExecuteNested(&trackRemoveAction); break; } - case PTD_OPERATION_1: - case PTD_OPERATION_2: - case PTD_OPERATION_4: - case PTD_OPERATION_GET_COST: + case PTD_OPERATION_PLACE_QUERY: + case PTD_OPERATION_PLACE: + case PTD_OPERATION_PLACE_GHOST: + case PTD_OPERATION_PLACE_TRACK_PREVIEW: { const rct_track_coordinates* trackCoordinates = &TrackCoordinates[trackType]; @@ -1455,18 +1455,18 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in } uint8_t flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags |= GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; flags |= GAME_COMMAND_FLAG_5; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_4) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags |= GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; flags |= GAME_COMMAND_FLAG_5; flags |= GAME_COMMAND_FLAG_GHOST; } - else if (_trackDesignPlaceOperation == PTD_OPERATION_1) + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = 0; } @@ -1569,10 +1569,10 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in case PTD_OPERATION_DRAW_OUTLINES: track_design_add_selection_tile(x, y); break; - case PTD_OPERATION_1: - case PTD_OPERATION_2: - case PTD_OPERATION_4: - case PTD_OPERATION_GET_COST: + case PTD_OPERATION_PLACE_QUERY: + case PTD_OPERATION_PLACE: + case PTD_OPERATION_PLACE_GHOST: + case PTD_OPERATION_PLACE_TRACK_PREVIEW: { rotation = (rotation + entrance->direction) & 3; bool isExit = false; @@ -1581,7 +1581,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in isExit = true; } - if (_trackDesignPlaceOperation != PTD_OPERATION_1) + if (_trackDesignPlaceOperation != PTD_OPERATION_PLACE_QUERY) { LocationXY16 tile = { (int16_t)(x + CoordsDirectionDelta[rotation].x), @@ -1604,16 +1604,16 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in int32_t stationIndex = tile_element->AsTrack()->GetStationIndex(); uint8_t flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_COST) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; } - if (_trackDesignPlaceOperation == PTD_OPERATION_4) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; } - if (_trackDesignPlaceOperation == PTD_OPERATION_1) + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { flags = 0; } @@ -1820,7 +1820,7 @@ static bool track_design_place_preview(rct_track_td6* td6, money32* cost, Ride** *flags |= TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE; } - money32 resultCost = place_virtual_track(td6, PTD_OPERATION_GET_COST, placeScenery, ride, mapSize, mapSize, z); + money32 resultCost = place_virtual_track(td6, PTD_OPERATION_PLACE_TRACK_PREVIEW, placeScenery, ride, mapSize, mapSize, z); gParkFlags = backup_park_flags; if (resultCost != MONEY32_UNDEFINED) @@ -1935,11 +1935,11 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags if (!(flags & GAME_COMMAND_FLAG_APPLY)) { _trackDesignDontPlaceScenery = false; - cost = place_virtual_track(td6, PTD_OPERATION_1, true, ride, x, y, z); + cost = place_virtual_track(td6, PTD_OPERATION_PLACE_QUERY, true, ride, x, y, z); if (_trackDesignPlaceStateSceneryUnavailable) { _trackDesignDontPlaceScenery = true; - cost = place_virtual_track(td6, PTD_OPERATION_1, false, ride, x, y, z); + cost = place_virtual_track(td6, PTD_OPERATION_PLACE_QUERY, false, ride, x, y, z); } } else @@ -1947,11 +1947,11 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags uint8_t operation; if (flags & GAME_COMMAND_FLAG_GHOST) { - operation = PTD_OPERATION_4; + operation = PTD_OPERATION_PLACE_GHOST; } else { - operation = PTD_OPERATION_2; + operation = PTD_OPERATION_PLACE; } cost = place_virtual_track(td6, operation, !_trackDesignDontPlaceScenery, ride, x, y, z); diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index b46fc86e1d..717030263d 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -198,11 +198,11 @@ enum enum { PTD_OPERATION_DRAW_OUTLINES, - PTD_OPERATION_1, - PTD_OPERATION_2, + PTD_OPERATION_PLACE_QUERY, + PTD_OPERATION_PLACE, PTD_OPERATION_GET_PLACE_Z, - PTD_OPERATION_4, - PTD_OPERATION_GET_COST, + PTD_OPERATION_PLACE_GHOST, + PTD_OPERATION_PLACE_TRACK_PREVIEW, PTD_OPERATION_CLEAR_OUTLINES, }; From 9f80a16353f34cb161cc81704489d1c5330f90ca Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 27 Mar 2019 19:33:27 +0000 Subject: [PATCH 175/506] Further rename --- src/openrct2/ride/TrackDesign.cpp | 8 ++++---- src/openrct2/ride/TrackDesign.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index ca2893e73b..d70a1ed196 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -775,7 +775,7 @@ static int32_t track_design_place_scenery( } } - if (_trackDesignPlaceOperation == PTD_OPERATION_CLEAR_OUTLINES && mode == 0) + if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0) { uint8_t entry_type, entry_index; if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) @@ -1363,7 +1363,7 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, } } - if (_trackDesignPlaceOperation == PTD_OPERATION_CLEAR_OUTLINES) + if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST) { ride_action_modify( ride, RIDE_MODIFY_DEMOLISH, @@ -1420,7 +1420,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in track_design_add_selection_tile(tile.x, tile.y); } break; - case PTD_OPERATION_CLEAR_OUTLINES: + case PTD_OPERATION_REMOVE_GHOST: { const rct_track_coordinates* trackCoordinates = &TrackCoordinates[trackType]; const rct_preview_track* trackBlock = trackBlockArray[trackType]; @@ -1659,7 +1659,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in } } - if (_trackDesignPlaceOperation == PTD_OPERATION_CLEAR_OUTLINES) + if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST) { sub_6CB945(ride); ride->Delete(); diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index 717030263d..32982f9b9b 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -203,7 +203,7 @@ enum PTD_OPERATION_GET_PLACE_Z, PTD_OPERATION_PLACE_GHOST, PTD_OPERATION_PLACE_TRACK_PREVIEW, - PTD_OPERATION_CLEAR_OUTLINES, + PTD_OPERATION_REMOVE_GHOST, }; enum From f7c84fff607caf04c80b026a2da657763ab0b004 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 27 Mar 2019 20:01:57 +0000 Subject: [PATCH 176/506] Split scenery place into multiple functions --- src/openrct2/ride/TrackDesign.cpp | 870 ++++++++++++++++-------------- 1 file changed, 455 insertions(+), 415 deletions(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index d70a1ed196..e66d69b2c4 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -702,6 +702,457 @@ static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_ gTrackPreviewMax.z = std::max(gTrackPreviewMax.z, z); } +static bool TrackDesignPlaceSceneryTileDrawOutline(LocationXY8 tile) +{ + uint8_t new_tile = 1; + LocationXY16* selectionTile = gMapSelectionTiles; + for (; selectionTile->x != -1; selectionTile++) + { + if (selectionTile->x == tile.x && selectionTile->y == tile.y) + { + new_tile = 0; + break; + } + // Need to subtract one because selectionTile in following block is incremented + if (selectionTile + 1 >= &gMapSelectionTiles[std::size(gMapSelectionTiles) - 1]) + { + new_tile = 0; + break; + } + } + if (new_tile) + { + selectionTile->x = tile.x; + selectionTile->y = tile.y; + selectionTile++; + selectionTile->x = -1; + } + return true; +} + +static bool TrackDesignPlaceSceneryTileRemoveGhost( + CoordsXY mapCoord, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) +{ + uint8_t entry_type, entry_index; + if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) + { + entry_type = object_entry_get_type(&scenery->scenery_object); + if (entry_type != OBJECT_TYPE_PATHS) + { + entry_type = 0xFF; + } + if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) + { + entry_type = 0xFF; + } + + entry_index = 0; + for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; + path = get_path_surface_entry(entry_index), entry_index++) + { + if (path == nullptr) + { + return true; + } + if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) + { + return true; + } + } + + if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) + { + entry_type = 0xFF; + } + } + int32_t z; + const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + | GAME_COMMAND_FLAG_GHOST; + + switch (entry_type) + { + case OBJECT_TYPE_SMALL_SCENERY: + { + // bl + rotation += scenery->flags; + rotation &= 3; + + // bh + uint8_t quadrant = (scenery->flags >> 2) + _currentTrackPieceDirection; + quadrant &= 3; + + rct_scenery_entry* small_scenery = get_small_scenery_entry(entry_index); + if (!(!scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_FULL_TILE) + && scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_DIAGONAL)) + && scenery_small_entry_has_flag( + small_scenery, + SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS)) + { + quadrant = 0; + } + + z = (scenery->z * 8 + originZ) / 8; + + auto removeSceneryAction = SmallSceneryRemoveAction(mapCoord.x, mapCoord.y, z, quadrant, entry_index); + removeSceneryAction.SetFlags(flags); + removeSceneryAction.Execute(); + + break; + } + case OBJECT_TYPE_LARGE_SCENERY: + { + z = (scenery->z * 8 + originZ) / 8; + + auto removeSceneryAction = LargeSceneryRemoveAction( + mapCoord.x, mapCoord.y, z, (rotation + scenery->flags) & 0x3, 0); + removeSceneryAction.SetFlags(flags); + removeSceneryAction.Execute(); + + break; + } + case OBJECT_TYPE_WALLS: + { + z = (scenery->z * 8 + originZ) / 8; + + uint8_t direction = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; + + TileCoordsXYZD wallLocation = { mapCoord.x / 32, mapCoord.y / 32, z, direction }; + auto wallRemoveAction = WallRemoveAction(wallLocation); + wallRemoveAction.SetFlags(flags); + + GameActions::Execute(&wallRemoveAction); + + break; + } + case OBJECT_TYPE_PATHS: + z = (scenery->z * 8 + originZ) / 8; + footpath_remove(mapCoord.x, mapCoord.y, z, flags); + break; + } + return true; +} + +static bool TrackDesignPlaceSceneryTileGetEntry(uint8_t& entry_type, uint8_t& entry_index, rct_td6_scenery_element* scenery) +{ + uint8_t entry_type, entry_index; + if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) + { + entry_type = object_entry_get_type(&scenery->scenery_object); + if (entry_type != OBJECT_TYPE_PATHS) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + + if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + + entry_index = 0; + for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; + path = get_path_surface_entry(entry_index), entry_index++) + { + if (path == nullptr) + { + return true; + } + if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) + { + return true; + } + } + + if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + } + return false; +} + +static bool TrackDesignPlaceSceneryTileGetPlaceZ(rct_td6_scenery_element* scenery) +{ + int32_t z = scenery->z * 8 + _trackDesignPlaceZ; + if (z < _trackDesignPlaceSceneryZ) + { + _trackDesignPlaceSceneryZ = z; + } + + uint8_t entry_type, entry_index; + TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery); + + return true; +} + +static bool TrackDesignPlaceSceneryTile( + CoordsXY mapCoord, LocationXY8 tile, uint8_t mode, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) +{ + if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0) + { + return TrackDesignPlaceSceneryTileDrawOutline(tile); + } + + if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0) + { + return TrackDesignPlaceSceneryTileRemoveGhost(mapCoord, scenery, rotation, originZ); + } + + if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) + { + return TrackDesignPlaceSceneryTileGetPlaceZ(scenery); + } + + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + uint8_t entry_type, entry_index; + if (TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery)) + { + return true; + } + + money32 cost; + int16_t z; + uint8_t flags; + uint8_t quadrant; + + switch (entry_type) + { + case OBJECT_TYPE_SMALL_SCENERY: + { + if (mode != 0) + { + return true; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) + { + return true; + } + + rotation += scenery->flags; + rotation &= 3; + z = scenery->z * 8 + originZ; + quadrant = ((scenery->flags >> 2) + _currentTrackPieceDirection) & 3; + + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_5; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) + { + flags = GAME_COMMAND_FLAG_PATH_SCENERY; + } + + gGameCommandErrorTitle = STR_CANT_POSITION_THIS_HERE; + + auto smallSceneryPlace = SmallSceneryPlaceAction( + { mapCoord.x, mapCoord.y, z, rotation }, quadrant, entry_index, scenery->primary_colour, + scenery->secondary_colour); + + smallSceneryPlace.SetFlags(flags); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&smallSceneryPlace) + : GameActions::QueryNested(&smallSceneryPlace); + + cost = res->Error == GA_ERROR::OK ? res->Cost : 0; + break; + } + case OBJECT_TYPE_LARGE_SCENERY: + if (mode != 0) + { + return true; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) + { + return true; + } + + rotation += scenery->flags; + rotation &= 3; + + z = scenery->z * 8 + originZ; + + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_5; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) + { + 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); + + if (cost == MONEY32_UNDEFINED) + { + cost = 0; + } + break; + case OBJECT_TYPE_WALLS: + { + if (mode != 0) + { + return true; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) + { + return true; + } + + z = scenery->z * 8 + originZ; + rotation += scenery->flags; + rotation &= 3; + + flags = GAME_COMMAND_FLAG_APPLY; + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_5; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + | GAME_COMMAND_FLAG_GHOST; + } + else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) + { + flags = 0; + } + + auto wallPlaceAction = WallPlaceAction( + entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, scenery->secondary_colour, + scenery->flags & 0xFC); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction) + : GameActions::Query(&wallPlaceAction); + + cost = res->Cost; + break; + } + case OBJECT_TYPE_PATHS: + if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) + { + return true; + } + + z = (scenery->z * 8 + originZ) / 8; + if (mode == 0) + { + if (scenery->flags & (1 << 7)) + { + // dh + entry_index |= (1 << 7); + } + + uint8_t bh = ((scenery->flags & 0xF) << rotation); + flags = bh >> 4; + bh = (bh | flags) & 0xF; + flags = (((scenery->flags >> 5) + rotation) & 3) << 5; + bh |= flags; + + bh |= scenery->flags & 0x90; + + flags = GAME_COMMAND_FLAG_APPLY; + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + | GAME_COMMAND_FLAG_GHOST; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) + { + flags = 0; + } + + uint8_t slope = ((bh >> 5) & 0x3) | ((bh >> 2) & 0x4); + uint8_t edges = bh & 0xF; + auto footpathPlaceAction = FootpathPlaceFromTrackAction( + { mapCoord.x, mapCoord.y, z * 8 }, slope, entry_index, edges); + footpathPlaceAction.SetFlags(flags); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&footpathPlaceAction) + : GameActions::QueryNested(&footpathPlaceAction); + // Ignore failures + cost = res->Error == GA_ERROR::OK ? res->Cost : 0; + } + else + { + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) + { + return true; + } + + TileElement* tile_element = map_get_path_element_at(mapCoord.x / 32, mapCoord.y / 32, z); + + if (tile_element == nullptr) + { + return true; + } + + footpath_queue_chain_reset(); + footpath_remove_edges_at(mapCoord.x, mapCoord.y, tile_element); + + flags = GAME_COMMAND_FLAG_APPLY; + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) + { + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + | GAME_COMMAND_FLAG_GHOST; + } + + footpath_connect_edges(mapCoord.x, mapCoord.y, tile_element, flags); + footpath_update_queue_chains(); + return true; + } + break; + default: + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + _trackDesignPlaceCost = add_clamp_money32(_trackDesignPlaceCost, cost); + if (_trackDesignPlaceOperation != PTD_OPERATION_PLACE) + { + if (cost == MONEY32_UNDEFINED) + { + _trackDesignPlaceCost = MONEY32_UNDEFINED; + } + } + if (_trackDesignPlaceCost != MONEY32_UNDEFINED) + { + return true; + } + if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE) + { + return true; + } + return false; + } + return true; +} + /** * * rct2: 0x006D0964 @@ -745,423 +1196,11 @@ static int32_t track_design_place_scenery( break; } - LocationXY16 mapCoord = { (int16_t)(tile.x * 32), (int16_t)(tile.y * 32) }; + CoordsXY mapCoord = { tile.x * 32, tile.y * 32 }; track_design_update_max_min_coordinates(mapCoord.x, mapCoord.y, originZ); - if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0) + if (!TrackDesignPlaceSceneryTile(mapCoord, tile, mode, scenery, rotation, originZ)) { - uint8_t new_tile = 1; - LocationXY16* selectionTile = gMapSelectionTiles; - for (; selectionTile->x != -1; selectionTile++) - { - if (selectionTile->x == tile.x && selectionTile->y == tile.y) - { - new_tile = 0; - break; - } - // Need to subtract one because selectionTile in following block is incremented - if (selectionTile + 1 >= &gMapSelectionTiles[std::size(gMapSelectionTiles) - 1]) - { - new_tile = 0; - break; - } - } - if (new_tile) - { - selectionTile->x = tile.x; - selectionTile->y = tile.y; - selectionTile++; - selectionTile->x = -1; - } - } - - if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0) - { - uint8_t entry_type, entry_index; - if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) - { - entry_type = object_entry_get_type(&scenery->scenery_object); - if (entry_type != OBJECT_TYPE_PATHS) - { - entry_type = 0xFF; - } - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - { - entry_type = 0xFF; - } - - entry_index = 0; - for (PathSurfaceEntry* path = get_path_surface_entry(0); - entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_path_surface_entry(entry_index), entry_index++) - { - if (path == nullptr) - { - continue; - } - if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) - { - continue; - } - } - - if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) - { - entry_type = 0xFF; - } - } - int32_t z; - const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 - | GAME_COMMAND_FLAG_GHOST; - - switch (entry_type) - { - case OBJECT_TYPE_SMALL_SCENERY: - { - // bl - rotation += scenery->flags; - rotation &= 3; - - // bh - uint8_t quadrant = (scenery->flags >> 2) + _currentTrackPieceDirection; - quadrant &= 3; - - rct_scenery_entry* small_scenery = get_small_scenery_entry(entry_index); - if (!(!scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_FULL_TILE) - && scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_DIAGONAL)) - && scenery_small_entry_has_flag( - small_scenery, - SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE - | SMALL_SCENERY_FLAG_THREE_QUARTERS)) - { - quadrant = 0; - } - - z = (scenery->z * 8 + originZ) / 8; - - auto removeSceneryAction = SmallSceneryRemoveAction(mapCoord.x, mapCoord.y, z, quadrant, entry_index); - removeSceneryAction.SetFlags(flags); - removeSceneryAction.Execute(); - - break; - } - case OBJECT_TYPE_LARGE_SCENERY: - { - z = (scenery->z * 8 + originZ) / 8; - - auto removeSceneryAction = LargeSceneryRemoveAction( - mapCoord.x, mapCoord.y, z, (rotation + scenery->flags) & 0x3, 0); - removeSceneryAction.SetFlags(flags); - removeSceneryAction.Execute(); - - break; - } - case OBJECT_TYPE_WALLS: - { - z = (scenery->z * 8 + originZ) / 8; - - uint8_t direction = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; - - TileCoordsXYZD wallLocation = { tile.x, tile.y, z, direction }; - auto wallRemoveAction = WallRemoveAction(wallLocation); - wallRemoveAction.SetFlags(flags); - - GameActions::Execute(&wallRemoveAction); - - break; - } - case OBJECT_TYPE_PATHS: - z = (scenery->z * 8 + originZ) / 8; - footpath_remove(mapCoord.x, mapCoord.y, z, flags); - break; - } - } - - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) - { - int32_t z = scenery->z * 8 + _trackDesignPlaceZ; - if (z < _trackDesignPlaceSceneryZ) - { - _trackDesignPlaceSceneryZ = z; - } - } - - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE - || _trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST - || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - uint8_t entry_type, entry_index; - if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) - { - entry_type = object_entry_get_type(&scenery->scenery_object); - if (entry_type != OBJECT_TYPE_PATHS) - { - _trackDesignPlaceStateSceneryUnavailable = true; - continue; - } - - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - { - _trackDesignPlaceStateSceneryUnavailable = true; - continue; - } - - entry_index = 0; - for (PathSurfaceEntry* path = get_path_surface_entry(0); - entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_path_surface_entry(entry_index), entry_index++) - { - if (path == nullptr) - { - continue; - } - if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) - { - continue; - } - } - - if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) - { - _trackDesignPlaceStateSceneryUnavailable = true; - continue; - } - } - - money32 cost; - int16_t z; - uint8_t flags; - uint8_t quadrant; - - switch (entry_type) - { - case OBJECT_TYPE_SMALL_SCENERY: - { - if (mode != 0) - { - continue; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) - { - continue; - } - - rotation += scenery->flags; - rotation &= 3; - z = scenery->z * 8 + originZ; - quadrant = ((scenery->flags >> 2) + _currentTrackPieceDirection) & 3; - - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY - | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY - | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) - { - flags = GAME_COMMAND_FLAG_PATH_SCENERY; - } - - gGameCommandErrorTitle = STR_CANT_POSITION_THIS_HERE; - - auto smallSceneryPlace = SmallSceneryPlaceAction( - { mapCoord.x, mapCoord.y, z, rotation }, quadrant, entry_index, scenery->primary_colour, - scenery->secondary_colour); - - smallSceneryPlace.SetFlags(flags); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&smallSceneryPlace) - : GameActions::QueryNested(&smallSceneryPlace); - - cost = res->Error == GA_ERROR::OK ? res->Cost : 0; - break; - } - case OBJECT_TYPE_LARGE_SCENERY: - if (mode != 0) - { - continue; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) - { - continue; - } - - rotation += scenery->flags; - rotation &= 3; - - z = scenery->z * 8 + originZ; - - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY; - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY - | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY - | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) - { - 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); - - if (cost == MONEY32_UNDEFINED) - { - cost = 0; - } - break; - case OBJECT_TYPE_WALLS: - { - if (mode != 0) - { - continue; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) - { - continue; - } - - z = scenery->z * 8 + originZ; - rotation += scenery->flags; - rotation &= 3; - - flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY - | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 - | GAME_COMMAND_FLAG_GHOST; - } - else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) - { - flags = 0; - } - - auto wallPlaceAction = WallPlaceAction( - entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, - scenery->secondary_colour, scenery->flags & 0xFC); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction) - : GameActions::Query(&wallPlaceAction); - - cost = res->Cost; - break; - } - case OBJECT_TYPE_PATHS: - if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) - { - continue; - } - - z = (scenery->z * 8 + originZ) / 8; - if (mode == 0) - { - if (scenery->flags & (1 << 7)) - { - // dh - entry_index |= (1 << 7); - } - - uint8_t bh = ((scenery->flags & 0xF) << rotation); - flags = bh >> 4; - bh = (bh | flags) & 0xF; - flags = (((scenery->flags >> 5) + rotation) & 3) << 5; - bh |= flags; - - bh |= scenery->flags & 0x90; - - flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 - | GAME_COMMAND_FLAG_GHOST; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) - { - flags = 0; - } - - uint8_t slope = ((bh >> 5) & 0x3) | ((bh >> 2) & 0x4); - uint8_t edges = bh & 0xF; - auto footpathPlaceAction = FootpathPlaceFromTrackAction( - { mapCoord.x, mapCoord.y, z * 8 }, slope, entry_index, edges); - footpathPlaceAction.SetFlags(flags); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&footpathPlaceAction) - : GameActions::QueryNested(&footpathPlaceAction); - // Ignore failures - cost = res->Error == GA_ERROR::OK ? res->Cost : 0; - } - else - { - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) - { - continue; - } - - TileElement* tile_element = map_get_path_element_at(mapCoord.x / 32, mapCoord.y / 32, z); - - if (tile_element == nullptr) - { - continue; - } - - footpath_queue_chain_reset(); - footpath_remove_edges_at(mapCoord.x, mapCoord.y, tile_element); - - flags = GAME_COMMAND_FLAG_APPLY; - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) - { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 - | GAME_COMMAND_FLAG_GHOST; - } - - footpath_connect_edges(mapCoord.x, mapCoord.y, tile_element, flags); - footpath_update_queue_chains(); - continue; - } - break; - default: - _trackDesignPlaceStateSceneryUnavailable = true; - continue; - } - _trackDesignPlaceCost = add_clamp_money32(_trackDesignPlaceCost, cost); - if (_trackDesignPlaceOperation != PTD_OPERATION_PLACE) - { - if (cost == MONEY32_UNDEFINED) - { - _trackDesignPlaceCost = MONEY32_UNDEFINED; - } - } - if (_trackDesignPlaceCost != MONEY32_UNDEFINED) - { - continue; - } - if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE) - { - continue; - } return 0; } } @@ -1202,7 +1241,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE - || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST + || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { uint8_t flags; money32 cost = 0; From 086e60dd1d02d398533d2711e2a4c31b92e851c0 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 27 Mar 2019 20:07:40 +0000 Subject: [PATCH 177/506] Save changes --- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 3b6c6d9dfd..a8e17840f9 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -404,7 +404,7 @@ static void window_track_place_clear_provisional() { auto ride = get_ride(_window_track_place_ride_index); place_virtual_track( - _trackDesign, PTD_OPERATION_CLEAR_OUTLINES, true, ride, _window_track_place_last_valid_x, + _trackDesign, PTD_OPERATION_REMOVE_GHOST, true, ride, _window_track_place_last_valid_x, _window_track_place_last_valid_y, _window_track_place_last_valid_z); _window_track_place_last_was_valid = false; } From 7b2363f0ef00e01346ea09e92ed5aec42f34669a Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 28 Mar 2019 18:02:02 +0000 Subject: [PATCH 178/506] Refactor further --- src/openrct2/ride/TrackDesign.cpp | 106 +++++++----------------------- 1 file changed, 23 insertions(+), 83 deletions(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index e66d69b2c4..d05c429501 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -13,6 +13,7 @@ #include "../Game.h" #include "../OpenRCT2.h" #include "../actions/FootpathPlaceFromTrackAction.hpp" +#include "../actions/FootpathRemoveAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/RideEntranceExitPlaceAction.hpp" #include "../actions/RideSetSetting.hpp" @@ -702,70 +703,22 @@ static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_ gTrackPreviewMax.z = std::max(gTrackPreviewMax.z, z); } -static bool TrackDesignPlaceSceneryTileDrawOutline(LocationXY8 tile) -{ - uint8_t new_tile = 1; - LocationXY16* selectionTile = gMapSelectionTiles; - for (; selectionTile->x != -1; selectionTile++) - { - if (selectionTile->x == tile.x && selectionTile->y == tile.y) - { - new_tile = 0; - break; - } - // Need to subtract one because selectionTile in following block is incremented - if (selectionTile + 1 >= &gMapSelectionTiles[std::size(gMapSelectionTiles) - 1]) - { - new_tile = 0; - break; - } - } - if (new_tile) - { - selectionTile->x = tile.x; - selectionTile->y = tile.y; - selectionTile++; - selectionTile->x = -1; - } - return true; -} - static bool TrackDesignPlaceSceneryTileRemoveGhost( CoordsXY mapCoord, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) { uint8_t entry_type, entry_index; - if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) + if (TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery)) { - entry_type = object_entry_get_type(&scenery->scenery_object); - if (entry_type != OBJECT_TYPE_PATHS) - { - entry_type = 0xFF; - } - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - { - entry_type = 0xFF; - } - - entry_index = 0; - for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_path_surface_entry(entry_index), entry_index++) - { - if (path == nullptr) - { - return true; - } - if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) - { - return true; - } - } - - if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) - { - entry_type = 0xFF; - } + return true; } - int32_t z; + + if (_trackDesignPlaceStateSceneryUnavailable) + { + return true; + } + + int32_t z = (scenery->z * 8 + originZ) / 8; + uint8_t sceneryRotation = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; @@ -773,11 +726,6 @@ static bool TrackDesignPlaceSceneryTileRemoveGhost( { case OBJECT_TYPE_SMALL_SCENERY: { - // bl - rotation += scenery->flags; - rotation &= 3; - - // bh uint8_t quadrant = (scenery->flags >> 2) + _currentTrackPieceDirection; quadrant &= 3; @@ -791,43 +739,34 @@ static bool TrackDesignPlaceSceneryTileRemoveGhost( quadrant = 0; } - z = (scenery->z * 8 + originZ) / 8; - auto removeSceneryAction = SmallSceneryRemoveAction(mapCoord.x, mapCoord.y, z, quadrant, entry_index); removeSceneryAction.SetFlags(flags); - removeSceneryAction.Execute(); - + GameActions::ExecuteNested(&removeSceneryAction); break; } case OBJECT_TYPE_LARGE_SCENERY: { - z = (scenery->z * 8 + originZ) / 8; - - auto removeSceneryAction = LargeSceneryRemoveAction( - mapCoord.x, mapCoord.y, z, (rotation + scenery->flags) & 0x3, 0); + auto removeSceneryAction = LargeSceneryRemoveAction(mapCoord.x, mapCoord.y, z, sceneryRotation, 0); removeSceneryAction.SetFlags(flags); - removeSceneryAction.Execute(); - + GameActions::ExecuteNested(&removeSceneryAction); break; } case OBJECT_TYPE_WALLS: { - z = (scenery->z * 8 + originZ) / 8; - - uint8_t direction = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; - - TileCoordsXYZD wallLocation = { mapCoord.x / 32, mapCoord.y / 32, z, direction }; + TileCoordsXYZD wallLocation = { mapCoord.x / 32, mapCoord.y / 32, z, sceneryRotation }; auto wallRemoveAction = WallRemoveAction(wallLocation); wallRemoveAction.SetFlags(flags); - GameActions::Execute(&wallRemoveAction); - + GameActions::ExecuteNested(&wallRemoveAction); break; } case OBJECT_TYPE_PATHS: - z = (scenery->z * 8 + originZ) / 8; - footpath_remove(mapCoord.x, mapCoord.y, z, flags); + { + auto removeSceneryAction = FootpathRemoveAction(mapCoord.x, mapCoord.y, z); + removeSceneryAction.SetFlags(flags); + GameActions::ExecuteNested(&removeSceneryAction); break; + } } return true; } @@ -892,7 +831,8 @@ static bool TrackDesignPlaceSceneryTile( { if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0) { - return TrackDesignPlaceSceneryTileDrawOutline(tile); + track_design_add_selection_tile(tile.x, tile.y); + return true; } if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0) From 30a51940859bfb23d1c8513ff609ff7e43010b03 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 28 Mar 2019 18:29:51 +0000 Subject: [PATCH 179/506] Use a vector for map selection tiles --- src/openrct2-ui/windows/Footpath.cpp | 6 +- src/openrct2-ui/windows/Map.cpp | 14 +- src/openrct2-ui/windows/RideConstruction.cpp | 33 ++--- src/openrct2-ui/windows/TopToolbar.cpp | 7 +- src/openrct2/paint/VirtualFloor.cpp | 20 +-- .../paint/tile_element/Paint.Surface.cpp | 4 +- src/openrct2/ride/TrackDesign.cpp | 125 ++++++++---------- src/openrct2/world/Map.cpp | 8 +- src/openrct2/world/Map.h | 2 +- 9 files changed, 96 insertions(+), 123 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 52de8443fb..eeab5df7c7 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -1165,9 +1165,9 @@ static void window_footpath_set_enabled_and_pressed_widgets() gMapSelectFlags |= MAP_SELECT_FLAG_GREEN; int32_t direction = gFootpathConstructDirection; - gMapSelectionTiles[0].x = gFootpathConstructFromPosition.x + CoordsDirectionDelta[direction].x; - gMapSelectionTiles[0].y = gFootpathConstructFromPosition.y + CoordsDirectionDelta[direction].y; - gMapSelectionTiles[1].x = -1; + gMapSelectionTiles.clear(); + gMapSelectionTiles.push_back({ gFootpathConstructFromPosition.x + CoordsDirectionDelta[direction].x, + gFootpathConstructFromPosition.y + CoordsDirectionDelta[direction].y }); map_invalidate_map_selection_tiles(); } diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 66fc7d905d..2e70b6a74f 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1235,14 +1235,12 @@ static void window_map_place_park_entrance_tool_update(int32_t x, int32_t y) } sideDirection = (direction + 1) & 3; - gMapSelectionTiles[0].x = mapX; - gMapSelectionTiles[0].y = mapY; - gMapSelectionTiles[1].x = mapX + CoordsDirectionDelta[sideDirection].x; - gMapSelectionTiles[1].y = mapY + CoordsDirectionDelta[sideDirection].y; - gMapSelectionTiles[2].x = mapX - CoordsDirectionDelta[sideDirection].x; - gMapSelectionTiles[2].y = mapY - CoordsDirectionDelta[sideDirection].y; - gMapSelectionTiles[3].x = -1; - gMapSelectionTiles[3].y = -1; + gMapSelectionTiles.clear(); + gMapSelectionTiles.push_back({ mapX, mapY }); + gMapSelectionTiles.push_back( + { mapX + CoordsDirectionDelta[sideDirection].x, mapY + CoordsDirectionDelta[sideDirection].y }); + gMapSelectionTiles.push_back( + { mapX - CoordsDirectionDelta[sideDirection].x, mapY - CoordsDirectionDelta[sideDirection].y }); gMapSelectArrowPosition.x = mapX; gMapSelectArrowPosition.y = mapY; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index c34145b3e9..07d53be375 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -3345,7 +3345,7 @@ static void window_ride_construction_select_map_tiles( trackBlock = get_track_def_from_ride(ride, trackType); trackDirection &= 3; - int32_t selectionTileIndex = 0; + gMapSelectionTiles.clear(); while (trackBlock->index != 255) { switch (trackDirection) @@ -3368,13 +3368,10 @@ static void window_ride_construction_select_map_tiles( offsetY = trackBlock->x; break; } - gMapSelectionTiles[selectionTileIndex].x = x + offsetX; - gMapSelectionTiles[selectionTileIndex].y = y + offsetY; - selectionTileIndex++; + + gMapSelectionTiles.push_back({ x + offsetX, y + offsetY }); trackBlock++; } - gMapSelectionTiles[selectionTileIndex].x = -1; - gMapSelectionTiles[selectionTileIndex].y = -1; } /** @@ -3510,10 +3507,8 @@ void ride_construction_toolupdate_construct(int32_t screenX, int32_t screenY) gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; gMapSelectArrowPosition.z = z; - gMapSelectionTiles[0].x = x; - gMapSelectionTiles[0].y = y; - gMapSelectionTiles[1].x = -1; - gMapSelectionTiles[1].y = -1; + gMapSelectionTiles.clear(); + gMapSelectionTiles.push_back({ x, y }); ride_id_t rideIndex; int32_t trackType, trackDirection, liftHillAndAlternativeState; @@ -3539,16 +3534,14 @@ void ride_construction_toolupdate_construct(int32_t screenX, int32_t screenY) if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { int32_t highestZ = 0; - LocationXY16* selectedTile = gMapSelectionTiles; - while (selectedTile->x != -1) + for (const auto& selectedTile : gMapSelectionTiles) { - if (selectedTile->x < (256 * 32) && selectedTile->y < (256 * 32)) + if (selectedTile.x < (256 * 32) && selectedTile.y < (256 * 32)) { - z = map_get_highest_z(selectedTile->x >> 5, selectedTile->y >> 5); + z = map_get_highest_z(selectedTile.x / 32, selectedTile.y / 32); if (z > highestZ) highestZ = z; } - selectedTile++; } } // loc_6CC8BF: @@ -3764,17 +3757,15 @@ void ride_construction_tooldown_construct(int32_t screenX, int32_t screenY) highestZ = 0; if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { - LocationXY16* selectedTile = gMapSelectionTiles; - while (selectedTile->x != -1) + + for (const auto& selectedTile : gMapSelectionTiles) { - if (selectedTile->x >= (256 * 32) || selectedTile->y >= (256 * 32)) + if (selectedTile.x >= (256 * 32) || selectedTile.y >= (256 * 32)) continue; - z = map_get_highest_z(selectedTile->x >> 5, selectedTile->y >> 5); + z = map_get_highest_z(selectedTile.x / 32, selectedTile.y / 32); if (z > highestZ) highestZ = z; - - selectedTile++; } } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index b1c8fddf82..3f2bf4363f 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2757,7 +2757,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y) case SCENERY_TYPE_LARGE: { scenery = get_large_scenery_entry(selected_scenery); - LocationXY16* selectedTile = gMapSelectionTiles; + gMapSelectionTiles.clear(); for (rct_large_scenery_tile* tile = scenery->large_scenery.tiles; tile->x_offset != (int16_t)(uint16_t)0xFFFF; tile++) @@ -2769,11 +2769,8 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y) tileLocation.x += mapTile.x; tileLocation.y += mapTile.y; - selectedTile->x = tileLocation.x; - selectedTile->y = tileLocation.y; - selectedTile++; + gMapSelectionTiles.push_back({tileLocation.x, tileLocation.y}); } - selectedTile->x = -1; gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_CONSTRUCT; map_invalidate_map_selection_tiles(); diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index ac4cb17e82..5aadd3508a 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -105,12 +105,12 @@ void virtual_floor_invalidate() if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { - for (LocationXY16* tile = gMapSelectionTiles; tile->x != -1; tile++) + for (const auto& tile : gMapSelectionTiles) { - min_position.x = std::min(min_position.x, tile->x); - min_position.y = std::min(min_position.y, tile->y); - max_position.x = std::max(max_position.x, tile->x); - max_position.y = std::max(max_position.y, tile->y); + min_position.x = std::min(min_position.x, tile.x); + min_position.y = std::min(min_position.y, tile.y); + max_position.x = std::max(max_position.x, tile.x); + max_position.y = std::max(max_position.y, tile.y); } } @@ -186,10 +186,10 @@ bool virtual_floor_tile_is_floor(int16_t x, int16_t y) else if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { // Check if we are anywhere near the selection tiles (larger scenery / rides) - for (LocationXY16* tile = gMapSelectionTiles; tile->x != -1; tile++) + for (const auto& tile : gMapSelectionTiles) { - if (x >= tile->x - _virtualFloorBaseSize && y >= tile->y - _virtualFloorBaseSize - && x <= tile->x + _virtualFloorBaseSize && y <= tile->y + _virtualFloorBaseSize) + if (x >= tile.x - _virtualFloorBaseSize && y >= tile.y - _virtualFloorBaseSize + && x <= tile.x + _virtualFloorBaseSize && y <= tile.y + _virtualFloorBaseSize) { return true; } @@ -223,9 +223,9 @@ static void virtual_floor_get_tile_properties( // See if we are on top of the selection tiles if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { - for (LocationXY16* tile = gMapSelectionTiles; tile->x != -1; tile++) + for (const auto& tile : gMapSelectionTiles) { - if (x == tile->x && y == tile->y) + if (x == tile.x && y == tile.y) { *outLit = true; break; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 8833f7b3da..9a74e4e411 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1193,9 +1193,9 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c { const LocationXY16& pos = session->MapPosition; - for (const LocationXY16* tile = gMapSelectionTiles; tile->x != -1; tile++) + for (const auto& tile : gMapSelectionTiles) { - if (tile->x != pos.x || tile->y != pos.y) + if (tile.x != pos.x || tile.y != pos.y) { continue; } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index d05c429501..dd926b6280 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -673,24 +673,14 @@ void track_design_mirror(rct_track_td6* td6) static void track_design_add_selection_tile(int16_t x, int16_t y) { - LocationXY16* selectionTile = gMapSelectionTiles; - // Subtract 2 because the tile gets incremented later on - for (; (selectionTile < gMapSelectionTiles + std::size(gMapSelectionTiles) - 2) && (selectionTile->x != -1); - selectionTile++) + for (const auto tile:gMapSelectionTiles) { - if (selectionTile->x == x && selectionTile->y == y) - { - return; - } - if (selectionTile + 1 >= &gMapSelectionTiles[300]) + if (tile.x == x && tile.y == y) { return; } } - selectionTile->x = x; - selectionTile->y = y; - selectionTile++; - selectionTile->x = -1; + gMapSelectionTiles.push_back(CoordsXY{x,y}); } static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_t z) @@ -703,11 +693,51 @@ static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_ gTrackPreviewMax.z = std::max(gTrackPreviewMax.z, z); } -static bool TrackDesignPlaceSceneryTileRemoveGhost( +static bool TrackDesignPlaceSceneryElementGetEntry(uint8_t& entry_type, uint8_t& entry_index, rct_td6_scenery_element* scenery) +{ + if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) + { + entry_type = object_entry_get_type(&scenery->scenery_object); + if (entry_type != OBJECT_TYPE_PATHS) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + + if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + + entry_index = 0; + for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; + path = get_path_surface_entry(entry_index), entry_index++) + { + if (path == nullptr) + { + return true; + } + if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) + { + return true; + } + } + + if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) + { + _trackDesignPlaceStateSceneryUnavailable = true; + return true; + } + } + return false; +} + +static bool TrackDesignPlaceSceneryElementRemoveGhost( CoordsXY mapCoord, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) { uint8_t entry_type, entry_index; - if (TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery)) + if (TrackDesignPlaceSceneryElementGetEntry(entry_type, entry_index, scenery)) { return true; } @@ -771,48 +801,7 @@ static bool TrackDesignPlaceSceneryTileRemoveGhost( return true; } -static bool TrackDesignPlaceSceneryTileGetEntry(uint8_t& entry_type, uint8_t& entry_index, rct_td6_scenery_element* scenery) -{ - uint8_t entry_type, entry_index; - if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) - { - entry_type = object_entry_get_type(&scenery->scenery_object); - if (entry_type != OBJECT_TYPE_PATHS) - { - _trackDesignPlaceStateSceneryUnavailable = true; - return true; - } - - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - { - _trackDesignPlaceStateSceneryUnavailable = true; - return true; - } - - entry_index = 0; - for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_path_surface_entry(entry_index), entry_index++) - { - if (path == nullptr) - { - return true; - } - if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) - { - return true; - } - } - - if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS]) - { - _trackDesignPlaceStateSceneryUnavailable = true; - return true; - } - } - return false; -} - -static bool TrackDesignPlaceSceneryTileGetPlaceZ(rct_td6_scenery_element* scenery) +static bool TrackDesignPlaceSceneryElementGetPlaceZ(rct_td6_scenery_element* scenery) { int32_t z = scenery->z * 8 + _trackDesignPlaceZ; if (z < _trackDesignPlaceSceneryZ) @@ -821,28 +810,28 @@ static bool TrackDesignPlaceSceneryTileGetPlaceZ(rct_td6_scenery_element* scener } uint8_t entry_type, entry_index; - TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery); + TrackDesignPlaceSceneryElementGetEntry(entry_type, entry_index, scenery); return true; } -static bool TrackDesignPlaceSceneryTile( +static bool TrackDesignPlaceSceneryElement( CoordsXY mapCoord, LocationXY8 tile, uint8_t mode, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) { if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0) { - track_design_add_selection_tile(tile.x, tile.y); + track_design_add_selection_tile(mapCoord.x, mapCoord.y); return true; } if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0) { - return TrackDesignPlaceSceneryTileRemoveGhost(mapCoord, scenery, rotation, originZ); + return TrackDesignPlaceSceneryElementRemoveGhost(mapCoord, scenery, rotation, originZ); } if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z) { - return TrackDesignPlaceSceneryTileGetPlaceZ(scenery); + return TrackDesignPlaceSceneryElementGetPlaceZ(scenery); } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE @@ -850,7 +839,7 @@ static bool TrackDesignPlaceSceneryTile( || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { uint8_t entry_type, entry_index; - if (TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery)) + if (TrackDesignPlaceSceneryElementGetEntry(entry_type, entry_index, scenery)) { return true; } @@ -1097,7 +1086,7 @@ static bool TrackDesignPlaceSceneryTile( * * rct2: 0x006D0964 */ -static int32_t track_design_place_scenery( +static int32_t track_design_place_all_scenery( rct_td6_scenery_element* scenery_start, int32_t originX, int32_t originY, int32_t originZ) { for (uint8_t mode = 0; mode <= 1; mode++) @@ -1139,7 +1128,7 @@ static int32_t track_design_place_scenery( CoordsXY mapCoord = { tile.x * 32, tile.y * 32 }; track_design_update_max_min_coordinates(mapCoord.x, mapCoord.y, originZ); - if (!TrackDesignPlaceSceneryTile(mapCoord, tile, mode, scenery, rotation, originZ)) + if (!TrackDesignPlaceSceneryElement(mapCoord, tile, mode, scenery, rotation, originZ)) { return 0; } @@ -1152,7 +1141,7 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES) { - gMapSelectionTiles->x = -1; + gMapSelectionTiles.clear(); gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; gMapSelectArrowPosition.z = tile_element_height(x, y) & 0xFFFF; @@ -1366,7 +1355,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in gTrackPreviewOrigin.z = z; if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES) { - gMapSelectionTiles->x = -1; + gMapSelectionTiles.clear(); gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; gMapSelectArrowPosition.z = tile_element_height(x, y) & 0xFFFF; @@ -1698,7 +1687,7 @@ int32_t place_virtual_track( rct_td6_scenery_element* scenery = td6->scenery_elements; if (track_place_success && scenery != nullptr) { - if (!track_design_place_scenery(scenery, gTrackPreviewOrigin.x, gTrackPreviewOrigin.y, gTrackPreviewOrigin.z)) + if (!track_design_place_all_scenery(scenery, gTrackPreviewOrigin.x, gTrackPreviewOrigin.y, gTrackPreviewOrigin.z)) { return _trackDesignPlaceCost; } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 3d39d6e68c..83762955bc 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -88,7 +88,7 @@ int16_t gMapBaseZ; TileElement gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3]; TileElement* gTileElementTilePointers[MAX_TILE_TILE_ELEMENT_POINTERS]; -LocationXY16 gMapSelectionTiles[300]; +std::vector gMapSelectionTiles; std::vector gPeepSpawns; TileElement* gNextFreeTileElement; @@ -1394,13 +1394,11 @@ void map_remove_all_rides() */ void map_invalidate_map_selection_tiles() { - LocationXY16* position; - if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)) return; - for (position = gMapSelectionTiles; position->x != -1; position++) - map_invalidate_tile_full(position->x, position->y); + for (const auto& position : gMapSelectionTiles) + map_invalidate_tile_full(position.x, position.y); } void map_get_bounding_box( diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 3328e74d56..90a907d653 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -107,7 +107,7 @@ extern uint8_t gMapGroundFlags; extern TileElement gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3]; extern TileElement* gTileElementTilePointers[MAX_TILE_TILE_ELEMENT_POINTERS]; -extern LocationXY16 gMapSelectionTiles[300]; +extern std::vector gMapSelectionTiles; extern std::vector gPeepSpawns; extern TileElement* gNextFreeTileElement; From 561ce03d18d7586a62d024527295611f2860a6f6 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 1 Apr 2019 17:53:56 +0100 Subject: [PATCH 180/506] Fix formatting --- src/openrct2-ui/windows/RideConstruction.cpp | 1 - src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 07d53be375..92386480ee 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -3757,7 +3757,6 @@ void ride_construction_tooldown_construct(int32_t screenX, int32_t screenY) highestZ = 0; if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT) { - for (const auto& selectedTile : gMapSelectionTiles) { if (selectedTile.x >= (256 * 32) || selectedTile.y >= (256 * 32)) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 3f2bf4363f..c15c5bc028 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2769,7 +2769,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y) tileLocation.x += mapTile.x; tileLocation.y += mapTile.y; - gMapSelectionTiles.push_back({tileLocation.x, tileLocation.y}); + gMapSelectionTiles.push_back({ tileLocation.x, tileLocation.y }); } gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_CONSTRUCT; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index dd926b6280..d4b5e1b804 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -673,14 +673,14 @@ void track_design_mirror(rct_track_td6* td6) static void track_design_add_selection_tile(int16_t x, int16_t y) { - for (const auto tile:gMapSelectionTiles) + for (const auto tile : gMapSelectionTiles) { if (tile.x == x && tile.y == y) { return; } } - gMapSelectionTiles.push_back(CoordsXY{x,y}); + gMapSelectionTiles.push_back(CoordsXY{ x, y }); } static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_t z) @@ -791,12 +791,12 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost( break; } case OBJECT_TYPE_PATHS: - { + { auto removeSceneryAction = FootpathRemoveAction(mapCoord.x, mapCoord.y, z); removeSceneryAction.SetFlags(flags); GameActions::ExecuteNested(&removeSceneryAction); break; - } + } } return true; } From 06645f6a0db34948feb759bbba6f36cb22222740 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 1 Apr 2019 18:30:34 +0100 Subject: [PATCH 181/506] Further small refactor. Name Game_command_flag_5 --- src/openrct2/ride/TrackDesign.cpp | 34 ++++++++++--------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index d4b5e1b804..6da8108ba0 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -751,7 +751,7 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost( uint8_t sceneryRotation = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; - + std::unique_ptr ga; switch (entry_type) { case OBJECT_TYPE_SMALL_SCENERY: @@ -763,41 +763,29 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost( if (!(!scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_FULL_TILE) && scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_DIAGONAL)) && scenery_small_entry_has_flag( - small_scenery, - SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS)) + small_scenery, + SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS)) { quadrant = 0; } - auto removeSceneryAction = SmallSceneryRemoveAction(mapCoord.x, mapCoord.y, z, quadrant, entry_index); - removeSceneryAction.SetFlags(flags); - GameActions::ExecuteNested(&removeSceneryAction); + ga = std::make_unique(mapCoord.x, mapCoord.y, z, quadrant, entry_index); break; } case OBJECT_TYPE_LARGE_SCENERY: - { - auto removeSceneryAction = LargeSceneryRemoveAction(mapCoord.x, mapCoord.y, z, sceneryRotation, 0); - removeSceneryAction.SetFlags(flags); - GameActions::ExecuteNested(&removeSceneryAction); + ga = std::make_unique(mapCoord.x, mapCoord.y, z, sceneryRotation, 0); break; - } case OBJECT_TYPE_WALLS: - { - TileCoordsXYZD wallLocation = { mapCoord.x / 32, mapCoord.y / 32, z, sceneryRotation }; - auto wallRemoveAction = WallRemoveAction(wallLocation); - wallRemoveAction.SetFlags(flags); - - GameActions::ExecuteNested(&wallRemoveAction); + ga = std::make_unique(TileCoordsXYZD{ mapCoord.x / 32, mapCoord.y / 32, z, sceneryRotation }); break; - } case OBJECT_TYPE_PATHS: - { - auto removeSceneryAction = FootpathRemoveAction(mapCoord.x, mapCoord.y, z); - removeSceneryAction.SetFlags(flags); - GameActions::ExecuteNested(&removeSceneryAction); + ga = std::make_unique(mapCoord.x, mapCoord.y, z); break; - } + default: + return true; } + ga->SetFlags(flags); + GameActions::ExecuteNested(ga.get()); return true; } From 356a0e5e911c13481d5ec37e2a586ca3e1d18f65 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 1 Apr 2019 18:58:16 +0100 Subject: [PATCH 182/506] Rework flags --- src/openrct2-ui/windows/LandRights.cpp | 2 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- src/openrct2/Game.cpp | 6 +-- src/openrct2/Game.h | 12 ++--- .../actions/FootpathSceneryPlaceAction.hpp | 6 --- src/openrct2/actions/GameAction.cpp | 4 +- src/openrct2/actions/GameAction.h | 2 +- src/openrct2/actions/MazeSetTrackAction.hpp | 2 +- src/openrct2/actions/RideDemolishAction.hpp | 2 +- src/openrct2/actions/TrackPlaceAction.hpp | 2 +- src/openrct2/management/Finance.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 4 +- src/openrct2/ride/TrackDesign.cpp | 48 +++++++++---------- src/openrct2/windows/_legacy.cpp | 4 +- src/openrct2/world/Footpath.cpp | 2 +- src/openrct2/world/Scenery.cpp | 6 +-- 17 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index c7ae24657e..1e3f5c9473 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -365,7 +365,7 @@ static void window_land_rights_tool_update_land_rights(int16_t x, int16_t y) return; _landRightsCost = game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_2, gMapSelectPositionA.y, + gMapSelectPositionA.x, GAME_COMMAND_FLAG_NO_SPEND, gMapSelectPositionA.y, (_landRightsMode == LAND_RIGHTS_MODE_BUY_LAND) ? BUY_LAND_RIGHTS_FLAG_BUY_LAND : BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y); diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index a8e17840f9..36a418bec6 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -283,7 +283,7 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI for (int32_t i = 0; i < 7; i++) { ride_id_t rideIndex; - uint16_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; + uint16_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; window_track_place_attempt_placement(_trackDesign, mapX, mapY, mapZ, flags, &cost, &rideIndex); if (cost != MONEY32_UNDEFINED) { diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 4aab2a6511..e8ffca0389 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -445,7 +445,7 @@ int32_t game_do_command_p( { // Check funds int32_t insufficientFunds = 0; - if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_2) && !(flags & GAME_COMMAND_FLAG_5) && cost != 0) + if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_NO_SPEND) && cost != 0) insufficientFunds = game_check_affordability(cost, flags); if (insufficientFunds != MONEY32_UNDEFINED) @@ -464,7 +464,7 @@ int32_t game_do_command_p( } if (network_get_mode() != NETWORK_MODE_NONE && !(flags & GAME_COMMAND_FLAG_NETWORKED) - && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5) + && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND) && gGameCommandNestLevel == 1) /* Send only top-level commands */ { network_send_gamecmd( @@ -487,7 +487,7 @@ int32_t game_do_command_p( { bool recordCommand = false; bool commandExecutes = (flags & GAME_COMMAND_FLAG_APPLY) && (flags & GAME_COMMAND_FLAG_GHOST) == 0 - && (flags & GAME_COMMAND_FLAG_5) == 0; + && (flags & GAME_COMMAND_FLAG_NO_SPEND) == 0; if (replayManager->IsRecording() && commandExecutes) recordCommand = true; diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 0034c6119a..5ccde16a38 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -103,13 +103,13 @@ enum GAME_COMMAND enum : uint32_t { - GAME_COMMAND_FLAG_APPLY = (1 << 0), // If this flag is set, the command is applied, otherwise only the cost is retrieved - GAME_COMMAND_FLAG_REPLAY = (1 << 1), // Command was issued from replay manager. - GAME_COMMAND_FLAG_2 = (1 << 2), + GAME_COMMAND_FLAG_APPLY = (1 << 0), // If this flag is set, the command is applied, otherwise only the cost is retrieved + GAME_COMMAND_FLAG_REPLAY = (1 << 1), // Command was issued from replay manager. + GAME_COMMAND_FLAG_2 = (1 << 2), // Unused GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED = (1 << 3), // Allow while paused - GAME_COMMAND_FLAG_4 = (1 << 4), - GAME_COMMAND_FLAG_5 = (1 << 5), - GAME_COMMAND_FLAG_GHOST = (1 << 6), + GAME_COMMAND_FLAG_4 = (1 << 4), // Unused + GAME_COMMAND_FLAG_NO_SPEND = (1 << 5), // Game command is not networked + GAME_COMMAND_FLAG_GHOST = (1 << 6), // Game command is not networked GAME_COMMAND_FLAG_PATH_SCENERY = (1 << 7), GAME_COMMAND_FLAG_NETWORKED = (1u << 31) // Game command is coming from network }; diff --git a/src/openrct2/actions/FootpathSceneryPlaceAction.hpp b/src/openrct2/actions/FootpathSceneryPlaceAction.hpp index aee3269473..b8fc4e21e2 100644 --- a/src/openrct2/actions/FootpathSceneryPlaceAction.hpp +++ b/src/openrct2/actions/FootpathSceneryPlaceAction.hpp @@ -87,9 +87,6 @@ public: if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAddition() == _pathItemType && !(pathElement->IsBroken())) { - if (GetFlags() & GAME_COMMAND_FLAG_4) - return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_POSITION_THIS_HERE); - return res; } @@ -129,9 +126,6 @@ public: res->Cost = sceneryEntry->path_bit.price; } - if (GetFlags() & GAME_COMMAND_FLAG_4) - return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_POSITION_THIS_HERE); - // Should place a ghost? if (GetFlags() & GAME_COMMAND_FLAG_GHOST) { diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 38b797778c..b7e078d671 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -326,7 +326,7 @@ namespace GameActions } else if (network_get_mode() == NETWORK_MODE_NONE) { - bool commandExecutes = (flags & GAME_COMMAND_FLAG_GHOST) == 0 && (flags & GAME_COMMAND_FLAG_5) == 0; + bool commandExecutes = (flags & GAME_COMMAND_FLAG_GHOST) == 0 && (flags & GAME_COMMAND_FLAG_NO_SPEND) == 0; bool recordAction = false; if (replayManager) @@ -358,7 +358,7 @@ namespace GameActions } // Only show errors when its not a ghost and not a preview and also top level action. - bool shouldShowError = !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5) && topLevel == true; + bool shouldShowError = !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND) && topLevel == true; // In network mode the error should be only shown to the issuer of the action. if (network_get_mode() != NETWORK_MODE_NONE) diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index 6792c8c348..352bcab7bb 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -126,7 +126,7 @@ public: // Make sure we execute some things only on the client. uint16_t flags = 0; - if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) != 0 || (GetFlags() & GAME_COMMAND_FLAG_5) != 0) + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) != 0 || (GetFlags() & GAME_COMMAND_FLAG_NO_SPEND) != 0) { flags |= GA_FLAGS::CLIENT_ONLY; } diff --git a/src/openrct2/actions/MazeSetTrackAction.hpp b/src/openrct2/actions/MazeSetTrackAction.hpp index 431dfb3017..7a0767bdd4 100644 --- a/src/openrct2/actions/MazeSetTrackAction.hpp +++ b/src/openrct2/actions/MazeSetTrackAction.hpp @@ -202,7 +202,7 @@ public: } uint32_t flags = GetFlags(); - if (!(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_2)) + if (!(flags & GAME_COMMAND_FLAG_GHOST)) { footpath_remove_litter(_x, _y, _z); wall_remove_at(floor2(_x, 32), floor2(_y, 32), _z, _z + 32); diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 3264f5ee1f..bca4f79d94 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -308,7 +308,7 @@ private: { auto trackRemoveAction = TrackRemoveAction( type, it.element->AsTrack()->GetSequenceIndex(), { x, y, z, rotation }); - trackRemoveAction.SetFlags(GAME_COMMAND_FLAG_5); + trackRemoveAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND); auto removRes = GameActions::ExecuteNested(&trackRemoveAction); diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index f413a3170f..d55e38745f 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -566,7 +566,7 @@ public: int32_t entranceDirections = 0; if (ride->overall_view.xy != RCT_XY8_UNDEFINED) { - if (!(GetFlags() & GAME_COMMAND_FLAG_5)) + if (!(GetFlags() & GAME_COMMAND_FLAG_NO_SPEND)) { if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE)) { diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index d0d541a048..dcacab3d7f 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -75,7 +75,7 @@ bool finance_check_money_required(uint32_t flags) return false; if (gScreenFlags & SCREEN_FLAGS_EDITOR) return false; - if (flags & GAME_COMMAND_FLAG_5) + if (flags & GAME_COMMAND_FLAG_NO_SPEND) return false; if (flags & GAME_COMMAND_FLAG_GHOST) return false; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index af6cf9d4c8..65fb451999 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2778,7 +2778,7 @@ private: auto wallPlaceAction = WallPlaceAction( type, { x * 32, y * 32, 0 }, edge, colourA, colourB, colourC); wallPlaceAction.SetFlags( - GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_PATH_SCENERY); GameActions::Execute(&wallPlaceAction); } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9d32efe96c..a8612f4f28 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -1451,7 +1451,7 @@ void ride_remove_provisional_track_piece() ride = get_ride(rideIndex); if (ride->type == RIDE_TYPE_MAZE) { - int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; maze_set_track(x, y, z, flags, false, 0, rideIndex, GC_SET_MAZE_TRACK_FILL); maze_set_track(x, y + 16, z, flags, false, 1, rideIndex, GC_SET_MAZE_TRACK_FILL); @@ -1474,7 +1474,7 @@ void ride_remove_provisional_track_piece() auto trackRemoveAction = TrackRemoveAction{ trackType, trackSequence, { next_track.x, next_track.y, z, static_cast(direction) } }; - trackRemoveAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + trackRemoveAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); GameActions::Execute(&trackRemoveAction); } } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 6da8108ba0..586c792461 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -749,7 +749,7 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost( int32_t z = (scenery->z * 8 + originZ) / 8; uint8_t sceneryRotation = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK; - const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + const uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; std::unique_ptr ga; switch (entry_type) @@ -859,12 +859,12 @@ static bool TrackDesignPlaceSceneryElement( if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { @@ -903,12 +903,12 @@ static bool TrackDesignPlaceSceneryElement( if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { @@ -943,11 +943,11 @@ static bool TrackDesignPlaceSceneryElement( if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) @@ -990,11 +990,11 @@ static bool TrackDesignPlaceSceneryElement( flags = GAME_COMMAND_FLAG_APPLY; if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) @@ -1032,11 +1032,11 @@ static bool TrackDesignPlaceSceneryElement( flags = GAME_COMMAND_FLAG_APPLY; if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } @@ -1183,11 +1183,11 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(mapCoord, rotation, ride->id, 0, false); @@ -1217,11 +1217,11 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(mapCoord, rotation, ride->id, 0, true); @@ -1239,11 +1239,11 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) @@ -1324,7 +1324,7 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { ride_action_modify( ride, RIDE_MODIFY_DEMOLISH, - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); } gTrackPreviewOrigin.x = x; @@ -1384,7 +1384,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in int32_t tempZ = z - trackCoordinates->z_begin + trackBlock->z; auto trackRemoveAction = TrackRemoveAction(trackType, 0, { x, y, tempZ, static_cast(rotation & 3) }); trackRemoveAction.SetFlags( - GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); GameActions::ExecuteNested(&trackRemoveAction); break; } @@ -1415,12 +1415,12 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { flags |= GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; - flags |= GAME_COMMAND_FLAG_5; + flags |= GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { flags |= GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; - flags |= GAME_COMMAND_FLAG_5; + flags |= GAME_COMMAND_FLAG_NO_SPEND; flags |= GAME_COMMAND_FLAG_GHOST; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) @@ -1563,11 +1563,11 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in uint8_t flags = GAME_COMMAND_FLAG_APPLY; if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) @@ -1718,7 +1718,7 @@ static bool track_design_place_preview(rct_track_td6* td6, money32* cost, Ride** ride_id_t rideIndex; uint8_t colour; - uint8_t rideCreateFlags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + uint8_t rideCreateFlags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; if (ride_create_command(td6->type, entry_index, rideCreateFlags, &rideIndex, &colour) == MONEY32_UNDEFINED) { return false; diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index 459ca7a1e5..c00e4026a5 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -104,7 +104,7 @@ money32 place_provisional_track_piece( ride = get_ride(rideIndex); if (ride->type == RIDE_TYPE_MAZE) { - int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 + int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; // 105 result = maze_set_track(x, y, z, flags, true, 0, rideIndex, GC_SET_MAZE_TRACK_BUILD); if (result == MONEY32_UNDEFINED) @@ -134,7 +134,7 @@ money32 place_provisional_track_piece( { auto trackPlaceAction = TrackPlaceAction( rideIndex, trackType, { x, y, z, static_cast(trackDirection) }, 0, 0, 0, liftHillAndAlternativeState); - trackPlaceAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + trackPlaceAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); // This command must not be sent over the network auto res = GameActions::Execute(&trackPlaceAction); result = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index a0dca55acf..c0418d886b 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -229,7 +229,7 @@ void footpath_provisional_remove() footpath_remove( gFootpathProvisionalPosition.x, gFootpathProvisionalPosition.y, gFootpathProvisionalPosition.z, - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); } } diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 7b233eddab..ef637ca3c4 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -189,7 +189,7 @@ void scenery_remove_ghost_tool_placement() gSceneryGhostType &= ~SCENERY_GHOST_FLAG_0; auto removeSceneryAction = SmallSceneryRemoveAction(x, y, z, gSceneryQuadrant, gSceneryPlaceObject); - removeSceneryAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST); + removeSceneryAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); removeSceneryAction.Execute(); } @@ -229,7 +229,7 @@ void scenery_remove_ghost_tool_placement() auto removeSceneryAction = LargeSceneryRemoveAction(x, y, z, gSceneryPlaceRotation, 0); removeSceneryAction.SetFlags( - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); removeSceneryAction.Execute(); } @@ -237,7 +237,7 @@ void scenery_remove_ghost_tool_placement() { gSceneryGhostType &= ~SCENERY_GHOST_FLAG_4; constexpr uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_5; + | GAME_COMMAND_FLAG_NO_SPEND; game_do_command(x, flags, y, z | (gSceneryPlaceRotation << 8), GAME_COMMAND_REMOVE_BANNER, 0, 0); } } From 52807287605abe00600d5d2293651fbb75b3060b Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 2 Apr 2019 18:17:37 +0100 Subject: [PATCH 183/506] Fix formatting --- src/openrct2/Game.h | 6 +++--- src/openrct2/ride/Ride.cpp | 3 ++- src/openrct2/ride/TrackDesign.cpp | 12 ++++++++---- src/openrct2/world/Footpath.cpp | 3 ++- src/openrct2/world/Scenery.cpp | 6 ++++-- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 5ccde16a38..c2750066e5 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -103,9 +103,9 @@ enum GAME_COMMAND enum : uint32_t { - GAME_COMMAND_FLAG_APPLY = (1 << 0), // If this flag is set, the command is applied, otherwise only the cost is retrieved - GAME_COMMAND_FLAG_REPLAY = (1 << 1), // Command was issued from replay manager. - GAME_COMMAND_FLAG_2 = (1 << 2), // Unused + GAME_COMMAND_FLAG_APPLY = (1 << 0), // If this flag is set, the command is applied, otherwise only the cost is retrieved + GAME_COMMAND_FLAG_REPLAY = (1 << 1), // Command was issued from replay manager. + GAME_COMMAND_FLAG_2 = (1 << 2), // Unused GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED = (1 << 3), // Allow while paused GAME_COMMAND_FLAG_4 = (1 << 4), // Unused GAME_COMMAND_FLAG_NO_SPEND = (1 << 5), // Game command is not networked diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index a8612f4f28..3a951724ac 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -1474,7 +1474,8 @@ void ride_remove_provisional_track_piece() auto trackRemoveAction = TrackRemoveAction{ trackType, trackSequence, { next_track.x, next_track.y, z, static_cast(direction) } }; - trackRemoveAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); + trackRemoveAction.SetFlags( + GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); GameActions::Execute(&trackRemoveAction); } } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 586c792461..560c804258 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1183,7 +1183,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { @@ -1217,7 +1218,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_NO_SPEND; } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { @@ -1324,7 +1326,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, { ride_action_modify( ride, RIDE_MODIFY_DEMOLISH, - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND + | GAME_COMMAND_FLAG_GHOST); } gTrackPreviewOrigin.x = x; @@ -1563,7 +1566,8 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in uint8_t flags = GAME_COMMAND_FLAG_APPLY; if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW) { - flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND; + flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_NO_SPEND; } if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST) { diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index c0418d886b..b734b1cef0 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -229,7 +229,8 @@ void footpath_provisional_remove() footpath_remove( gFootpathProvisionalPosition.x, gFootpathProvisionalPosition.y, gFootpathProvisionalPosition.z, - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND + | GAME_COMMAND_FLAG_GHOST); } } diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index ef637ca3c4..022197a0f4 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -189,7 +189,8 @@ void scenery_remove_ghost_tool_placement() gSceneryGhostType &= ~SCENERY_GHOST_FLAG_0; auto removeSceneryAction = SmallSceneryRemoveAction(x, y, z, gSceneryQuadrant, gSceneryPlaceObject); - removeSceneryAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); + removeSceneryAction.SetFlags( + GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); removeSceneryAction.Execute(); } @@ -229,7 +230,8 @@ void scenery_remove_ghost_tool_placement() auto removeSceneryAction = LargeSceneryRemoveAction(x, y, z, gSceneryPlaceRotation, 0); removeSceneryAction.SetFlags( - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED + | GAME_COMMAND_FLAG_NO_SPEND); removeSceneryAction.Execute(); } From eedb24700d73c5485e0f7c35b4b3a8433feef8d0 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 2 Apr 2019 18:33:14 +0100 Subject: [PATCH 184/506] Fix #8535, #8480. Unintialised variable used to get path object. When you try to mirror a track design that has a path object type that isn't loaded it will try to pass an uninitialised variable as the index of the path object. This will cause a bad pointer to be generated. Fix was to auto set it to zero and to be super careful reset it again to zero in the case when its not available --- src/openrct2/ride/TrackDesign.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 560c804258..b9954db94a 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -494,7 +494,7 @@ static void track_design_mirror_scenery(rct_track_td6* td6) rct_td6_scenery_element* scenery = td6->scenery_elements; for (; scenery != nullptr && scenery->scenery_object.end_flag != 0xFF; scenery++) { - uint8_t entry_type, entry_index; + uint8_t entry_type{ 0 }, entry_index{ 0 }; if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) { entry_type = object_entry_get_type(&scenery->scenery_object); @@ -502,6 +502,8 @@ static void track_design_mirror_scenery(rct_track_td6* td6) { continue; } + + entry_index = 0; } rct_scenery_entry* scenery_entry = (rct_scenery_entry*)object_entry_get_chunk(entry_type, entry_index); From cee953f899ac1cb23cf176eada6fd95f0e87df5d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 4 Apr 2019 19:20:55 +0100 Subject: [PATCH 185/506] Fix #9042. Pass the flags to wall placement when in track design mode --- src/openrct2/ride/TrackDesign.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index b9954db94a..35debd6efe 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -960,6 +960,7 @@ static bool TrackDesignPlaceSceneryElement( auto wallPlaceAction = WallPlaceAction( entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, scenery->secondary_colour, scenery->flags & 0xFC); + wallPlaceAction.SetFlags(flags); auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction) : GameActions::Query(&wallPlaceAction); From 3e9356857f6677cd1cea26ac07bf356dde21b4c9 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 18:06:40 +0100 Subject: [PATCH 186/506] Fix wall placement in track designs. X and Y values go a bit screwey in ride previews. So you need to override there check. Also fixed the wall from nesting the command wrong --- src/openrct2/actions/WallPlaceAction.hpp | 5 +++-- src/openrct2/ride/TrackDesign.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 62bb6835bf..e2c55ee387 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -14,6 +14,7 @@ #include "../ride/RideGroupManager.h" #include "../ride/Track.h" #include "../ride/TrackData.h" +#include "../ride/TrackDesign.h" #include "../world/Banner.h" #include "../world/LargeScenery.h" #include "../world/MapAnimation.h" @@ -71,7 +72,7 @@ public: res->Position.x += 16; res->Position.y += 16; - if (res->Position.z == 0) + if (_loc.z == 0) { res->Position.z = tile_element_height(res->Position.x, res->Position.y) & 0xFFFF; } @@ -91,7 +92,7 @@ public: return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); } } - else if ((_loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)) + else if (!byte_9D8150 && (_loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)) { log_error("Invalid x/y coordinates. x = %d y = %d", _loc.x, _loc.y); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 35debd6efe..f9091f7a42 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -961,8 +961,8 @@ static bool TrackDesignPlaceSceneryElement( entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, scenery->secondary_colour, scenery->flags & 0xFC); wallPlaceAction.SetFlags(flags); - auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction) - : GameActions::Query(&wallPlaceAction); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&wallPlaceAction) + : GameActions::QueryNested(&wallPlaceAction); cost = res->Cost; break; From 787993c117fddc4e2f7c9b186d0085080053fe7d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 18:16:24 +0100 Subject: [PATCH 187/506] Fix #9062. Pass the correct flag for ghosts. --- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index c15c5bc028..d34d6c42b9 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2515,7 +2515,7 @@ static money32 try_place_ghost_scenery( auto wallPlaceAction = WallPlaceAction( type, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); wallPlaceAction.SetFlags( - GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_PATH_SCENERY); + GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { if (result->Error != GA_ERROR::OK) return; From 63f9e3dbb4322ff8c9be3b711a89fef7275c35e4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 18:56:44 +0100 Subject: [PATCH 188/506] Set tertiary colour correctly --- src/openrct2/ride/TrackDesign.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index f9091f7a42..bc724828b5 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -959,7 +959,7 @@ static bool TrackDesignPlaceSceneryElement( auto wallPlaceAction = WallPlaceAction( entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, scenery->secondary_colour, - scenery->flags & 0xFC); + (scenery->flags & 0xFC) >> 2); wallPlaceAction.SetFlags(flags); auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&wallPlaceAction) : GameActions::QueryNested(&wallPlaceAction); From 8fc1d7023980e55596a62cdcc5ef1ed2e213a469 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 15:59:40 +0100 Subject: [PATCH 189/506] Implement small scenery set colour action --- src/openrct2-ui/windows/TopToolbar.cpp | 11 +- src/openrct2/Game.cpp | 7 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/SmallScenerySetColourAction.hpp | 116 ++++++++++++++++++ src/openrct2/world/Map.h | 2 - src/openrct2/world/SmallScenery.cpp | 54 -------- 7 files changed, 128 insertions(+), 66 deletions(-) create mode 100644 src/openrct2/actions/SmallScenerySetColourAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index d34d6c42b9..d36b17e501 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1010,11 +1011,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg return; uint8_t quadrant = tile_element->AsSmallScenery()->GetSceneryQuadrant(); - gGameCommandErrorTitle = STR_CANT_REPAINT_THIS; - game_do_command( - grid_x, GAME_COMMAND_FLAG_APPLY | quadrant << 8, grid_y, - tile_element->base_height | (tile_element->AsSmallScenery()->GetEntryIndex() << 8), - GAME_COMMAND_SET_SCENERY_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8)); + auto repaintScenery = SmallScenerySetColourAction( + { grid_x, grid_y, tile_element->base_height * 8 }, quadrant, tile_element->AsSmallScenery()->GetEntryIndex(), + gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour); + + GameActions::Execute(&repaintScenery); break; } case VIEWPORT_INTERACTION_ITEM_WALL: diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index e8ffca0389..80ce37e882 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -644,9 +644,8 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c network_append_server_log(log_msg); } else if ( - command == GAME_COMMAND_SET_SCENERY_COLOUR || command == GAME_COMMAND_SET_WALL_COLOUR - || command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR || command == GAME_COMMAND_SET_BANNER_COLOUR - || command == GAME_COMMAND_SET_BANNER_STYLE) + command == GAME_COMMAND_SET_WALL_COLOUR || command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR + || command == GAME_COMMAND_SET_BANNER_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE) { // Log editing scenery char* args[1] = { @@ -1292,7 +1291,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_place_maze_design, game_command_place_banner, game_command_remove_banner, - game_command_set_scenery_colour, + nullptr, game_command_set_wall_colour, game_command_set_large_scenery_colour, game_command_set_banner_colour, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index c2750066e5..ed90316eb2 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -71,7 +71,7 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_MAZE_DESIGN, GAME_COMMAND_PLACE_BANNER, GAME_COMMAND_REMOVE_BANNER, - GAME_COMMAND_SET_SCENERY_COLOUR, + GAME_COMMAND_SET_SCENERY_COLOUR, // GA GAME_COMMAND_SET_WALL_COLOUR, GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, GAME_COMMAND_SET_BANNER_COLOUR, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index cda9214e33..ccb7ea18c8 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -51,6 +51,7 @@ #include "SignSetStyleAction.hpp" #include "SmallSceneryPlaceAction.hpp" #include "SmallSceneryRemoveAction.hpp" +#include "SmallScenerySetColourAction.hpp" #include "StaffFireAction.hpp" #include "StaffHireNewAction.hpp" #include "StaffSetColourAction.hpp" @@ -115,6 +116,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/SmallScenerySetColourAction.hpp b/src/openrct2/actions/SmallScenerySetColourAction.hpp new file mode 100644 index 0000000000..8f30ffd604 --- /dev/null +++ b/src/openrct2/actions/SmallScenerySetColourAction.hpp @@ -0,0 +1,116 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../OpenRCT2.h" +#include "../common.h" +#include "../core/MemoryStream.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/Ride.h" +#include "../ride/TrackDesign.h" +#include "../world/MapAnimation.h" +#include "../world/Park.h" +#include "../world/SmallScenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "../world/TileElement.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(SmallScenerySetColourAction, GAME_COMMAND_SET_SCENERY_COLOUR, GameActionResult) +{ +private: + CoordsXYZ _loc; + uint8_t _quadrant; + uint8_t _sceneryType; + uint8_t _primaryColour; + uint8_t _secondaryColour; + +public: + SmallScenerySetColourAction() = default; + + SmallScenerySetColourAction( + CoordsXYZ loc, uint8_t quadrant, uint8_t sceneryType, uint8_t primaryColour, uint8_t secondaryColour) + : _loc(loc) + , _quadrant(quadrant) + , _sceneryType(sceneryType) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_quadrant) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) + << DS_TAG(_secondaryColour); + } + + 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(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ErrorTitle = STR_CANT_REPAINT_THIS; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_owned(_loc.x, _loc.y, _loc.z)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + } + + auto sceneryElement = map_get_small_scenery_element_at(_loc.x, _loc.y, _loc.z / 8, _sceneryType, _quadrant); + + if (sceneryElement == nullptr) + { + log_error("Small scenery not found at: x = %d, y = %d, z = %d", _loc.x, _loc.y, _loc.z); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(sceneryElement->IsGhost())) + { + return res; + } + + if (isExecuting) + { + sceneryElement->SetPrimaryColour(_primaryColour); + sceneryElement->SetSecondaryColour(_secondaryColour); + + map_invalidate_tile_full(_loc.x, _loc.y); + } + + return res; + } +}; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 90a907d653..734330b4b7 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -191,8 +191,6 @@ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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_set_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_wall_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_large_scenery_colour( diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index 2958c533ba..94a66bc76c 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -24,60 +24,6 @@ #include "Scenery.h" #include "Surface.h" -static money32 SmallScenerySetColour( - int16_t x, int16_t y, uint8_t baseHeight, uint8_t quadrant, uint8_t sceneryType, uint8_t primaryColour, - uint8_t secondaryColour, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t z = baseHeight * 8; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) - { - if (!map_is_location_owned(x, y, z)) - { - return MONEY32_UNDEFINED; - } - } - - auto tileElement = map_get_small_scenery_element_at(x, y, baseHeight, sceneryType, quadrant); - - if (tileElement == nullptr) - { - return 0; - } - - if ((flags & GAME_COMMAND_FLAG_GHOST) && !(tileElement->IsGhost())) - { - return 0; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - tileElement->SetPrimaryColour(primaryColour); - tileElement->SetSecondaryColour(secondaryColour); - - map_invalidate_tile_full(x, y); - } - - return 0; -} - -/** - * - * rct2: 0x006E0F26 - */ -void game_command_set_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - int32_t* ebp) -{ - *ebx = SmallScenerySetColour( - *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, ((*ebx >> 8) & 0xFF), (*edx >> 8) & 0xFF, *ebp & 0xFF, (*ebp >> 8) & 0xFF, - *ebx & 0xFF); -} - /** * * rct2: 0x006E0D6E, 0x006B8D88 From 8ef5afe2ced8acf65eb290aaf7212303c31ae342 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 19:36:44 +0100 Subject: [PATCH 190/506] Implement wall set colour action --- src/openrct2-ui/windows/TopToolbar.cpp | 11 +- src/openrct2/Game.cpp | 6 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/WallSetColourAction.hpp | 161 ++++++++++++++++++ src/openrct2/world/Map.h | 2 - src/openrct2/world/Wall.cpp | 56 ------ 7 files changed, 173 insertions(+), 67 deletions(-) create mode 100644 src/openrct2/actions/WallSetColourAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index d36b17e501..2dff172b21 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1026,11 +1027,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg if (!(scenery_entry->wall.flags & (WALL_SCENERY_HAS_PRIMARY_COLOUR | WALL_SCENERY_HAS_GLASS))) return; - gGameCommandErrorTitle = STR_CANT_REPAINT_THIS; - game_do_command( - grid_x, 1 | (gWindowSceneryPrimaryColour << 8), grid_y, - tile_element->GetDirection() | (tile_element->base_height << 8), GAME_COMMAND_SET_WALL_COLOUR, 0, - gWindowScenerySecondaryColour | (gWindowSceneryTertiaryColour << 8)); + auto repaintScenery = WallSetColourAction( + { grid_x, grid_y, tile_element->base_height * 8, tile_element->GetDirection() }, gWindowSceneryPrimaryColour, + gWindowScenerySecondaryColour, gWindowSceneryTertiaryColour); + + GameActions::Execute(&repaintScenery); break; } case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY: diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 80ce37e882..ff27d0acda 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -644,8 +644,8 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c network_append_server_log(log_msg); } else if ( - command == GAME_COMMAND_SET_WALL_COLOUR || command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR - || command == GAME_COMMAND_SET_BANNER_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE) + command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR || command == GAME_COMMAND_SET_BANNER_COLOUR + || command == GAME_COMMAND_SET_BANNER_STYLE) { // Log editing scenery char* args[1] = { @@ -1292,7 +1292,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_place_banner, game_command_remove_banner, nullptr, - game_command_set_wall_colour, + nullptr, game_command_set_large_scenery_colour, game_command_set_banner_colour, game_command_set_land_ownership, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index ed90316eb2..c64e65b6ab 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -72,7 +72,7 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_BANNER, GAME_COMMAND_REMOVE_BANNER, GAME_COMMAND_SET_SCENERY_COLOUR, // GA - GAME_COMMAND_SET_WALL_COLOUR, + GAME_COMMAND_SET_WALL_COLOUR, // GA GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, GAME_COMMAND_SET_BANNER_COLOUR, GAME_COMMAND_SET_LAND_OWNERSHIP, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index ccb7ea18c8..a3f8bb8b59 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -65,6 +65,7 @@ #include "TrackSetBrakeSpeedAction.hpp" #include "WallPlaceAction.hpp" #include "WallRemoveAction.hpp" +#include "WallSetColourAction.hpp" #include "WaterLowerAction.hpp" #include "WaterRaiseAction.hpp" #include "WaterSetHeightAction.hpp" @@ -114,6 +115,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/WallSetColourAction.hpp b/src/openrct2/actions/WallSetColourAction.hpp new file mode 100644 index 0000000000..0589114ac1 --- /dev/null +++ b/src/openrct2/actions/WallSetColourAction.hpp @@ -0,0 +1,161 @@ +/***************************************************************************** + * 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 "../OpenRCT2.h" +#include "../management/Finance.h" +#include "../ride/RideGroupManager.h" +#include "../ride/Track.h" +#include "../ride/TrackData.h" +#include "../world/Banner.h" +#include "../world/LargeScenery.h" +#include "../world/MapAnimation.h" +#include "../world/Scenery.h" +#include "../world/SmallScenery.h" +#include "../world/Surface.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(WallSetColourAction, GAME_COMMAND_SET_WALL_COLOUR, GameActionResult) +{ +private: + CoordsXYZD _loc; + int32_t _primaryColour; + int32_t _secondaryColour; + int32_t _tertiaryColour; + +public: + WallSetColourAction() + { + } + + WallSetColourAction(CoordsXYZD loc, int32_t primaryColour, int32_t secondaryColour, int32_t tertiaryColour) + : _loc(loc) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + , _tertiaryColour(tertiaryColour) + { + } + + 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(_primaryColour) << DS_TAG(_secondaryColour) << DS_TAG(_tertiaryColour); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_REPAINT_THIS; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_in_park({ _loc.x, _loc.y }) + && !gCheatsSandboxMode) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + + auto wallElement = map_get_wall_element_at(_loc.x, _loc.y, _loc.z / 8, _loc.direction); + if (wallElement == nullptr) + { + log_error( + "Could not find wall element at: x = %d, y = %d, z = %d, direction = %u", _loc.x, _loc.y, _loc.z, + _loc.direction); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(wallElement->IsGhost())) + { + return res; + } + + rct_scenery_entry* sceneryEntry = wallElement->GetEntry(); + if (sceneryEntry == nullptr) + { + log_error("Could not find wall object"); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } + + if (_primaryColour > 31) + { + log_error("Primary colour invalid: colour = %d", _primaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (_secondaryColour > 31) + { + log_error("Secondary colour invalid: colour = %d", _secondaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) + { + if (_tertiaryColour > 31) + { + log_error("Tertiary colour invalid: colour = %d", _tertiaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + } + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ErrorTitle = STR_CANT_REPAINT_THIS; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + + auto wallElement = map_get_wall_element_at(_loc.x, _loc.y, _loc.z / 8, _loc.direction); + if (wallElement == nullptr) + { + log_error( + "Could not find wall element at: x = %d, y = %d, z = %d, direction = %u", _loc.x, _loc.y, _loc.z, + _loc.direction); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(wallElement->IsGhost())) + { + return res; + } + + rct_scenery_entry* sceneryEntry = wallElement->GetEntry(); + if (sceneryEntry == nullptr) + { + log_error("Could not find wall object"); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } + + wallElement->SetPrimaryColour(_primaryColour); + wallElement->SetSecondaryColour(_secondaryColour); + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) + { + wallElement->SetTertiaryColour(_tertiaryColour); + } + map_invalidate_tile_zoom1(_loc.x, _loc.y, _loc.z, _loc.z + 72); + + return res; + } + +private: +}; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 734330b4b7..d009c5677b 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -191,8 +191,6 @@ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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_set_wall_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_large_scenery_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_colour( diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 137c26ca9e..d238a49a10 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -29,49 +29,6 @@ #include "Surface.h" #include "Wall.h" -static money32 WallSetColour( - int16_t x, int16_t y, uint8_t baseHeight, uint8_t direction, uint8_t primaryColour, uint8_t secondaryColour, - uint8_t tertiaryColour, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t z = baseHeight * 8; - - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_in_park({ x, y }) && !gCheatsSandboxMode) - { - return MONEY32_UNDEFINED; - } - - auto wallElement = map_get_wall_element_at(x, y, baseHeight, direction); - if (wallElement == nullptr) - { - return 0; - } - - if ((flags & GAME_COMMAND_FLAG_GHOST) && !(wallElement->IsGhost())) - { - return 0; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - rct_scenery_entry* scenery_entry = wallElement->GetEntry(); - wallElement->SetPrimaryColour(primaryColour); - wallElement->SetSecondaryColour(secondaryColour); - - if (scenery_entry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) - { - wallElement->SetTertiaryColour(tertiaryColour); - } - map_invalidate_tile_zoom1(x, y, z, z + 72); - } - - return 0; -} - /** * * rct2: 0x006E588E @@ -136,19 +93,6 @@ void wall_remove_intersecting_walls(int32_t x, int32_t y, int32_t z0, int32_t z1 } while (!(tileElement++)->IsLastForTile()); } -/** - * - * rct2: 0x006E56B5 - */ -void game_command_set_wall_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - int32_t* ebp) -{ - *ebx = WallSetColour( - *eax & 0xFFFF, *ecx & 0xFFFF, (*edx >> 8) & 0xFF, *edx & 0xFF, (*ebx >> 8) & 0xFF, *ebp & 0xFF, (*ebp >> 8) & 0xFF, - *ebx & 0xFF); -} - uint8_t WallElement::GetSlope() const { return (type & TILE_ELEMENT_QUADRANT_MASK) >> 6; From 5ab42488a9897f7de63b552ed502061e2c736522 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 08:51:14 +0100 Subject: [PATCH 191/506] Implement large scenery set colour action --- src/openrct2-ui/windows/TopToolbar.cpp | 11 +- src/openrct2/Game.cpp | 6 +- src/openrct2/Game.h | 6 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/LargeScenerySetColourAction.hpp | 145 ++++++++++++++++++ src/openrct2/world/Map.cpp | 83 ---------- src/openrct2/world/Map.h | 2 - 7 files changed, 158 insertions(+), 97 deletions(-) create mode 100644 src/openrct2/actions/LargeScenerySetColourAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 2dff172b21..240f3ca4db 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1042,11 +1043,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg if (!(scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR)) return; - gGameCommandErrorTitle = STR_CANT_REPAINT_THIS; - game_do_command( - grid_x, 1 | (tile_element->GetDirection() << 8), grid_y, - tile_element->base_height | (tile_element->AsLargeScenery()->GetSequenceIndex() << 8), - GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8)); + auto repaintScenery = LargeScenerySetColourAction( + { grid_x, grid_y, tile_element->base_height * 8, tile_element->GetDirection() }, + tile_element->AsLargeScenery()->GetSequenceIndex(), gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour); + + GameActions::Execute(&repaintScenery); break; } case VIEWPORT_INTERACTION_ITEM_BANNER: diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index ff27d0acda..066e1076f2 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -643,9 +643,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_REMOVE_SCENERY, args); network_append_server_log(log_msg); } - else if ( - command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR || command == GAME_COMMAND_SET_BANNER_COLOUR - || command == GAME_COMMAND_SET_BANNER_STYLE) + else if (command == GAME_COMMAND_SET_BANNER_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE) { // Log editing scenery char* args[1] = { @@ -1293,7 +1291,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_remove_banner, nullptr, nullptr, - game_command_set_large_scenery_colour, + nullptr, game_command_set_banner_colour, game_command_set_land_ownership, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index c64e65b6ab..4e48f867c3 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -71,9 +71,9 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_MAZE_DESIGN, GAME_COMMAND_PLACE_BANNER, GAME_COMMAND_REMOVE_BANNER, - GAME_COMMAND_SET_SCENERY_COLOUR, // GA - GAME_COMMAND_SET_WALL_COLOUR, // GA - GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, + GAME_COMMAND_SET_SCENERY_COLOUR, // GA + GAME_COMMAND_SET_WALL_COLOUR, // GA + GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA GAME_COMMAND_SET_BANNER_COLOUR, GAME_COMMAND_SET_LAND_OWNERSHIP, GAME_COMMAND_CLEAR_SCENERY, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index a3f8bb8b59..bf29777317 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -23,6 +23,7 @@ #include "LandSetHeightAction.hpp" #include "LandSmoothAction.hpp" #include "LargeSceneryRemoveAction.hpp" +#include "LargeScenerySetColourAction.hpp" #include "LoadOrQuitAction.hpp" #include "MazeSetTrackAction.hpp" #include "ParkEntranceRemoveAction.hpp" @@ -120,6 +121,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/LargeScenerySetColourAction.hpp b/src/openrct2/actions/LargeScenerySetColourAction.hpp new file mode 100644 index 0000000000..b877c4857e --- /dev/null +++ b/src/openrct2/actions/LargeScenerySetColourAction.hpp @@ -0,0 +1,145 @@ +/***************************************************************************** + * 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 "../OpenRCT2.h" +#include "../management/Finance.h" +#include "../world/Scenery.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(LargeScenerySetColourAction, GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, GameActionResult) +{ +private: + CoordsXYZD _loc; + uint8_t _tileIndex; + uint8_t _primaryColour; + uint8_t _secondaryColour; + +public: + LargeScenerySetColourAction() = default; + + LargeScenerySetColourAction(CoordsXYZD loc, uint8_t tileIndex, uint8_t primaryColour, uint8_t secondaryColour) + : _loc(loc) + , _tileIndex(tileIndex) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_tileIndex) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour); + } + + 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(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = tile_element_height(_loc.x, _loc.y); + res->ErrorTitle = STR_CANT_REPAINT_THIS; + + if (_loc.x < 0 || _loc.y < 0 || _loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY) + { + log_error("Invalid x / y coordinates: x = %d, y = %d", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (_primaryColour > 31) + { + log_error("Invalid primary colour: colour = %u", _primaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (_secondaryColour > 31) + { + log_error("Invalid primary colour: colour = %u", _secondaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + auto largeElement = map_get_large_scenery_segment(_loc.x, _loc.y, _loc.z / 8, _loc.direction, _tileIndex); + + if (largeElement == nullptr) + { + log_error( + "Could not find large scenery at: x = %d, y = %d, z = %d, direction = %d, tileIndex = %u", _loc.x, _loc.y, + _loc.z, _loc.direction, _tileIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(largeElement->IsGhost())) + { + return res; + } + + rct_scenery_entry* sceneryEntry = largeElement->GetEntry(); + + if (sceneryEntry == nullptr) + { + log_error("Could not find scenery object. type = %u", largeElement->GetEntryIndex()); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } + // Work out the base tile coordinates (Tile with index 0) + auto baseX = sceneryEntry->large_scenery.tiles[_tileIndex].x_offset; + auto baseY = sceneryEntry->large_scenery.tiles[_tileIndex].y_offset; + rotate_map_coordinates(&baseX, &baseY, _loc.direction); + + CoordsXYZ baseTile = { _loc.x - baseX, _loc.y - baseY, + _loc.z - sceneryEntry->large_scenery.tiles[_tileIndex].z_offset }; + + auto i = 0; + for (auto tile = sceneryEntry->large_scenery.tiles; tile->x_offset != -1; ++tile, ++i) + { + // Work out the current tile coordinates + auto tileX = tile->x_offset; + auto tileY = tile->y_offset; + rotate_map_coordinates(&tileX, &tileY, _loc.direction); + CoordsXYZ currentTile = { tileX + baseTile.x, tileY + baseTile.y, tile->z_offset + baseTile.z }; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_owned(currentTile.x, currentTile.y, currentTile.z)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + } + + if (isExecuting) + { + auto tileElement = map_get_large_scenery_segment(currentTile.x, currentTile.y, _loc.z / 8, _loc.direction, i); + + tileElement->SetPrimaryColour(_primaryColour); + tileElement->SetSecondaryColour(_secondaryColour); + + map_invalidate_tile_full(currentTile.x, currentTile.y); + } + } + return res; + } +}; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 83762955bc..608b160195 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -795,89 +795,6 @@ bool map_is_location_owned_or_has_rights(int32_t x, int32_t y) return false; } -/** - * - * rct2: 0x006B909A - */ -void game_command_set_large_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - int32_t* ebp) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t x = *eax; - int32_t y = *ecx; - uint8_t tile_element_direction = *ebx >> 8; - uint8_t flags = *ebx & 0xFF; - uint8_t base_height = *edx; - uint8_t tileIndex = *edx >> 8; - uint8_t colour1 = *ebp; - uint8_t colour2 = *ebp >> 8; - int32_t z = tile_element_height(x, y); - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - auto tile_element = map_get_large_scenery_segment(x, y, base_height, tile_element_direction, tileIndex); - - if (tile_element == nullptr) - { - *ebx = 0; - return; - } - - if ((flags & GAME_COMMAND_FLAG_GHOST) && !(tile_element->IsGhost())) - { - *ebx = 0; - return; - } - - rct_scenery_entry* scenery_entry = tile_element->GetEntry(); - - // Work out the base tile coordinates (Tile with index 0) - LocationXYZ16 baseTile = { - scenery_entry->large_scenery.tiles[tileIndex].x_offset, scenery_entry->large_scenery.tiles[tileIndex].y_offset, - static_cast((base_height * 8) - scenery_entry->large_scenery.tiles[tileIndex].z_offset) - }; - rotate_map_coordinates(&baseTile.x, &baseTile.y, tile_element_direction); - baseTile.x = x - baseTile.x; - baseTile.y = y - baseTile.y; - - for (int32_t i = 0; scenery_entry->large_scenery.tiles[i].x_offset != -1; ++i) - { - assert(i < MAXIMUM_MAP_SIZE_TECHNICAL); - - // Work out the current tile coordinates - LocationXYZ16 currentTile = { scenery_entry->large_scenery.tiles[i].x_offset, - scenery_entry->large_scenery.tiles[i].y_offset, - scenery_entry->large_scenery.tiles[i].z_offset }; - rotate_map_coordinates(¤tTile.x, ¤tTile.y, tile_element_direction); - currentTile.x += baseTile.x; - currentTile.y += baseTile.y; - currentTile.z += baseTile.z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) - { - if (!map_is_location_owned(currentTile.x, currentTile.y, currentTile.z)) - { - *ebx = MONEY32_UNDEFINED; - return; - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - auto tileElement = map_get_large_scenery_segment( - currentTile.x, currentTile.y, base_height, tile_element_direction, i); - - tileElement->SetPrimaryColour(colour1); - tileElement->SetSecondaryColour(colour2); - - map_invalidate_tile_full(currentTile.x, currentTile.y); - } - } - *ebx = 0; -} - // 0x00981A1E // Table of pre-calculated surface slopes (32) when raising the land tile for a given selection (5) // 0x1F = new slope diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index d009c5677b..323c081808 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -191,8 +191,6 @@ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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_set_large_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_banner_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_place_banner( From 3593366e9544e1e99f85ac2ca4f9848070619c34 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 09:15:41 +0100 Subject: [PATCH 192/506] Implement banner set colour action --- src/openrct2-ui/windows/TopToolbar.cpp | 10 +- src/openrct2/Game.cpp | 28 +---- src/openrct2/Game.h | 2 +- .../actions/BannerSetColourAction.hpp | 110 ++++++++++++++++++ .../actions/GameActionRegistration.cpp | 2 + src/openrct2/world/Banner.cpp | 57 --------- src/openrct2/world/Map.h | 2 - 7 files changed, 121 insertions(+), 90 deletions(-) create mode 100644 src/openrct2/actions/BannerSetColourAction.hpp diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 240f3ca4db..dd92e78d61 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1056,10 +1057,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg rct_scenery_entry* scenery_entry = get_banner_entry(banner->type); if (scenery_entry->banner.flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR) { - gGameCommandErrorTitle = STR_CANT_REPAINT_THIS; - game_do_command( - grid_x, 1, grid_y, tile_element->base_height | ((tile_element->AsBanner()->GetPosition() & 0x3) << 8), - GAME_COMMAND_SET_BANNER_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8)); + auto repaintScenery = BannerSetColourAction( + { grid_x, grid_y, tile_element->base_height * 8, tile_element->AsBanner()->GetPosition()}, + gWindowSceneryPrimaryColour); + + GameActions::Execute(&repaintScenery); } break; } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 066e1076f2..a202acf72b 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -643,7 +643,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_REMOVE_SCENERY, args); network_append_server_log(log_msg); } - else if (command == GAME_COMMAND_SET_BANNER_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE) + else if (command == GAME_COMMAND_SET_BANNER_STYLE) { // Log editing scenery char* args[1] = { @@ -651,30 +651,6 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c }; format_string(log_msg, 256, STR_LOG_EDIT_SCENERY, args); network_append_server_log(log_msg); - if (command == GAME_COMMAND_SET_BANNER_NAME || command == GAME_COMMAND_SET_SIGN_NAME) - { - static char banner_name[128]; - - std::fill_n(banner_name, sizeof(banner_name), ' '); - int nameChunkIndex = *eax & 0xFFFF; - - int nameChunkOffset = nameChunkIndex - 1; - if (nameChunkOffset < 0) - nameChunkOffset = 2; - nameChunkOffset *= 12; - nameChunkOffset = std::min(nameChunkOffset, (int32_t)(std::size(banner_name) - 12)); - std::memcpy(banner_name + nameChunkOffset + 0, edx, 4); - std::memcpy(banner_name + nameChunkOffset + 4, ebp, 4); - std::memcpy(banner_name + nameChunkOffset + 8, edi, 4); - banner_name[sizeof(banner_name) - 1] = '\0'; - - char* args_sign[2] = { - (char*)player_name, - (char*)banner_name, - }; - format_string(log_msg, 256, STR_LOG_SET_SIGN_NAME, args_sign); - network_append_server_log(log_msg); - } } } @@ -1292,7 +1268,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_banner_colour, + nullptr, game_command_set_land_ownership, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 4e48f867c3..c954315318 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -74,7 +74,7 @@ enum GAME_COMMAND GAME_COMMAND_SET_SCENERY_COLOUR, // GA GAME_COMMAND_SET_WALL_COLOUR, // GA GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA - GAME_COMMAND_SET_BANNER_COLOUR, + GAME_COMMAND_SET_BANNER_COLOUR, // GA GAME_COMMAND_SET_LAND_OWNERSHIP, GAME_COMMAND_CLEAR_SCENERY, // GA GAME_COMMAND_SET_BANNER_NAME, // GA diff --git a/src/openrct2/actions/BannerSetColourAction.hpp b/src/openrct2/actions/BannerSetColourAction.hpp new file mode 100644 index 0000000000..5235d154e4 --- /dev/null +++ b/src/openrct2/actions/BannerSetColourAction.hpp @@ -0,0 +1,110 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../management/Finance.h" +#include "../windows/Intent.h" +#include "../world/Banner.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(BannerSetColourAction, GAME_COMMAND_SET_BANNER_COLOUR, GameActionResult) +{ +private: + CoordsXYZD _loc; + uint8_t _primaryColour; + +public: + BannerSetColourAction() = default; + + BannerSetColourAction(CoordsXYZD loc, uint8_t primaryColour) + : _loc(loc) + , _primaryColour(primaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_primaryColour); + } + + 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(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ErrorTitle = STR_CANT_REPAINT_THIS; + + if (_loc.x < 0 || _loc.y < 0 || _loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY) + { + log_error("Invalid x / y coordinates: x = %d, y = %d", _loc.x, _loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (_primaryColour > 31) + { + log_error("Invalid primary colour: colour = %u", _primaryColour); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if (!map_can_build_at(_loc.x, _loc.y, _loc.z - 16)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + + auto bannerElement = map_get_banner_element_at(_loc.x / 32, _loc.y / 32, _loc.z / 8, _loc.direction); + + if (bannerElement == nullptr) + { + log_error( + "Could not find banner at: x = %d, y = %d, z = %d, direction = %u", _loc.x, _loc.y, _loc.z, _loc.direction); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } + + auto index = bannerElement->GetIndex(); + if (index > MAX_BANNERS || index == BANNER_INDEX_NULL) + { + log_error("Invalid banner index: index = %u", index); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } + + if (isExecuting) + { + auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); + intent.putExtra(INTENT_EXTRA_BANNER_INDEX, index); + context_broadcast_intent(&intent); + + gBanners[index].colour = _primaryColour; + map_invalidate_tile_zoom1(_loc.x, _loc.y, _loc.z, _loc.z + 32); + } + + return res; + } +}; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index bf29777317..8ebf7cebe0 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -7,6 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "BannerSetColourAction.hpp" #include "BannerSetNameAction.hpp" #include "ClearAction.hpp" #include "ClimateSetAction.hpp" @@ -75,6 +76,7 @@ namespace GameActions { void Register() { + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 278dd327fd..1162f26470 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -117,52 +117,6 @@ static money32 BannerRemove(int16_t x, int16_t y, uint8_t baseHeight, uint8_t di return refund; } -static money32 BannerSetColour(int16_t x, int16_t y, uint8_t baseHeight, uint8_t direction, uint8_t colour, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t z = (baseHeight * 8); - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!map_can_build_at(x, y, z - 16)) - { - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - TileElement* tileElement = map_get_first_element_at(x / 32, y / 32); - - bool found = false; - do - { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER) - continue; - - if (tileElement->AsBanner()->GetPosition() != direction) - continue; - - found = true; - break; - } while (!(tileElement++)->IsLastForTile()); - - if (!found) - { - return MONEY32_UNDEFINED; - } - - auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); - intent.putExtra(INTENT_EXTRA_BANNER_INDEX, tileElement->AsBanner()->GetIndex()); - context_broadcast_intent(&intent); - - gBanners[tileElement->AsBanner()->GetIndex()].colour = colour; - map_invalidate_tile_zoom1(x, y, z, z + 32); - } - - return 0; -} - static money32 BannerPlace( int16_t x, int16_t y, uint8_t pathBaseHeight, uint8_t direction, uint8_t colour, uint8_t type, BannerIndex* bannerIndex, uint8_t flags) @@ -540,17 +494,6 @@ void game_command_remove_banner( *ebx = BannerRemove(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebx & 0xFF); } -/** - * - * rct2: 0x006BA16A - */ -void game_command_set_banner_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - int32_t* ebp) -{ - *ebx = BannerSetColour(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebp & 0xFF, *ebx & 0xFF); -} - /** * * rct2: 0x006B9E6D diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 323c081808..0ca811bcdc 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -191,8 +191,6 @@ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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_set_banner_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_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( From aa65e25c6b0c7c0e5148ce1de2f1b59900e7105c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 10:10:36 +0100 Subject: [PATCH 193/506] Implement banner set style action --- src/openrct2-ui/windows/Banner.cpp | 27 +-- src/openrct2/Game.cpp | 11 +- src/openrct2/Game.h | 10 +- .../actions/BannerSetColourAction.hpp | 2 +- src/openrct2/actions/BannerSetStyleAction.hpp | 185 ++++++++++++++++++ .../actions/GameActionRegistration.cpp | 2 + src/openrct2/world/Banner.cpp | 74 ------- src/openrct2/world/Map.h | 2 - 8 files changed, 209 insertions(+), 104 deletions(-) create mode 100644 src/openrct2/actions/BannerSetStyleAction.hpp diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index d080dcbd50..3fe1b278f6 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -195,11 +197,13 @@ static void window_banner_mouseup(rct_window* w, rct_widgetindex widgetIndex) w, WIDX_BANNER_TEXT, STR_BANNER_TEXT, STR_ENTER_BANNER_TEXT, gBanners[w->number].string_idx, 0, 32); break; case WIDX_BANNER_NO_ENTRY: + { textinput_cancel(); - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, - banner->flags ^ BANNER_FLAG_NO_ENTRY); + auto bannerSetStyle = BannerSetStyleAction( + BannerSetStyleType::NoEntry, w->number, banner->flags ^ BANNER_FLAG_NO_ENTRY); + GameActions::Execute(&bannerSetStyle); break; + } } } @@ -242,26 +246,25 @@ static void window_banner_mousedown(rct_window* w, rct_widgetindex widgetIndex, */ static void window_banner_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) { - rct_banner* banner = &gBanners[w->number]; - switch (widgetIndex) { case WIDX_MAIN_COLOUR: + { if (dropdownIndex == -1) break; - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, dropdownIndex, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, - banner->flags); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::PrimaryColour, w->number, dropdownIndex); + GameActions::Execute(&bannerSetStyle); break; + } case WIDX_TEXT_COLOUR_DROPDOWN_BUTTON: + { if (dropdownIndex == -1) break; - - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, dropdownIndex + 1, - banner->flags); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::TextColour, w->number, dropdownIndex + 1); + GameActions::Execute(&bannerSetStyle); break; + } } } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index a202acf72b..0620e3d32f 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -643,15 +643,6 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_REMOVE_SCENERY, args); network_append_server_log(log_msg); } - else if (command == GAME_COMMAND_SET_BANNER_STYLE) - { - // Log editing scenery - char* args[1] = { - (char*)player_name, - }; - format_string(log_msg, 256, STR_LOG_EDIT_SCENERY, args); - network_append_server_log(log_msg); - } } void pause_toggle() @@ -1273,7 +1264,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_banner_style, + nullptr, nullptr, game_command_set_player_group, game_command_modify_groups, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index c954315318..6b80e1c6d5 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -76,11 +76,11 @@ enum GAME_COMMAND GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA GAME_COMMAND_SET_BANNER_COLOUR, // GA GAME_COMMAND_SET_LAND_OWNERSHIP, - GAME_COMMAND_CLEAR_SCENERY, // GA - GAME_COMMAND_SET_BANNER_NAME, // GA - GAME_COMMAND_SET_SIGN_NAME, // GA - GAME_COMMAND_SET_BANNER_STYLE, - GAME_COMMAND_SET_SIGN_STYLE, // GA + GAME_COMMAND_CLEAR_SCENERY, // GA + GAME_COMMAND_SET_BANNER_NAME, // GA + GAME_COMMAND_SET_SIGN_NAME, // GA + GAME_COMMAND_SET_BANNER_STYLE, // GA + GAME_COMMAND_SET_SIGN_STYLE, // GA GAME_COMMAND_SET_PLAYER_GROUP, GAME_COMMAND_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, diff --git a/src/openrct2/actions/BannerSetColourAction.hpp b/src/openrct2/actions/BannerSetColourAction.hpp index 5235d154e4..ff1d1a51d7 100644 --- a/src/openrct2/actions/BannerSetColourAction.hpp +++ b/src/openrct2/actions/BannerSetColourAction.hpp @@ -89,7 +89,7 @@ private: } auto index = bannerElement->GetIndex(); - if (index > MAX_BANNERS || index == BANNER_INDEX_NULL) + if (index >= MAX_BANNERS || index == BANNER_INDEX_NULL) { log_error("Invalid banner index: index = %u", index); return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp new file mode 100644 index 0000000000..162231bc35 --- /dev/null +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -0,0 +1,185 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../management/Finance.h" +#include "../windows/Intent.h" +#include "../world/Banner.h" +#include "GameAction.h" + +// There is also the BannerSetColourAction that sets primary colour but this action takes banner index rather than x, y, z, +// direction +enum class BannerSetStyleType : uint8_t +{ + PrimaryColour, + TextColour, + NoEntry, + Count +}; + +DEFINE_GAME_ACTION(BannerSetStyleAction, GAME_COMMAND_SET_BANNER_STYLE, GameActionResult) +{ +private: + uint8_t _type = static_cast(BannerSetStyleType::Count); + uint8_t _bannerIndex = BANNER_INDEX_NULL; + uint8_t _parameter; + +public: + BannerSetStyleAction() = default; + + BannerSetStyleAction(BannerSetStyleType type, uint8_t bannerIndex, uint8_t parameter) + : _type(static_cast(type)) + , _bannerIndex(bannerIndex) + , _parameter(parameter) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_type) << DS_TAG(_bannerIndex) << DS_TAG(_parameter); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + + if (_bannerIndex >= MAX_BANNERS || _bannerIndex == BANNER_INDEX_NULL) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + + rct_banner* banner = &gBanners[_bannerIndex]; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = banner->x * 32 + 16; + res->Position.y = banner->y * 32 + 16; + res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + + TileElement* tileElement = banner_get_tile_element(_bannerIndex); + + if (tileElement == nullptr) + { + log_error("Could not find banner index = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + switch (static_cast(_type)) + { + case BannerSetStyleType::PrimaryColour: + if (_parameter > 31) + { + log_error("Invalid primary colour: colour = %u", _parameter); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + break; + + case BannerSetStyleType::TextColour: + if (_parameter > 13) + { + log_error("Invalid text colour: colour = %u", _parameter); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + break; + case BannerSetStyleType::NoEntry: + break; + default: + log_error("Invalid type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + + rct_banner* banner = &gBanners[_bannerIndex]; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = banner->x * 32 + 16; + res->Position.y = banner->y * 32 + 16; + res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + + TileElement* tileElement = banner_get_tile_element(_bannerIndex); + + if (tileElement == nullptr) + { + log_error("Could not find banner index = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + switch (static_cast(_type)) + { + case BannerSetStyleType::PrimaryColour: + banner->colour = _parameter; + break; + case BannerSetStyleType::TextColour: + { + banner->text_colour = _parameter; + int32_t colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; + + utf8 buffer[256]; + format_string(buffer, 256, banner->string_idx, nullptr); + int32_t firstCodepoint = utf8_get_next(buffer, nullptr); + if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) + { + utf8_write_codepoint(buffer, colourCodepoint); + } + else + { + utf8_insert_codepoint(buffer, colourCodepoint); + } + + rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); + if (stringId != 0) + { + rct_string_id prevStringId = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prevStringId); + } + else + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_SET_BANNER_TEXT); + } + break; + } + case BannerSetStyleType::NoEntry: + { + BannerElement* bannerElement = tileElement->AsBanner(); + banner->flags &= BANNER_FLAG_NO_ENTRY; + banner->flags |= BANNER_FLAG_NO_ENTRY & (_parameter != 0); + uint8_t allowedEdges = 0xF; + if (banner->flags & BANNER_FLAG_NO_ENTRY) + { + allowedEdges &= ~(1 << bannerElement->GetPosition()); + } + bannerElement->SetAllowedEdges(allowedEdges); + break; + } + default: + log_error("Invalid type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); + intent.putExtra(INTENT_EXTRA_BANNER_INDEX, _bannerIndex); + context_broadcast_intent(&intent); + + return res; + } +}; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 8ebf7cebe0..ec7c557059 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -9,6 +9,7 @@ #include "BannerSetColourAction.hpp" #include "BannerSetNameAction.hpp" +#include "BannerSetStyleAction.hpp" #include "ClearAction.hpp" #include "ClimateSetAction.hpp" #include "FootpathPlaceAction.hpp" @@ -78,6 +79,7 @@ namespace GameActions { Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 1162f26470..6390a25eba 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -227,73 +227,6 @@ static money32 BannerPlace( return bannerEntry->banner.price; } -static money32 BannerSetStyle(BannerIndex bannerIndex, uint8_t colour, uint8_t textColour, uint8_t bannerFlags, uint8_t flags) -{ - if (bannerIndex >= MAX_BANNERS) - { - gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; - return MONEY32_UNDEFINED; - } - - rct_banner* banner = &gBanners[bannerIndex]; - - TileElement* tileElement = banner_get_tile_element(bannerIndex); - - if (tileElement == nullptr) - { - return MONEY32_UNDEFINED; - } - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - banner->colour = colour; - banner->text_colour = textColour; - banner->flags = bannerFlags; - - uint8_t allowedEdges = 0xF; - if (banner->flags & BANNER_FLAG_NO_ENTRY) - { - allowedEdges &= ~(1 << tileElement->AsBanner()->GetPosition()); - } - tileElement->AsBanner()->SetAllowedEdges(allowedEdges); - - int32_t colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; - - utf8 buffer[256]; - format_string(buffer, 256, banner->string_idx, nullptr); - int32_t firstCodepoint = utf8_get_next(buffer, nullptr); - if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) - { - utf8_write_codepoint(buffer, colourCodepoint); - } - else - { - utf8_insert_codepoint(buffer, colourCodepoint); - } - - rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); - if (stringId != 0) - { - rct_string_id prevStringId = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prevStringId); - - auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); - intent.putExtra(INTENT_EXTRA_BANNER_INDEX, bannerIndex); - context_broadcast_intent(&intent); - } - else - { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - return MONEY32_UNDEFINED; - } - - return 0; -} - static BannerIndex BannerGetNewIndex() { for (BannerIndex bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) @@ -506,13 +439,6 @@ void game_command_place_banner( *ebx & 0xFF); } -void game_command_set_banner_style( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - int32_t* ebp) -{ - *ebx = BannerSetStyle(*ecx & 0xFF, *edx & 0xFF, *edi & 0xFF, *ebp & 0xFF, *ebx & 0xFF); -} - BannerIndex BannerElement::GetIndex() const { return index; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 0ca811bcdc..b551f6752c 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -199,8 +199,6 @@ 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( 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_style( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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 From 008ed86bca9c655bf162692153a086d28de7d27d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 12:02:04 +0100 Subject: [PATCH 194/506] Make requested fixes --- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2/actions/BannerSetStyleAction.hpp | 4 ++-- src/openrct2/actions/LargeScenerySetColourAction.hpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index dd92e78d61..7d605ddb15 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1058,7 +1058,7 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg if (scenery_entry->banner.flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR) { auto repaintScenery = BannerSetColourAction( - { grid_x, grid_y, tile_element->base_height * 8, tile_element->AsBanner()->GetPosition()}, + { grid_x, grid_y, tile_element->base_height * 8, tile_element->AsBanner()->GetPosition() }, gWindowSceneryPrimaryColour); GameActions::Execute(&repaintScenery); diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp index 162231bc35..390db7c86f 100644 --- a/src/openrct2/actions/BannerSetStyleAction.hpp +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -161,8 +161,8 @@ public: case BannerSetStyleType::NoEntry: { BannerElement* bannerElement = tileElement->AsBanner(); - banner->flags &= BANNER_FLAG_NO_ENTRY; - banner->flags |= BANNER_FLAG_NO_ENTRY & (_parameter != 0); + banner->flags &= ~BANNER_FLAG_NO_ENTRY; + banner->flags |= (_parameter != 0) ? BANNER_FLAG_NO_ENTRY : 0; uint8_t allowedEdges = 0xF; if (banner->flags & BANNER_FLAG_NO_ENTRY) { diff --git a/src/openrct2/actions/LargeScenerySetColourAction.hpp b/src/openrct2/actions/LargeScenerySetColourAction.hpp index b877c4857e..0888488205 100644 --- a/src/openrct2/actions/LargeScenerySetColourAction.hpp +++ b/src/openrct2/actions/LargeScenerySetColourAction.hpp @@ -130,10 +130,17 @@ private: } } + auto tileElement = map_get_large_scenery_segment(currentTile.x, currentTile.y, _loc.z / 8, _loc.direction, i); + + if (tileElement == nullptr) + { + log_error( + "Large scenery element not found at: x = %d, y = %d, z = %d, direction = %d", _loc.x, _loc.y, _loc.z, + _loc.direction); + return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); + } if (isExecuting) { - auto tileElement = map_get_large_scenery_segment(currentTile.x, currentTile.y, _loc.z / 8, _loc.direction, i); - tileElement->SetPrimaryColour(_primaryColour); tileElement->SetSecondaryColour(_secondaryColour); From 57efe286cf5c3a05d10db8733d8ad5d03cd28cf6 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 12:24:02 +0100 Subject: [PATCH 195/506] 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 21bda33c66..b564311839 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 "15" +#define NETWORK_STREAM_VERSION "16" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 7c901addc6400cc8c7bfc78ac42389411fad6276 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 7 Apr 2019 13:22:57 +0200 Subject: [PATCH 196/506] Fix #9068: Unable to place staff or peeps during multiplayer --- src/openrct2/network/Network.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 21bda33c66..9a8118472e 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1934,7 +1934,13 @@ void Network::ProcessPlayerInfo() auto* player = GetPlayerByID(it->second.Id); if (player != nullptr) { - *player = it->second; + const NetworkPlayer& networkedInfo = it->second; + player->Flags = networkedInfo.Flags; + player->Group = networkedInfo.Group; + player->LastAction = networkedInfo.LastAction; + player->LastActionCoord = networkedInfo.LastActionCoord; + player->MoneySpent = networkedInfo.MoneySpent; + player->CommandsRan = networkedInfo.CommandsRan; } } _pendingPlayerInfo.erase(gCurrentTicks); From d63919c0ccb385dfc1a846506531ec33cab6c1fa Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 5 Apr 2019 19:16:23 +0100 Subject: [PATCH 197/506] 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 198/506] 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 199/506] 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 200/506] 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 201/506] 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 202/506] 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 203/506] 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; From 981bd638e3c9968df7d9799144c824a600be1f51 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 8 Apr 2019 21:35:35 +0200 Subject: [PATCH 204/506] readme: do not mention the master branch PPA, which is no longer built [ci skip] --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 67314da372..7bc8d6de87 100644 --- a/readme.md +++ b/readme.md @@ -66,7 +66,7 @@ OpenRCT2 requires original files of RollerCoaster Tycoon 2 to play. It can be bo Some Linux distributions offer native packages already. These packages are usually third-party, but we're trying to resolve issues they are facing. * ArchLinux AUR: [openrct2-git](https://aur.archlinux.org/packages/openrct2-git) and [openrct2](https://aur.archlinux.org/packages/openrct2) -* Ubuntu PPA: [`master` branch](https://launchpad.net/~openrct2/+archive/ubuntu/master) and [`develop` branch](https://launchpad.net/~openrct2/+archive/ubuntu/nightly) +* Ubuntu PPA: [`develop` branch](https://launchpad.net/~openrct2/+archive/ubuntu/nightly) (nightly builds) * openSUSE OBS: [games/openrct2](https://software.opensuse.org/download.html?project=games&package=openrct2) * Gentoo (main portage tree): [games-simulation/openrct2](https://packages.gentoo.org/packages/games-simulation/openrct2) * NixOS (`nixos-unstable` channel): [openrct2](https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/openrct2/default.nix) From 198194fa353a87b3627c1c79591acc428b8c4730 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 9 Apr 2019 04:00:23 +0000 Subject: [PATCH 205/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 2 ++ data/language/da-DK.txt | 3 +++ data/language/ko-KR.txt | 2 ++ 3 files changed, 7 insertions(+) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index ab49468871..11396244c4 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3772,6 +3772,8 @@ STR_6301 :{SMALLFONT}{BLACK}Kopírovat název vybraného objektu do schránky STR_6302 :{SMALLFONT}{BLACK}Kopírovat seznam objektů do schránky STR_6303 :Stahování objektu ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Otevřít výběr kulis +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Experimentální podpora více vláken pro vykreslování obrazu, může způsobit nestabilitu. ############################################################################### ## RCT2 Scenarios diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 6fb08c954b..dc7869ce91 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3775,6 +3775,9 @@ STR_6301 :{SMALLFONT}{BLACK}Kopier det valgte objekt til udklipsholder. STR_6302 :{SMALLFONT}{BLACK}Kopier hele listen af manglende objekter til udklipsholderen. STR_6303 :Henter objekt ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Åben scenarie vælger +STR_6305 :Multi-tråde +STR_6306 :{SMALLFONT}{BLACK}Eksperimentel indstilling, brug flere processor kerner til at gengive spillet, kan påvirke stabiliteten. + ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 123aa8036e..d481e26b55 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3762,6 +3762,8 @@ STR_6301 :{SMALLFONT}{BLACK}선택한 오브젝트의 이름을 클립보드 STR_6302 :{SMALLFONT}{BLACK}빠진 오브젝트의 전체 목록을 클립보드에 복사합니다. STR_6303 :오브젝트 다운로드 중 ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :오브젝트 스포이드 +STR_6305 :멀티스레딩 +STR_6306 :{SMALLFONT}{BLACK}렌더링을 하기 위해 여러 개의 스레드를 사용합니다. 실험적인 기능이므로 불안정할 수 있습니다. ############# From e2e4c1d942e4f0408b1b08ab0b708462cb13335e Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 9 Apr 2019 18:39:33 +0100 Subject: [PATCH 206/506] Fix #9079. Null derference checked for when getting banner element. Unsure how the save managed to get in this state --- src/openrct2/actions/BannerSetStyleAction.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp index 390db7c86f..50254ab9d0 100644 --- a/src/openrct2/actions/BannerSetStyleAction.hpp +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -96,6 +96,11 @@ public: } break; case BannerSetStyleType::NoEntry: + if (tileElement->AsBanner() == nullptr) + { + log_error("Tile element was not a banner."); + return MakeResult(GA_ERROR::UNKNOWN, STR_NONE); + } break; default: log_error("Invalid type: %u", _type); @@ -161,6 +166,12 @@ public: case BannerSetStyleType::NoEntry: { BannerElement* bannerElement = tileElement->AsBanner(); + if (bannerElement == nullptr) + { + log_error("Tile element was not a banner."); + return MakeResult(GA_ERROR::UNKNOWN, STR_NONE); + } + banner->flags &= ~BANNER_FLAG_NO_ENTRY; banner->flags |= (_parameter != 0) ? BANNER_FLAG_NO_ENTRY : 0; uint8_t allowedEdges = 0xF; From 0ffa6d1ae5277884596887cb89b6b8e7bad730c9 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 9 Apr 2019 18:46:31 +0100 Subject: [PATCH 207/506] 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 c16b37d00a..9b77d842fc 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 "17" +#define NETWORK_STREAM_VERSION "18" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 27cccce312c56ddf5e5bebb52394948bf728388c Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 10 Apr 2019 04:00:21 +0000 Subject: [PATCH 208/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index d481e26b55..251396fe3f 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -111,8 +111,6 @@ STR_0525 :반원 모양의 트랙을 구불구불 커브를 돌며 내려오 STR_0526 :손님들이 회전하는 전망대 캐빈에 탑승해서 높은 곳을 구경하는 놀이기구입니다. STR_0527 :수직 루프를 사용할 수 있는 부드러운 철제 트랙의 롤러코스터입니다. STR_0528 :고무보트를 타고 반원이나 원형 모양의 트랙을 따라 미끄러지는 놀이기구입니다. -손님들이 공기를 넣은 고무 보트를 타고 반원이나 원형의 튜브 트랙을 따라 이동하는 놀이기구입니다. -고무 보트를 타고 반원이나 원형의 모양의 트랙을 미끄러져 달리는 놀이기구입니다. STR_0529 :오래된 기차 선로처럼 보이게 만든 철제 트랙을 따라 움직이는 탄광 열차 테마를 한 롤러코스터 차량입니다. STR_0530 :철제 케이블에 달린 차량이 연속적으로 놀이기구의 한쪽 끝에서 다른 쪽 끝을 왕복 운행합니다. STR_0531 :차량이 나선 트랙과 루프를 통과하는 알찬 구성의 철제 트랙 롤러코스터입니다. From 8632eb7297de719f6f192fe34eeac6173bd6aa00 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 11 Apr 2019 04:00:23 +0000 Subject: [PATCH 209/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/fr-FR.txt | 3 +++ data/language/zh-CN.txt | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/data/language/fr-FR.txt b/data/language/fr-FR.txt index 78c86021b2..0dd5747184 100644 --- a/data/language/fr-FR.txt +++ b/data/language/fr-FR.txt @@ -3765,6 +3765,9 @@ STR_6300 :{SMALLFONT}{BLACK}Télécharge tous les objets manquants s'ils sont STR_6301 :{SMALLFONT}{BLACK}Copie les noms des objets sélectionnés dans le presse-papier. STR_6302 :{SMALLFONT}{BLACK}Copie la liste des objets manquants dans le presse-papier. STR_6303 :Téléchargement de l'objet ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Ouvrir le sélecteur de paysage +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Option expérimentale pour utiliser plusieurs threads pour le rendu, peut causer des problèmes d'instabilité. ############# # Scenarios # diff --git a/data/language/zh-CN.txt b/data/language/zh-CN.txt index ad89e03fbb..4690a305e3 100644 --- a/data/language/zh-CN.txt +++ b/data/language/zh-CN.txt @@ -2425,7 +2425,6 @@ STR_3190 :额外的道路对象 STR_3191 :景物组别 STR_3192 :乐园入口 STR_3193 :水塘 -STR_3194 :剧情简介 STR_3195 :研发列表 STR_3196 :{WINDOW_COLOUR_2}研发组别: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}游戏开始时已研发好的项目: @@ -3594,8 +3593,8 @@ STR_6125 :对象类型 STR_6126 :未知类型 STR_6127 :文件: {STRING} STR_6128 :文件不能被加载, 因为其中一部分引用的对象丢失或错误. 以下是这些对象的列表. -STR_6129 :将选中的项目复制到剪贴板 -STR_6130 :将整个列表复制到剪贴板 +STR_6129 :复制 +STR_6130 :复制全部 STR_6131 :对象源 STR_6132 :忽略研究状态 STR_6133 :{SMALLFONT}{BLACK}使用还未被研究出的游乐设施和景观 @@ -3741,6 +3740,37 @@ STR_6272 :站台 STR_6273 :音乐 STR_6274 :无法设置配色方案... STR_6275 :{WINDOW_COLOUR_2}车站类型: +STR_6276 :{RED}{STRINGID} 有游客被困住了,这可能是因为无效的设施类型或者运行模式 +STR_6277 :{WINDOW_COLOUR_2}车站编号: {BLACK}{COMMA16} +STR_6278 :自动保存数量 +STR_6279 :{SMALLFONT}{BLACK}应该保留的自动保存数量 +STR_6284 :网络 +STR_6285 :网络信息 +STR_6286 :接收 +STR_6287 :发送 +STR_6288 :已接收 +STR_6289 :已发生 +STR_6290 :基础协议 +STR_6291 :指令 +STR_6292 :测绘 +STR_6293 :B +STR_6294 :KiB +STR_6295 :MiB +STR_6296 :GiB +STR_6297 :TiB +STR_6298 :{STRING}/秒 +STR_6280 :{SMALLFONT}{BLACK}聊天室 +STR_6281 :{SMALLFONT}{BLACK}在工具栏中加入激活聊天窗口的按钮 +STR_6282 :聊天室 +STR_6283 :暂时无法聊天。你连接到服务器了吗? +STR_6299 :下载全部 +STR_6300 :{SMALLFONT}{BLACK}从网络上下载可下载缺失文件 +STR_6301 :{SMALLFONT}{BLACK}将所选文件名称复制到剪贴板 +STR_6302 :{SMALLFONT}{BLACK}将整个缺失文件列表复制到剪贴板 +STR_6303 :下载文件 ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :打开景物选择器 +STR_6305 :多线程 +STR_6306 :{SMALLFONT}{BLACK}使用多个线程进行渲染的实验选项可能会导致游戏不稳定 ############# From 69ef23740e3cbb22e002cebdece4086eb5917f7c Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 15 Apr 2019 04:00:29 +0000 Subject: [PATCH 210/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/hu-HU.txt | 190 ++++- data/language/it-IT.txt | 34 +- data/language/zh-CN.txt | 1798 +++++++++++++++++++-------------------- 3 files changed, 1115 insertions(+), 907 deletions(-) diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index ea3aadac3f..3dbe5dfe33 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -142,6 +142,8 @@ STR_0559 :Nagy tematizált épület, tele ijesztő folyosókkal és kísérte STR_0560 :Egy hely, ahol a rosszul lett vendégek gyorsabban összeszedhetik magukat STR_0561 :Cirkuszi állatprodukció egy nagy sátorban STR_0562 :Motoros autók utaznak egy többszintes pálya mentén, miközben kísérteties díszletek és speciális effektusok mellett haladnak el +STR_0563 :Kényelmes, egyszerű biztonsági rudas vonatokban ülve élvezhetik az utasok a hatalmas, sima eséseket és csavaros pályákat, valamint a bőséges „légi időt” az emelkedők után +STR_0564 :Ez a fa pályán futó hullámvasút gyors, durva, hangos és „kontroll nélküli” utazási élményt nyújt, bőséges „légi idővel” STR_0578 :A kocsik egy abroncsokkal körbefogott, meredek esésekkel és palástorsókkal teli pálya mentén haladnak STR_0579 :Egy enyhe minigolf-játék STR_0582 :Önvezető légpárnás járművek @@ -512,6 +514,11 @@ STR_1166 :Nem süllyesztheted le itt a vízszintet.... STR_1167 :Nem emelheted fel itt a vízszintet.... STR_1146 :Még nem épült bejárat STR_1147 :Még nem épült kijárat +STR_1148 :Negyed terhelés +STR_1149 :Fél terhelés +STR_1150 :Háromnegyed terhelés +STR_1151 :Teljes terhelés +STR_1152 :Bármekkora terhelés STR_1153 :Magasságjelek a játékok pályáin STR_1154 :Magasságjelek a talajon STR_1155 :Magasságjelek az utakon @@ -558,6 +565,8 @@ STR_1202 :Egy ember áll a sorban STR_1203 :{COMMA16} ember áll a sorban STR_1204 :{COMMA16} perc a sorbanállási idő STR_1205 :{COMMA16} perc a sorbanállási idő +STR_1206 :{WINDOW_COLOUR_2}Várjon erre: +STR_1209 :{SMALLFONT}{BLACK}Válaszd ki, hogy várakozzon-e utasokra indulás előtt STR_1211 :{WINDOW_COLOUR_2}Minimum várakozási idő STR_1212 :{WINDOW_COLOUR_2}Maximum várakozási idő: STR_1213 :{SMALLFONT}{BLACK}Az indulás előtti minimum várakozási idő kiválasztása @@ -705,7 +714,7 @@ STR_1354 :{WINDOW_COLOUR_2}Legmagasabb esés: {BLACK}{LENGTH} STR_1355 :{WINDOW_COLOUR_2}Esések: {BLACK}{COMMA16} STR_1356 :{WINDOW_COLOUR_2}Fordítások: {BLACK}{COMMA16} STR_1357 :{WINDOW_COLOUR_2}Lyukak: {BLACK}{COMMA16} -STR_1358 :{WINDOW_COLOUR_2}Összes levegőben töltött idő: {BLACK}{COMMA2DP32} mp +STR_1358 :{WINDOW_COLOUR_2}Összes „légi” idő: {BLACK}{COMMA2DP32} mp STR_1359 :{WINDOW_COLOUR_2}Sorbanállási idő: {BLACK}{COMMA16} perc STR_1360 :{WINDOW_COLOUR_2}Sorbanállási idő: {BLACK}{COMMA16} perc STR_1361 :Nem változtatható meg a sebesség... @@ -1063,6 +1072,8 @@ STR_1742 :{WINDOW_COLOUR_2}Max. ember a játékon: STR_1743 :{SMALLFONT}{BLACK}Maximum ennyi ember lehet egyszerre a játékon STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_1749 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{DURATION} +STR_1752 :{SMALLFONT}{BLACK}A park egyedi vendégeinek listázása +STR_1753 :{SMALLFONT}{BLACK}A park vendégeinek összegző listázása STR_1754 :{BLACK}{COMMA16} vendég STR_1755 :{BLACK}{COMMA16} vendég STR_1756 :{WINDOW_COLOUR_2}Belépési díj: @@ -2239,7 +2250,6 @@ STR_3190 :Úti extrák STR_3191 :Díszletcsoportok STR_3192 :Park bejárata STR_3193 :Víz -STR_3194 :Pálya leírása STR_3195 :Találmányok listája STR_3196 :{WINDOW_COLOUR_2}Kutatási csoport: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}A játék kezdetekor már elérhető találmányok: @@ -2527,6 +2537,7 @@ STR_5366 :Normál STR_5367 :Gyors STR_5369 :Park paraméterei... STR_5370 :{SMALLFONT}{BLACK}Kattints erre a gombra, hogy módosítsd{NEWLINE}a park olyan paramétereit, mint{NEWLINE}a vendégek generálása és a pénz. +STR_5372 :Jobb egeres húzás invertálása STR_5373 :Név {STRINGID} STR_5374 :Dátum {STRINGID} STR_5375 :▲ @@ -2712,6 +2723,7 @@ STR_5578 :Orosz rubel (₽) STR_5579 :Ablak méretezése: STR_5580 :Cseh korona (Kč) STR_5581 :FPS megjelenítése +STR_5582 :Egérmutató elfogása az ablakban STR_5583 :{COMMA1DP16} m/s STR_5584 :SI STR_5586 :Boltok és bódék automatikus megnyitása @@ -2792,6 +2804,7 @@ STR_5762 :Kínai jüan (CN¥) STR_5763 :Minden fájl STR_5764 :Érvénytelen játéktípus STR_5765 :Az érvénytelen típusú játékok nem szerkeszthetők +STR_5766 :Magyar forint (Ft) STR_5767 :Bevétel STR_5768 :Összes vendég STR_5769 :Teljes nyereség @@ -2807,7 +2820,7 @@ STR_5778 :Építés ideje: {COMMA16} éve STR_5779 :Bevétel: {CURRENCY2DP} óránként STR_5780 :Üzemeltetési költség: {CURRENCY2DP} óránként STR_5781 :Üzemeltetési költség: Ismeretlen -STR_5782 :Kapcsolódva vagy. A(z) ’{STRING}’ lenyomásával cseveghetsz. +STR_5782 :Csatlakoztál. A(z) ’{STRING}’ lenyomásával cseveghetsz. STR_5783 :{WINDOW_COLOUR_2}Lezárt pálya STR_5784 :{BLACK}Teljesíts korábbi pályákat a feloldásához. STR_5785 :A csoport nem nevezhető át... @@ -2838,7 +2851,13 @@ STR_5820 :{SMALLFONT}{BLACK}A játék minimalizálása, ha elveszti a fókusz STR_5822 :{SMALLFONT}{BLACK}A nap és az éjszaka váltakozásának bekapcsolása.{NEWLINE}A teljes ciklus egy játékbeli hónapig tart STR_5823 :{SMALLFONT}{BLACK}Nagybetűs megjelenítés a hirdetőtáblákon (RCT1-beli viselkedés) STR_5824 :{SMALLFONT}{BLACK}A villámhatás kikapcsolása{NEWLINE}a viharok alatt +STR_5825 :{SMALLFONT}{BLACK}Az egérmutató maradjon az ablakon belül +STR_5826 :{SMALLFONT}{BLACK}A látkép jobb egeres húzásának invertálása STR_5835 :{SMALLFONT}{BLACK}A játék némítása, ha az ablak elveszti a fókuszt +STR_5838 :{SMALLFONT}{BLACK}Külön gomb a pénzügyi ablak számára az eszköztáron +STR_5839 :{SMALLFONT}{BLACK}Külön gomb a kutatás-fejlesztés ablak számára az eszköztáron +STR_5840 :{SMALLFONT}{BLACK}Külön gomb a csalások ablak számára az eszköztáron +STR_5841 :{SMALLFONT}{BLACK}Külön gomb a legutóbbi hírek ablak számára az eszköztáron STR_5843 :{SMALLFONT}{BLACK}A pályák progresszív feloldásának engedélyezése (RCT1-beli viselkedés) STR_5844 :{SMALLFONT}{BLACK}Tartsa fenn a kapcsolatot a többjátékos{NEWLINE}szerverrel akkor is, ha szinkronizációs vagy egyéb hiba jelentkezik STR_5845 :{SMALLFONT}{BLACK}Hozzáadja a hibakereső{NEWLINE}eszközök gombját az eszköztárhoz.{NEWLINE}Engedélyezi a fejlesztői konzol gyorsbillentyűjét @@ -2935,12 +2954,18 @@ STR_6010 :{COMMA2DP32} m STR_6011 :{COMMA1DP16} láb STR_6016 :Mező módosítása STR_6017 :Kérlek lassíts +STR_6030 :{SMALLFONT}{BLACK}Díszletválasztó. Kattints bármelyik díszletre a térképen, hogy újat építhess ugyanabból a darabból. STR_6031 :Szerver leírása: STR_6032 :Szerver üdvözlés: STR_6033 :Az RCT1 telepítési útvonala: +STR_6034 :{SMALLFONT}{BLACK}{STRING} +STR_6035 :Kérlek válaszd ki az RCT1 mappádat +STR_6036 :{SMALLFONT}{BLACK}Törlés +STR_6037 :Kérlek válassz egy érvényes RCT1 mappát STR_6041 :{BLACK}Nem vettél fel gépészt! STR_6055 :OpenRCT2 magasságtérkép fájl STR_6056 :{SMALLFONT}{BLACK}Némítás +STR_6057 :{SMALLFONT}{BLACK}Külön gomb a némítási opció számára az eszköztáron STR_6058 :Némítás STR_6059 :» STR_6060 :Vendégek vásárlásainak animálása @@ -2953,6 +2978,7 @@ STR_6099 :Kapcsolódtál a szerverhez. STR_6100 :Bontottad a kapcsolatot a szerverrel. STR_6101 :Nem csökken a játékok értéke STR_6102 :{SMALLFONT}{BLACK}A játékok értéke nem csökken az idő múlásával, így a vendégek nem fogják hirtelen azt gondolni, hogy túl drágák +STR_6103 :{SMALLFONT}{BLACK}Ez a beállítás le van tiltva hálózati játék alatt. STR_6104 :Dugóhúzó hullámvasút STR_6105 :Hiperhullámvasút STR_6106 :Autós utazás @@ -2983,6 +3009,7 @@ STR_6140 :Változási napló... STR_6141 :RCT1 alsó eszköztár STR_6142 :{WINDOW_COLOUR_2}Pálya neve: {BLACK}{STRING} STR_6143 :{WINDOW_COLOUR_2}Játék típusa: {BLACK}{STRINGID} +STR_6146 :Minden rajzolható pályaelem engedélyezése STR_6148 :Csatlakozás a főszerverhez... STR_6149 :Nem sikerült csatlakozni a főszerverhez STR_6150 :Érvénytelen válasz a főszervertől (nincs JSON-szám) @@ -2994,10 +3021,11 @@ STR_6156 :A név le van foglalva STR_6157 :Konzol STR_6158 :Fájl betöltése sikertelen...{NEWLINE}Nem kompatibilis RCTC verzió: {COMMA16} STR_6159 :Sima legközelebbi szomszéd +STR_6160 :{WINDOW_COLOUR_2}Rendelkezésre álló járművek: {BLACK}{STRING} STR_6161 :Rácsok megjelenítése be/ki STR_6162 :Forgó vad egér STR_6164 :{WHITE}❌ -STR_6165 :Vertikális szinkron használata +STR_6165 :Vertikális szinkron STR_6166 :{SMALLFONT}{BLACK}A megjelenített képkockákat a kijelző frissítési gyakoriságához igazítja, így megakadályozza a kép szétcsúszását. STR_6167 :{SMALLFONT}{BLACK}Haladó STR_6168 :Főcím @@ -3111,7 +3139,7 @@ STR_6277 :{WINDOW_COLOUR_2}Állomás index: {BLACK}{COMMA16} STR_6278 :Automentések mennyisége STR_6279 :{SMALLFONT}{BLACK}A megőrzendő automentések száma STR_6280 :{SMALLFONT}{BLACK}Chat -STR_6281 :{SMALLFONT}{BLACK}Külön chat gomb mutatása az eszköztáron +STR_6281 :{SMALLFONT}{BLACK}Külön gomb a chat ablak számára az eszköztáron STR_6282 :Chat STR_6283 :A chat jelenleg nem elérhető. Csatlakozva vagy szerverhez? STR_6284 :Hálózat @@ -3134,6 +3162,9 @@ STR_6300 :{SMALLFONT}{BLACK}Az összes hiányzó objektum letöltése, ha el STR_6301 :{SMALLFONT}{BLACK}A kiválasztott objektumnév vágólapra másolása. STR_6302 :{SMALLFONT}{BLACK}A hiányzó objektumok teljes listájának vágólapra másolása. STR_6303 :Objektum letöltése ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Díszletválasztó megnyitása +STR_6305 :Többszálúság +STR_6306 :{SMALLFONT}{BLACK}Kísérleti beállítás, mellyel bekapcsolható a több szálon történő megjelenítés, instabilitást okozhat. ############# # Scenarios # @@ -3403,6 +3434,155 @@ STR_DTLS :Egy nagy kertnek arra van szüksége, hogy sikeres vidámpark legye ## Loopy Landscapes + +STR_SCNR :Jéghegy-szigetek +STR_PARK :Jéghegy-szigetek +STR_DTLS :Ez az ambiciózus vidámpark egy csoportnyi jéghegyre épült + + +STR_SCNR :Vulkánia +STR_PARK :Vulkánia +STR_DTLS :Egy szunnyadó vulkán adja ennek a hullámvasút-építő kihívásnak a helyszínét + + +STR_SCNR :Száraz Magasságok +STR_PARK :Száraz Magasságok +STR_DTLS :Az a kihívásod, hogy gondoskodj a park fejlesztéséről, miközben biztosítod a vendégek jókedvét, pénzügyi korlátok nélkül + + +STR_SCNR :Borotva Sziklák +STR_PARK :Borotva Sziklák +STR_DTLS :Az a feladatod, hogy egy masszív, hullámvasutakkal teli parkot alakíts ki a Borotva Sziklák között + + +STR_SCNR :Kráter-tó +STR_PARK :Kráter-tó +STR_DTLS :Egy ősi kráterben elterülő hatalmas tó a park a helyszíne + + +STR_SCNR :Szédítő Kilátások +STR_PARK :Szédítő Kilátások +STR_DTLS :Ebben a nagy parkban már van egy kiváló hiperhullámvasút, de sokkal nyereségesebbé kell tenned + + +STR_SCNR :Paradicsomi Móló 2 +STR_PARK :Paradicsomi Móló 2 +STR_DTLS :Paradicsomi Móló kiterjesztette a tenger feletti sétány-hálózatát és a feladatod az, hogy a park bővítésével biztosítsd az extra hely kihasználtságát + + +STR_SCNR :Sárkány-öböl +STR_PARK :Sárkány-öböl +STR_DTLS :Ez a tengerparti öböl a helyszíne ennek a hullámvasút-építő kihívásnak + + +STR_SCNR :Jó Lovag Park +STR_PARK :Jó Lovag Park +STR_DTLS :Egy kastély két hullámvasúttal, amit egy nagyobb vidámparkká kell fejlesztened + + +STR_SCNR :Nyüzsgő Nyúlkert +STR_PARK :Nyüzsgő Nyúlkert +STR_DTLS :Egy park, ahol az utak és hullámvasutak nagy része föld alatt van + + +STR_SCNR :Nagy Gleccser +STR_PARK :Nagy Gleccser +STR_DTLS :Fejleszd vidámparkká ezt a gleccserekkel teli völgyet + + +STR_SCNR :Őrült Kráterek +STR_PARK :Őrült Kráterek +STR_DTLS :Egy messzi világban, ahol nincs szükség pénzre, szórakoztató központot kell építened, hogy biztosítsd az emberek boldogságát + + +STR_SCNR :Sivár Sivatag +STR_PARK :Sivár Sivatag +STR_DTLS :Öt hullámvasutat kell befejezni ebben a sivatagi parkban + + +STR_SCNR :Fakukac Park +STR_PARK :Fakukac Park +STR_DTLS :Ez a történelmi park csak régi stílusú játékokat építhet + + +STR_SCNR :Ikarusz Park +STR_PARK :Ikarusz Park +STR_DTLS :Fejleszd ezt a földönkívüli parkot, hogy maximalizáld a nyereségét + + +STR_SCNR :Napos Mocsarak +STR_PARK :Napos Mocsarak +STR_DTLS :Ennek a jól tematizált vidámparknak már számos játéka van, de bőven van helye a terjeszkedésre + + +STR_SCNR :Rémálom Dombok +STR_PARK :Rémálom Dombok +STR_DTLS :Egy rémisztő vidámpark, a közepén egy hatalmas hullámvasúttal + + +STR_SCNR :Mennydörgő-sziklák +STR_PARK :Mennydörgő-sziklák +STR_DTLS :A homokból két nagydarab szikla áll ki, melyeken megkezdődött egy vidámpark építése + + +STR_SCNR :Oktogon Park +STR_PARK :Oktogon Park +STR_DTLS :Tíz hullámvasutat kell építened ebben a nagy parkban + + +STR_SCNR :Élménysziget +STR_PARK :Élménysziget +STR_DTLS :A hosszú, keskeny sziget kihívásokkal teli helyszín a megadott hullámvasutak építésére + + +STR_SCNR :Jégcsap Világok +STR_PARK :Jégcsap Világok +STR_DTLS :Alakítsd át a jeges tájat virágzó vidámparkká + + +STR_SCNR :Déli Homok +STR_PARK :Déli Homok +STR_DTLS :Ez a néhány okosan tervezett hullámvasúttal rendelkező sivatagi park arra vár, hogy kibővítsd + + +STR_SCNR :Törpe Tornyok +STR_PARK :Törpe Tornyok +STR_DTLS : Öt meglévő hullámvasutat kell befejezned ebben a kis parkban + + +STR_SCNR :Sohamár Park +STR_PARK :Sohamár Park +STR_DTLS :Egy nagy park, egyedi közlekedési rendszerrel a széle körül + + +STR_SCNR :Pacifica +STR_PARK :Pacifica +STR_DTLS :Ez a nagy sziget csak a tiéd, hogy vidámparkká fejleszd + + +STR_SCNR :Városi Dzsungel +STR_PARK :Városi Dzsungel +STR_DTLS :Ez a hatalmas elhagyatott felhőkarcoló egyedi lehetőség egy vidámpark-fejlesztő számára + + +STR_SCNR :Terrorváros +STR_PARK :Terrorváros +STR_DTLS :Ez a városi terület csak a tiéd, hogy vidámparkká fejleszd + + +STR_SCNR :Megavilág Park +STR_PARK :Megavilág Park +STR_DTLS :Van mit javítani ezen az óriási, játékokkal teli parkon + + +STR_SCNR :Vénuszi Tavak +STR_PARK :Vénuszi Tavak +STR_DTLS :Alakítsd át egy messzi bolygó földterületét vidámparkká + + +STR_SCNR :Mikro Park +STR_PARK :Mikro Park +STR_DTLS :Próbáld meg létrehozni a világ legkisebb nyereséges parkját ## Real Parks from RCT1 # None of them had details diff --git a/data/language/it-IT.txt b/data/language/it-IT.txt index 49a6a26494..b0be645a0a 100644 --- a/data/language/it-IT.txt +++ b/data/language/it-IT.txt @@ -2418,7 +2418,6 @@ STR_3190 :Percorsi (extra) STR_3191 :Gruppi di scenari STR_3192 :Entrata del parco STR_3193 :Acqua -STR_3194 :Descrizione dello scenario STR_3195 :Lista delle invenzioni STR_3196 :{WINDOW_COLOUR_2}Gruppo di ricerca: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Oggetti già inventati all'avvio della partita @@ -3587,8 +3586,8 @@ STR_6125 :Tipo oggetto STR_6126 :Tipo sconosciuto STR_6127 :File: {STRING} STR_6128 :Non è stato possibile caricare il file perché alcuni riferimenti ad oggetti presenti sono corrotti o mancanti. Una lista di tali oggetti è riportata qui di seguito. -STR_6129 :Copia oggetto selezionato -STR_6130 :Copia l'intera lista di oggetti +STR_6129 :Copia +STR_6130 :Copia tutti STR_6131 :Origine oggetto STR_6132 :Ignora stato di ricerca STR_6133 :{SMALLFONT}{BLACK}Permette di accedere ad attrazioni e scenari non ancora inventati @@ -3736,6 +3735,35 @@ STR_6274 :Impossibile impostare schema colore... STR_6275 :{WINDOW_COLOUR_2}Stile stazione: STR_6276 :{RED}{STRINGID} ha ospiti bloccati, probabilmente a causa di un errato tipo di attrazione o modalità operativa. STR_6277 :{WINDOW_COLOUR_2}Indice stazione: {BLACK}{COMMA16} +STR_6278 :Numero autosalvataggi +STR_6279 :{SMALLFONT}{BLACK}Numero di autosalvataggi da mantenere +STR_6280 :{SMALLFONT}{BLACK}Chat +STR_6281 :{SMALLFONT}{BLACK}Mostra un tasto separato nella barra degli strumenti per la finestra di chat +STR_6282 :Chat +STR_6283 :La chat non è disponibile al momento. Si è connessi a un server? +STR_6284 :Rete +STR_6285 :Informazioni di rete +STR_6286 :Ricevi +STR_6287 :Invia +STR_6288 :Totale ricevuto +STR_6289 :Totale inviato +STR_6290 :Protocollo di base +STR_6291 :Comandi +STR_6292 :Mappa +STR_6293 :B +STR_6294 :KiB +STR_6295 :MiB +STR_6296 :GiB +STR_6297 :TiB +STR_6298 :{STRING}/sec +STR_6299 :Scarica tutti +STR_6300 :{SMALLFONT}{BLACK}Scarica tutti gli oggetti mancanti se sono disponibili online. +STR_6301 :{SMALLFONT}{BLACK}Copia il nome dell'oggetto selezionato negli appunti. +STR_6302 :{SMALLFONT}{BLACK}Copia l'intera lista degli oggetti mancanti negli appunti. +STR_6303 :Scaricamento oggetto ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Apri selezione scenario +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Opzione sperimentale per utilizzare più thread per il rendering, potrebbe causare instabilità. ############# # Scenarios # diff --git a/data/language/zh-CN.txt b/data/language/zh-CN.txt index 4690a305e3..7dbb822701 100644 --- a/data/language/zh-CN.txt +++ b/data/language/zh-CN.txt @@ -12,7 +12,7 @@ STR_0007 :迷你火车 STR_0008 :单轨电车 STR_0009 :迷你悬挂过山车 STR_0010 :游船出租 -STR_0011 :木制疯狂老鼠过山车 +STR_0011 :木制野生鼠过山车 STR_0012 :赛马过山车 STR_0013 :轨道小车 STR_0014 :喷射-自由落体 @@ -100,30 +100,30 @@ STR_0091 :Unknown Ride (59) # LIM: Linear Induction Motors STR_0092 :LIM喷射过山车 STR_0512 :一种紧凑的过山车,有着螺旋状的爬升和平滑盘旋的下坠 -STR_0513 :A looping roller coaster where the riders ride in a standing position -STR_0514 :Trains suspended beneath the roller coaster track swing out to the side around corners -STR_0515 :A steel roller coaster with trains that are held beneath the track, with many complex and twisting track elements -STR_0516 :A gentle roller coaster for people who haven't yet got the courage to face the larger rides -STR_0517 :Passengers ride in miniature trains along a narrow-gauge railway track -STR_0518 :Passengers travel in electric trains along a monorail track -STR_0519 :Passengers ride in small cars hanging beneath the single-rail track, swinging freely from side to side around corners -STR_0520 :A dock platform where guests can drive/row personal watercraft on a body of water -STR_0521 :A fast and twisting roller coaster with tight turns and steep drops. Intensity is bound to be high. -STR_0522 :A smaller roller coaster where the riders sit above the track with no car around them -STR_0523 :Riders travel slowly in powered vehicles along a track-based route -STR_0524 :Freefall car is pneumatically launched up a tall steel tower and then allowed to freefall down -STR_0525 :Riders career down a twisting track guided only by the curvature and banking of the semi-circular track -STR_0526 :Passengers travel in a rotating observation cabin which travels up a tall tower -STR_0527 :A smooth steel-tracked roller coaster capable of vertical loops -STR_0528 :Riders travel in inflatable dinghies down a twisting semi-circular or completely enclosed tube track -STR_0529 :Mine train themed roller coaster trains career along steel roller coaster track made to look like old railway track -STR_0530 :Cars hang from a steel cable which runs continuously from one end of the ride to the other and back again -STR_0531 :A compact steel-tracked roller coaster where the train travels through corkscrews and loops +STR_0513 :乘客采用站立方式乘坐的过山车,全身都能感受到翻滚时血液在体内的涌动 +STR_0514 :一种转弯的时候会自行产生离心运动,车厢可自由摆动的过山车 +STR_0515 :一种车厢在轨道下方的铁制的过山车, 同时附有复杂且扭曲的轨道元素 +STR_0516 :一种在各方面都比较缓和的过山车,适合不擅长乘着过山车的乘坐 +STR_0517 :乘客乘坐小型列车沿着一条窄轨道前进 +STR_0518 :乘客乘坐电车沿着一条单轨铁道 +STR_0519 :乘客乘坐悬挂在单轨轨道下方的车厢,在拐角处从一侧到另一侧自由摆动 +STR_0520 :一个码头,允许游客在水上驾驶/划船 +STR_0521 :快速且扭曲的过山车,紧凑地转弯,陡峭地下落造就了极高的刺激度。 +STR_0522 :一款较小型的过山车, 乘客坐在轨道上而并没有其他车包围他们 +STR_0523 :乘客会坐在有动力的车辆内, 慢慢地依照轨道进行观光游览 +STR_0524 :自由落体的车辆会被气体喷射到高塔顶, 并随后自由落下 +STR_0525 :乘客飞驰在扭曲的轨道上, 只靠弯道及半月型的轨道引领他们 +STR_0526 :乘客会在不断旋转并上升到最顶的座舱内观看乐园景色 +STR_0527 :一款以顺滑轨道为特征的过山车, 并附有垂直回环可供使用 +STR_0528 :乘客坐在充气小艇中于半月型或完全封闭的轨道上滑翔 +STR_0529 :以采矿列车为主题的过山车沿着铁架轨道行驶, 令它很像在古老的轨道行驶上 +STR_0530 :列车悬挂在钢缆下并不断于车站与车站之间游走 +STR_0531 :一款列车会穿过螺旋及回环的较小型过山车 STR_0532 : STR_0533 : -STR_0534 :Self-drive petrol-engined go karts -STR_0535 :Log-shaped boats travel along a water channel, splashing down steep slopes to soak the riders -STR_0536 :Circular boats meander along a wide water channel, splashing through waterfalls and thrilling riders through foaming rapids +STR_0534 :自驾式, 并以气油驱动的小型赛车(卡丁车) +STR_0535 :以运木为形状的小船穿梭于有水的轨道, 并会于下滑时溅湿游客 +STR_0536 :圆形的小船穿梭于比较广阔的水道, 于水道中被瀑布溅湿, 并有激流使乘客的紧张感大增 STR_0537 : STR_0538 : STR_0539 : @@ -138,50 +138,50 @@ STR_0550 : STR_0551 : STR_0552 : STR_0553 : -STR_0554 :The car is accelerated out of the station along a long level track using Linear Induction Motors, then heads straight up a vertical spike of track, freefalling back down to return to the station -STR_0555 :Guests ride in an elevator up or down a vertical tower to get from one level to another -STR_0556 :Extra-wide cars descend completely vertical sloped track for the ultimate freefall roller coaster experience +STR_0554 :列车会被又长又直的轨道上的直线发动机加速, 然后衝上垂直轨道, 自由落体后回到车站 +STR_0555 :游客乘搭升降机上下穿梭于垂直的管道中, 并借此访问另一层 +STR_0556 :加阔的列车于垂直下坡上完全滑落, 给予人终极的过山车自由落体体验 STR_0557 : STR_0558 : STR_0559 : STR_0560 : STR_0561 : -STR_0562 :Powered cars travel along a multi-level track past spooky scenery and special effects -STR_0563 :Sitting in comfortable trains with only simple lap restraints riders enjoy giant smooth drops and twisting track as well as plenty of 'air time' over the hills -STR_0564 :Running on wooden track, this coaster is fast, rough, noisy, and gives an 'out of control' riding experience with plenty of 'air time' -STR_0565 :A simple wooden roller coaster capable of only gentle slopes and turns, where the cars are only kept on the track by side friction wheels and gravity -STR_0566 :Individual roller coaster cars zip around a tight zig-zag layout of track with sharp corners and short sharp drops -STR_0567 :Sitting in seats suspended either side of the track, riders are pitched head-over-heels while they plunge down steep drops and travel through various inversions -STR_0569 :Riding in special harnesses below the track, riders experience the feeling of flight as they swoop through the air -STR_0571 :Circular cars spin around as they travel along the zig-zagging wooden track -STR_0572 :Large capacity boats travel along a wide water channel, propelled up slopes by a conveyer belt, accelerating down steep slopes to soak the riders with a gaint splash -STR_0573 :Powered helicoper shaped cars running on a steel track, controlled by the pedalling of the riders -STR_0574 :Riders are held in special harnesses in a lying-down position, travlling through twisted track and inversions either on their backs or facing the ground -STR_0575 :Powered trains hanging from a single rail transport people around the park -STR_0577 :Bogied cars run on wooden tracks, turning around on special reversing sections -STR_0578 :Cars run along track enclosed by circular hoops, traversing steep drops and heartline twists +STR_0562 :有动力的车辆将会穿梭于有著恐怖景物及特效的多层轨道中 +STR_0563 :乘客坐在舒适并只有简单安全装备的列车上享受巨大而顺滑的下滑, 扭曲的轨道和充足的'空中'时间 +STR_0564 :一款在木製轨道运行的过山车, 这个过山车会嘈吵地飞驰过高低不平的轨道, 给乘客充足的'空中时间'之馀,同时会给人一种'失去控制'的乘坐体验 +STR_0565 :一款只能使用普通下坡及弯道的简单木製过山车, 车辆只靠产生轨道阻力的车轮及重力滑翔于轨道上 +STR_0566 :每辆单独的过山车都会游走在附有急弯及急短下坡的Z型轨道上 +STR_0567 :乘客坐在悬挂在轨道的不同位置下, 衝下陡下坡及各种倒转轨道时, 会被翻腾得四脚朝天 +STR_0569 :乘客将会乘坐在轨道下的特别繫带, 在空中盘旋时体验飞一般的感受 +STR_0571 :圆型的车辆于他们行走在Z型轨道上被不停的转动 +STR_0572 :载客量大的小船游走于宽敞的水道上, 由输送带送他们上坡, 并于下坡中加速, 务求溅出巨型的水花令到乘客全身湿透 +STR_0573 :有动力的直升机型车辅于钢轨上游走, 他们由乘客的脚踏所控制 +STR_0574 :乘客躺卧在特别繫带中, 以他们面向的背或头游走于曲折的轨道及翻转 +STR_0575 :有动力的列车悬挂在单轨下运送乘客到乐园内的不同地方 +STR_0577 :拥有转向架的车辅于木製轨道上, 被特别的倒转装置转向 +STR_0578 :车辆运行于O型的轨道中, 并会穿过陡下坡及横滚轨道 STR_0579 : -STR_0580 :A giant steel roller coaster capable of smooth drops and hills of over 300ft -STR_0581 :A ring of seats is pulled to the top of a tall tower while gently rotating, then allowed to free-fall down, stopping gently at the bottom using magnetic brakes +STR_0580 :一款可建造顺滑下坡及高达300英尺坡道的巨型铁製过山车 +STR_0581 :围绕著塔的座位会在不断慢慢旋转中被拉至塔顶, 然后便自由落体, 再被有磁力的煞车装置慢慢煞停于站台 STR_0582 : STR_0583 : -STR_0584 :Special bicycles run on a steel monorail track, propelled by the pedalling of the riders -STR_0585 :Riders sit in pairs of seats suspended beneath the track as they loop and twist through tight inversions -STR_0586 :Boat shaped cars run on roller coaster track to allow twisting curves and steep drops, splashing down into sections of water for gentle river sections -STR_0587 :After an exhilarating air-powered launch, the train speeds up a vertical track, over the top, and vertically down the other side to return to the station -STR_0588 :Individual cars run beneath a zig-zagging track with hairpin turns and sharp drops +STR_0584 :运行在铁製单轨上的特别单车, 像一般单车一样, 会被乘客踏行 +STR_0585 :乘客坐在轨道悬挂下的一对对的座位经历被紧密的轨道上旋转及迴转 +STR_0586 :船型的车辆行驶于过山车的轨道上, 允许他们能够拥有扭曲式的弯道陡下坡等轨道配置, 更会被普通的水道所溅湿 +STR_0587 :过山车列车被令人胆跳心惊的气动发车加速衝上垂直轨道后, 穿过最顶, 然后垂直下落到另一边回到车站 +STR_0588 :每辆单独的过山车游走在附有髮夹弯及急下坡的Z型轨道上 STR_0589 : -STR_0590 :Riders ride in a submerged submarine through an underwater course -STR_0591 :Raft-shaped boats gently meander around a river track +STR_0590 :乘客在潜艇中观赏水底的景观 +STR_0591 :木筏造型船于河道上慢慢地游览著 STR_0593 : -STR_0598 :Inverted roller coaster trains are accelerated out of the station to travel up a vertical spike of track, then reverse back through the station to travel backwards up another vertical spike of track -STR_0599 :A compact roller coaster with individual cars and smooth twisting drops -STR_0600 :Powered mine trains career along a smooth and twisted track layout -STR_0602 :Roller coaster trains are accelerated out of the station by linear induction motors to speed through twisting inversions +STR_0598 :反转式过山车加速离开车站, 穿过到垂直轨道的尖端, 然后倒转返回到车站, 再穿越到另一边垂直轨道的尖端 +STR_0599 :一款拥有独立车辆及顺滑又弯曲的下坡的紧凑式过山车 +STR_0600 :有动车的採矿列车游走在顺滑但又曲折的轨道配置中 +STR_0602 :过山车列车由直线发动机加速离开车站, 穿过盘绕的倒转轨道后回到车站 STR_0767 :游客 {INT32} -STR_0768 :勤杂工 {INT32} -STR_0769 :机械师 {INT32} -STR_0770 :警卫 {INT32} +STR_0768 :清洁工人 {INT32} +STR_0769 :维修人员 {INT32} +STR_0770 :安全警卫 {INT32} STR_0771 :表演人员 {INT32} STR_0777 :未命名游乐园{POP16}{POP16} STR_0778 :指示牌 @@ -314,7 +314,7 @@ STR_0924 :{SMALLFONT}{BLACK}向下螺旋 STR_0925 :{SMALLFONT}{BLACK}向上螺旋 STR_0926 :不能移除此物... STR_0927 :不能在此建造... -STR_0928 :{SMALLFONT}{BLACK}Chain lift, to pull cars up slopes +STR_0928 :{SMALLFONT}{BLACK}提升坡将会把车厢拉上坡 STR_0929 :'S'型弯道 (向左) STR_0930 :'S'型弯道 (向右) STR_0931 :垂直回环 (向左) @@ -391,7 +391,7 @@ STR_1001 :轨道不适合此类型的车 STR_1002 :不能开启 {POP16}{POP16}{POP16}{STRINGID}... STR_1003 :不能测试 {POP16}{POP16}{POP16}{STRINGID}... STR_1004 :不能关闭 {POP16}{POP16}{POP16}{STRINGID}... -STR_1005 :Can't start construction on {POP16}{POP16}{POP16}{STRINGID}... +STR_1005 :不能开始建造 {POP16}{POP16}{POP16}{STRINGID}... STR_1006 :必须先关闭 STR_1007 :不能创建足够的车辆 STR_1008 :{SMALLFONT}{BLACK}开放, 关闭或测试游乐设施/店铺 @@ -408,20 +408,20 @@ STR_1018 :不能做出改变... STR_1019 :不能做出改变... STR_1020 :不能做出改变... STR_1021 :{POP16}{POP16}{POP16}{POP16}{STRINGID} -STR_1022 :{POP16}{POP16}{POP16}{COMMA16} car per train -STR_1023 :{POP16}{POP16}{POP16}{COMMA16} cars per train -STR_1024 :{COMMA16} car per train -STR_1025 :{COMMA16} cars per train +STR_1022 :{POP16}{POP16}{POP16}{COMMA16} 车/列车 +STR_1023 :{POP16}{POP16}{POP16}{COMMA16} 车/列车 +STR_1024 :{COMMA16} 车/列车 +STR_1025 :{COMMA16} 车/列车 STR_1026 :车站站台太长! -STR_1027 :{SMALLFONT}{BLACK}Locate this on Main View +STR_1027 :{SMALLFONT}{BLACK}将主视定位到此 STR_1028 :离开地图边缘! -STR_1029 :Cannot build partly above and partly below water! -STR_1030 :Can only build this underwater! -STR_1031 :Can't build this underwater! -STR_1032 :Can only build this on water! -STR_1033 :Can only build this above ground! -STR_1034 :Can only build this on land! -STR_1035 :Local authority won't allow construction above tree-height! +STR_1029 :不能在半水上半水下地形上建造! +STR_1030 :只能建造在水下! +STR_1031 :不能建造在水下! +STR_1032 :只能建造在水上! +STR_1033 :只能建造在地上! +STR_1034 :只能建造在地面! +STR_1035 :当地权威不允许建筑物高度超过树的高度 STR_1036 :加载游戏 STR_1037 :加载地形 STR_1038 :将存档转换为关卡 @@ -443,493 +443,493 @@ STR_1053 :{SMALLFONT}{BLACK}游乐园内的游乐设施 STR_1054 :{SMALLFONT}{BLACK}命名游乐设施/店铺 STR_1055 :{SMALLFONT}{BLACK}命名游客 STR_1056 :{SMALLFONT}{BLACK}命名职员 -STR_1057 :游乐设施/店铺名称 -STR_1058 :Enter new name for this ride/attraction: -STR_1059 :Can't rename ride/attraction... -STR_1060 :Invalid ride/attraction name -STR_1061 :Normal mode -STR_1062 :Continuous circuit mode -STR_1063 :Reverse-Incline launched shuttle mode -STR_1064 :Powered launch (passing station) -STR_1065 :Shuttle mode -STR_1066 :Boat hire mode -STR_1067 :Upward launch -STR_1068 :Rotating lift mode -STR_1069 :Station to station mode -STR_1070 :Single ride per admission -STR_1071 :Unlimited rides per admission +STR_1057 :游乐设施/店铺命名 +STR_1058 :请输入这个游乐设施/店铺的新名字: +STR_1059 :重命名 设施/店铺 失败... +STR_1060 :无效的设施/店铺名字 +STR_1061 :正常模式 +STR_1062 :连续循环模式 +STR_1063 :反向倾斜循环发车模式 +STR_1064 :动力发车 (通过车站) +STR_1065 :循环模式 +STR_1066 :出租小船模式 +STR_1067 :向上发车 +STR_1068 :旋转上升模式 +STR_1069 :站对站模式 +STR_1070 :每次入场单程 +STR_1071 :每次入场无限次乘坐 STR_1072 :迷宫模式 STR_1073 :赛车模式 -STR_1074 :Bumper-car mode +STR_1074 :碰碰车模式 STR_1075 :摇摆模式 -STR_1076 :Shop stall mode +STR_1076 :商店摆摊模式 STR_1077 :旋转模式 STR_1078 :向前旋转 STR_1079 :向后旋转 STR_1080 :电影: ”飞行员复仇记” STR_1081 :3D电影: ”鼠尾” -STR_1082 :Space rings mode -STR_1083 :Beginners mode -STR_1084 :LIM-powered launch +STR_1082 :太空转轮模式 +STR_1083 :菜鸟模式 +STR_1084 :LIM动力模式 STR_1085 :电影: ”尖叫乘客” STR_1086 :3D电影: ”暴风猎人” STR_1087 :3D电影: ”太空海盗” -STR_1088 :Intense mode -STR_1089 :Berserk mode +STR_1088 :刺激模式 +STR_1089 :惊悚模式 STR_1090 :鬼屋模式 -STR_1091 :Circus show mode -STR_1092 :Downward launch -STR_1093 :Crooked house mode -STR_1094 :Freefall drop mode -STR_1095 :Continuous circuit block sectioned mode -STR_1096 :Powered launch (without passing station) -STR_1097 :Powered launch block sectioned mode -STR_1098 :Moving to end of {POP16}{STRINGID} -STR_1099 :Waiting for passengers at {POP16}{STRINGID} -STR_1100 :Waiting to depart {POP16}{STRINGID} -STR_1101 :Departing {POP16}{STRINGID} -STR_1102 :Travelling at {VELOCITY} -STR_1103 :Arriving at {POP16}{STRINGID} -STR_1104 :Unloading passengers at {POP16}{STRINGID} -STR_1105 :Travelling at {VELOCITY} -STR_1106 :Crashing! -STR_1107 :Crashed! -STR_1108 :Travelling at {VELOCITY} -STR_1109 :Swinging -STR_1110 :Rotating -STR_1111 :Rotating -STR_1112 :Operating -STR_1113 :Showing film -STR_1114 :Rotating -STR_1115 :Operating -STR_1116 :Operating -STR_1117 :Doing circus show -STR_1118 :Operating -STR_1119 :Waiting for cable lift -STR_1120 :Travelling at {VELOCITY} -STR_1121 :Stopping -STR_1122 :Waiting for passengers -STR_1123 :Waiting to start -STR_1124 :Starting -STR_1125 :Operating -STR_1126 :Stopping -STR_1127 :Unloading passengers -STR_1128 :Stopped by block brakes -STR_1129 :All vehicles in same colours -STR_1130 :Different colours per {STRINGID} -STR_1131 :Different colours per vehicle -STR_1132 :Vehicle {POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1133 :Vehicle {POP16}{COMMA16} +STR_1091 :马戏团表演模式 +STR_1092 :向下发车 +STR_1093 :古怪小屋模式 +STR_1094 :自由落体式下降模式 +STR_1095 :区域刹车连续循环模式 +STR_1096 :动力发车(不通过车站) +STR_1097 :动力发车区域刹车模式 +STR_1098 :移动到 {POP16}{STRINGID} 尾端 +STR_1099 :等待乘客 {POP16}{STRINGID} +STR_1100 :等待离站 {POP16}{STRINGID} +STR_1101 :离站 {POP16}{STRINGID} +STR_1102 :以 {VELOCITY} 行驶 +STR_1103 :到达 {POP16}{STRINGID} +STR_1104 :乘客在 {POP16}{STRINGID} 下车 +STR_1105 :以 {VELOCITY} 行驶 +STR_1106 :毁坏中! +STR_1107 :已毁坏! +STR_1108 :以 {VELOCITY} 行驶 +STR_1109 :摇摆中 +STR_1110 :旋转中 +STR_1111 :旋转中 +STR_1112 :运行中 +STR_1113 :放映中 +STR_1114 :旋转中 +STR_1115 :运行中 +STR_1116 :运行中 +STR_1117 :马戏表演中 +STR_1118 :运行中 +STR_1119 :等待锁链拉升中 +STR_1120 :以 {VELOCITY} 行驶 +STR_1121 :停止中 +STR_1122 :等待乘客 +STR_1123 :等待开始 +STR_1124 :开始中 +STR_1125 :运行中 +STR_1126 :停止中 +STR_1127 :卸客中 +STR_1128 :被区域刹车刹停 +STR_1129 :全部车辆使用相同颜色 +STR_1130 :不同{STRINGID}使用不同颜色 +STR_1131 :不同车辆使用不同颜色 +STR_1132 :车辆 {POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1133 :车辆 {POP16}{COMMA16} STR_1134 :{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} {COMMA16} STR_1135 :{STRINGID} {COMMA16} -STR_1136 :{SMALLFONT}{BLACK}Select main colour -STR_1137 :{SMALLFONT}{BLACK}Select additional colour 1 -STR_1138 :{SMALLFONT}{BLACK}Select additional colour 2 -STR_1139 :{SMALLFONT}{BLACK}Select support structure colour -STR_1140 :{SMALLFONT}{BLACK}Select vehicle colour scheme option -STR_1141 :{SMALLFONT}{BLACK}Select which vehicle/train to modify +STR_1136 :{SMALLFONT}{BLACK}选择主要配色 +STR_1137 :{SMALLFONT}{BLACK}选择额外配色 1 +STR_1138 :{SMALLFONT}{BLACK}选择额外配色 2 +STR_1139 :{SMALLFONT}{BLACK}选择支撑框架配色 +STR_1140 :{SMALLFONT}{BLACK}选择车辆配色主题 +STR_1141 :{SMALLFONT}{BLACK}选择需要魔改的车辆/列车 STR_1142 :{MOVE_X}{SMALLFONT}{STRINGID} STR_1143 :»{MOVE_X}{SMALLFONT}{STRINGID} -STR_1144 :Can't build/move entrance for this ride/attraction... -STR_1145 :Can't build/move exit for this ride/attraction... -STR_1146 :Entrance not yet built -STR_1147 :Exit not yet built -STR_1148 :Quarter load -STR_1149 :Half load -STR_1150 :Three-quarter load -STR_1151 :Full load -STR_1152 :Any load -STR_1153 :Height Marks on Ride Tracks设施轨道高度标记 -STR_1154 :Height Marks on Land土地高度标记 -STR_1155 :Height Marks on Paths道路高度标记 +STR_1144 :不能建造/移动这个游乐设施的入口... +STR_1145 :不能建造/移动这个游乐设施的出口... +STR_1146 :尚未建造入口 +STR_1147 :尚未建造出口 +STR_1148 :四分之一载客量 +STR_1149 :二分之一载客量 +STR_1150 :四分之三载客量 +STR_1151 :满载 +STR_1152 :随意载客 +STR_1153 :设施轨道高度标记 +STR_1154 :土地高度标记 +STR_1155 :道路高度标记 STR_1156 :{MOVE_X}{SMALLFONT}{STRINGID} STR_1157 :✓{MOVE_X}{SMALLFONT}{STRINGID} -STR_1158 :Can't remove this... -STR_1159 :{SMALLFONT}{BLACK}Place scenery, gardens, and other accessories -STR_1160 :{SMALLFONT}{BLACK}Create/adjust lakes & water -STR_1161 :Can't position this here... +STR_1158 :不能移除此物... +STR_1159 :{SMALLFONT}{BLACK}放置景观,花园和其他美化物 +STR_1160 :{SMALLFONT}{BLACK}创建/调整湖泊和水塘 +STR_1161 :不能放置于此... STR_1162 :{OUTLINE}{TOPAZ}{STRINGID} -STR_1163 :{STRINGID}{NEWLINE}(Right-Click to Modify) -STR_1164 :{STRINGID}{NEWLINE}(Right-Click to Remove) +STR_1163 :{STRINGID}{NEWLINE}(按右键修改) +STR_1164 :{STRINGID}{NEWLINE}(按右键移除) STR_1165 :{STRINGID} - {STRINGID} {COMMA16} -STR_1166 :Can't lower water level here... -STR_1167 :Can't raise water level here... +STR_1166 :无法降低此处水位... +STR_1167 :无法升高此处水位... STR_1168 :选项 STR_1169 :(无) STR_1170 :{STRING} STR_1171 :{RED}已关闭 - - STR_1172 :{YELLOW}{STRINGID} - - -STR_1173 :{SMALLFONT}{BLACK}Build footpaths and queue lines -STR_1174 :Banner sign in the way -STR_1175 :Can't build this on sloped footpath -STR_1176 :Can't build footpath here... -STR_1177 :Can't remove footpath from here... -STR_1178 :Land slope unsuitable -STR_1179 :Footpath in the way -STR_1180 :Can't build this underwater! -STR_1181 :Footpaths -STR_1182 :Type -STR_1183 :Direction -STR_1184 :Slope -STR_1185 :{SMALLFONT}{BLACK}Direction -STR_1186 :{SMALLFONT}{BLACK}Slope down -STR_1187 :{SMALLFONT}{BLACK}Level -STR_1188 :{SMALLFONT}{BLACK}Slope up -STR_1189 :{SMALLFONT}{BLACK}Construct the selected footpath section -STR_1190 :{SMALLFONT}{BLACK}Remove previous footpath section +STR_1173 :{SMALLFONT}{BLACK}建造道路和队列线 +STR_1174 :横幅挡到了 +STR_1175 :不能在倾斜的小径上建造这个 +STR_1176 :不能在此建造道路... +STR_1177 :不能移除此处道路... +STR_1178 :坡道坡度不合适 +STR_1179 :道路挡到了 +STR_1180 :不能建造在水下! +STR_1181 :道路 +STR_1182 :类型 +STR_1183 :方向 +STR_1184 :坡度 +STR_1185 :{SMALLFONT}{BLACK}方向 +STR_1186 :{SMALLFONT}{BLACK}下坡 +STR_1187 :{SMALLFONT}{BLACK}水平 +STR_1188 :{SMALLFONT}{BLACK}上坡 +STR_1189 :{SMALLFONT}{BLACK}建造选中的道路 +STR_1190 :{SMALLFONT}{BLACK}移除上一段道路 STR_1191 :{BLACK}{STRINGID} STR_1192 :{OUTLINE}{RED}{STRINGID} STR_1193 :{WINDOW_COLOUR_2}{STRINGID} -STR_1194 :Closed -STR_1195 :Test Run -STR_1196 :Open -STR_1197 :Broken Down -STR_1198 :Crashed! -STR_1199 :{COMMA16} person on ride -STR_1200 :{COMMA16} people on ride -STR_1201 :Nobody in queue line -STR_1202 :1 person in queue line -STR_1203 :{COMMA16} people in queue line -STR_1204 :{COMMA16} minute queue time -STR_1205 :{COMMA16} minutes queue time -STR_1206 :{WINDOW_COLOUR_2}Wait for: -STR_1207 :{WINDOW_COLOUR_2}Leave if another train arrives at station -STR_1208 :{WINDOW_COLOUR_2}Leave if another boat arrives at station -STR_1209 :{SMALLFONT}{BLACK}Select whether should wait for passengers before departing -STR_1210 :{SMALLFONT}{BLACK}Select whether should leave if another vehicle arrives at the same station -STR_1211 :{WINDOW_COLOUR_2}Minimum waiting time: -STR_1212 :{WINDOW_COLOUR_2}Maximum waiting time: -STR_1213 :{SMALLFONT}{BLACK}Select minimum length of time to wait before departing -STR_1214 :{SMALLFONT}{BLACK}Select maximum length of time to wait before departing -STR_1215 :{WINDOW_COLOUR_2}Synchronise with adjacent stations -STR_1216 :{SMALLFONT}{BLACK}Select whether to synchronise departure with all adjacent stations (for 'racing') -STR_1217 :{COMMA16} seconds +STR_1194 :已关闭 +STR_1195 :测试运行 +STR_1196 :开启 +STR_1197 :故障了 +STR_1198 :已毁坏! +STR_1199 :{COMMA16}名游客在游乐设施上 +STR_1200 :{COMMA16}名游客在游乐设施上 +STR_1201 :无人在排队 +STR_1202 :1人在排队 +STR_1203 :{COMMA16}人在排队 +STR_1204 :{COMMA16}分钟等候时间 +STR_1205 :{COMMA16}分钟等候时间 +STR_1206 :{WINDOW_COLOUR_2}等待: +STR_1207 :{WINDOW_COLOUR_2}当其他列车进站后就发车 +STR_1208 :{WINDOW_COLOUR_2}当其他船到站后就发车 +STR_1209 :{SMALLFONT}{BLACK}选择发车前是否等待乘客 +STR_1210 :{SMALLFONT}{BLACK}选择当其他车辆入站后,是否发车 +STR_1211 :{WINDOW_COLOUR_2}最短等待时间: +STR_1212 :{WINDOW_COLOUR_2}最长等待时间: +STR_1213 :{SMALLFONT}{BLACK}选择发车前最短等待时长 +STR_1214 :{SMALLFONT}{BLACK}选择发车前最长等待时长 +STR_1215 :{WINDOW_COLOUR_2}与相邻站同步 +STR_1216 :{SMALLFONT}{BLACK}选择是否与所有相邻车站同步发车(为了“赛车”) +STR_1217 :{COMMA16} 秒 STR_1218 :{BLACK}➕ STR_1219 :{BLACK}➖ -STR_1220 :Exit only -STR_1221 :No entrance -STR_1222 :No exit -STR_1223 :{SMALLFONT}{BLACK}Transport rides -STR_1224 :{SMALLFONT}{BLACK}Gentle rides -STR_1225 :{SMALLFONT}{BLACK}Roller coasters -STR_1226 :{SMALLFONT}{BLACK}Thrill rides -STR_1227 :{SMALLFONT}{BLACK}Water rides -STR_1228 :{SMALLFONT}{BLACK}Shops & stalls -STR_1229 :train -STR_1230 :trains -STR_1231 :Train -STR_1232 :Trains -STR_1233 :{COMMA16} train -STR_1234 :{COMMA16} trains -STR_1235 :Train {COMMA16} -STR_1236 :boat -STR_1237 :boats -STR_1238 :Boat -STR_1239 :Boats -STR_1240 :{COMMA16} boat -STR_1241 :{COMMA16} boats -STR_1242 :Boat {COMMA16} -STR_1243 :track -STR_1244 :tracks -STR_1245 :Track -STR_1246 :Tracks -STR_1247 :{COMMA16} track -STR_1248 :{COMMA16} tracks -STR_1249 :Track {COMMA16} -STR_1250 :docking platform -STR_1251 :docking platforms -STR_1252 :Docking platform -STR_1253 :Docking platforms -STR_1254 :{COMMA16} docking platform -STR_1255 :{COMMA16} docking platforms -STR_1256 :Docking platform {COMMA16} -STR_1257 :station -STR_1258 :stations -STR_1259 :Station -STR_1260 :Stations -STR_1261 :{COMMA16} station -STR_1262 :{COMMA16} stations -STR_1263 :Station {COMMA16} -STR_1264 :car -STR_1265 :cars -STR_1266 :Car -STR_1267 :Cars -STR_1268 :{COMMA16} car -STR_1269 :{COMMA16} cars -STR_1270 :Car {COMMA16} -STR_1271 :building -STR_1272 :buildings -STR_1273 :Building -STR_1274 :Buildings -STR_1275 :{COMMA16} building -STR_1276 :{COMMA16} buildings -STR_1277 :Building {COMMA16} -STR_1278 :structure -STR_1279 :structures -STR_1280 :Structure -STR_1281 :Structures -STR_1282 :{COMMA16} structure -STR_1283 :{COMMA16} structures -STR_1284 :Structure {COMMA16} -STR_1285 :ship -STR_1286 :ships -STR_1287 :Ship -STR_1288 :Ships -STR_1289 :{COMMA16} ship -STR_1290 :{COMMA16} ships -STR_1291 :Ship {COMMA16} -STR_1292 :cabin -STR_1293 :cabins -STR_1294 :Cabin -STR_1295 :Cabins -STR_1296 :{COMMA16} cabin -STR_1297 :{COMMA16} cabins -STR_1298 :Cabin {COMMA16} -STR_1299 :wheel -STR_1300 :wheels -STR_1301 :Wheel -STR_1302 :Wheels -STR_1303 :{COMMA16} wheel -STR_1304 :{COMMA16} wheels -STR_1305 :Wheel {COMMA16} -STR_1306 :ring -STR_1307 :rings -STR_1308 :Ring -STR_1309 :Rings -STR_1310 :{COMMA16} ring -STR_1311 :{COMMA16} rings -STR_1312 :Ring {COMMA16} -STR_1313 :player -STR_1314 :players -STR_1315 :Player -STR_1316 :Players -STR_1317 :{COMMA16} player -STR_1318 :{COMMA16} players -STR_1319 :Player {COMMA16} -STR_1320 :course -STR_1321 :courses -STR_1322 :Course -STR_1323 :Courses -STR_1324 :{COMMA16} course -STR_1325 :{COMMA16} courses -STR_1326 :Course {COMMA16} -STR_1327 :{SMALLFONT}{BLACK}Rotate objects by 90° -STR_1328 :Level land required -STR_1329 :{WINDOW_COLOUR_2}Launch speed: -STR_1330 :{SMALLFONT}{BLACK}Maximum speed when leaving station +STR_1220 :出口 +STR_1221 :没有入口 +STR_1222 :没有出口 +STR_1223 :{SMALLFONT}{BLACK}运输类游乐设施 +STR_1224 :{SMALLFONT}{BLACK}温和类游乐设施 +STR_1225 :{SMALLFONT}{BLACK}过山车 +STR_1226 :{SMALLFONT}{BLACK}惊险游乐设施 +STR_1227 :{SMALLFONT}{BLACK}水上游乐设施 +STR_1228 :{SMALLFONT}{BLACK}商店及摊贩 +STR_1229 :列车 +STR_1230 :列车 +STR_1231 :列车 +STR_1232 :列车 +STR_1233 :{COMMA16} 列车 +STR_1234 :{COMMA16} 列车 +STR_1235 :列车 {COMMA16} +STR_1236 :小船 +STR_1237 :小船 +STR_1238 :小船 +STR_1239 :小船 +STR_1240 :{COMMA16} 小船 +STR_1241 :{COMMA16} 小船 +STR_1242 :船 {COMMA16} +STR_1243 :轨道 +STR_1244 :轨道 +STR_1245 :轨道 +STR_1246 :轨道 +STR_1247 :{COMMA16} 轨道 +STR_1248 :{COMMA16} 轨道 +STR_1249 :轨道 {COMMA16} +STR_1250 :码头 +STR_1251 :码头 +STR_1252 :码头 +STR_1253 :码头 +STR_1254 :{COMMA16} 码头 +STR_1255 :{COMMA16} 码头 +STR_1256 :码头 {COMMA16} +STR_1257 :车站 +STR_1258 :车站 +STR_1259 :车站 +STR_1260 :车站 +STR_1261 :{COMMA16} 车站 +STR_1262 :{COMMA16} 车站 +STR_1263 :车站 {COMMA16} +STR_1264 :车辆 +STR_1265 :车辆 +STR_1266 :车辆 +STR_1267 :车辆 +STR_1268 :{COMMA16} 车辆 +STR_1269 :{COMMA16} 车辆 +STR_1270 :车辆 {COMMA16} +STR_1271 :建筑物 +STR_1272 :建筑物 +STR_1273 :建筑物 +STR_1274 :建筑物 +STR_1275 :{COMMA16} 建筑物 +STR_1276 :{COMMA16} 建筑物 +STR_1277 :建筑物 {COMMA16} +STR_1278 :结构 +STR_1279 :结构 +STR_1280 :结构 +STR_1281 :结构 +STR_1282 :{COMMA16} 结构 +STR_1283 :{COMMA16} 结构 +STR_1284 :结构 {COMMA16} +STR_1285 :船 +STR_1286 :船 +STR_1287 :船 +STR_1288 :船 +STR_1289 :{COMMA16} 条船 +STR_1290 :{COMMA16} 条船 +STR_1291 :船 {COMMA16} +STR_1292 :座舱 +STR_1293 :座舱 +STR_1294 :座舱 +STR_1295 :座舱 +STR_1296 :{COMMA16} 个座舱 +STR_1297 :{COMMA16} 个座舱 +STR_1298 :座舱 {COMMA16} +STR_1299 :摩天轮 +STR_1300 :摩天轮 +STR_1301 :摩天轮 +STR_1302 :摩天轮 +STR_1303 :{COMMA16} 个摩天轮 +STR_1304 :{COMMA16} 个摩天轮 +STR_1305 :摩天轮 {COMMA16} +STR_1306 :转轮 +STR_1307 :转轮 +STR_1308 :转轮 +STR_1309 :转轮 +STR_1310 :{COMMA16} 个转轮 +STR_1311 :{COMMA16} 个转轮 +STR_1312 :转轮 {COMMA16} +STR_1313 :玩家 +STR_1314 :玩家 +STR_1315 :玩家 +STR_1316 :玩家 +STR_1317 :{COMMA16} 名玩家 +STR_1318 :{COMMA16} 名玩家 +STR_1319 :玩家 {COMMA16} +STR_1320 :场地 +STR_1321 :场地 +STR_1322 :场地 +STR_1323 :场地 +STR_1324 :{COMMA16} 个场地 +STR_1325 :{COMMA16} 个场地 +STR_1326 :场地 {COMMA16} +STR_1327 :{SMALLFONT}{BLACK}旋转物体 90° +STR_1328 :需要水平地面 +STR_1329 :{WINDOW_COLOUR_2}发车速度: +STR_1330 :{SMALLFONT}{BLACK}离站时最高速度 STR_1331 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VELOCITY} STR_1332 :{VELOCITY} STR_1333 :{STRINGID} - {STRINGID}{POP16} STR_1334 :{STRINGID} - {STRINGID} {COMMA16} -STR_1335 :{STRINGID} - Entrance{POP16}{POP16} -STR_1336 :{STRINGID} - Station {POP16}{COMMA16} Entrance -STR_1337 :{STRINGID} - Exit{POP16}{POP16} -STR_1338 :{STRINGID} - Station {POP16}{COMMA16} Exit -STR_1339 :{BLACK}No test results yet... -STR_1340 :{WINDOW_COLOUR_2}Max. speed: {BLACK}{VELOCITY} -STR_1341 :{WINDOW_COLOUR_2}Ride time: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} +STR_1335 :{STRINGID} - 入口{POP16}{POP16} +STR_1336 :{STRINGID} - 车站 {POP16}{COMMA16} 入口 +STR_1337 :{STRINGID} - 出口{POP16}{POP16} +STR_1338 :{STRINGID} - 车站 {POP16}{COMMA16} 出口 +STR_1339 :{BLACK}暂无测试结果... +STR_1340 :{WINDOW_COLOUR_2}最高速度: {BLACK}{VELOCITY} +STR_1341 :{WINDOW_COLOUR_2}乘坐时间: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1342 :{DURATION} STR_1343 :{DURATION} / -STR_1344 :{WINDOW_COLOUR_2}Ride length: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} +STR_1344 :{WINDOW_COLOUR_2}轨道长度: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1345 :{LENGTH} STR_1346 :{LENGTH} / -STR_1347 :{WINDOW_COLOUR_2}Average speed: {BLACK}{VELOCITY} -STR_1348 :{WINDOW_COLOUR_2}Max. positive vertical G's: {BLACK}{COMMA2DP32}g -STR_1349 :{WINDOW_COLOUR_2}Max. positive vertical G's: {OUTLINE}{RED}{COMMA2DP32}g -STR_1350 :{WINDOW_COLOUR_2}Max. negative vertical G's: {BLACK}{COMMA2DP32}g -STR_1351 :{WINDOW_COLOUR_2}Max. negative vertical G's: {OUTLINE}{RED}{COMMA2DP32}g -STR_1352 :{WINDOW_COLOUR_2}Max. lateral G's: {BLACK}{COMMA2DP32}g -STR_1353 :{WINDOW_COLOUR_2}Max. lateral G's: {OUTLINE}{RED}{COMMA2DP32}g -STR_1354 :{WINDOW_COLOUR_2}Highest drop height: {BLACK}{LENGTH} -STR_1355 :{WINDOW_COLOUR_2}Drops: {BLACK}{COMMA16} -STR_1356 :{WINDOW_COLOUR_2}Inversions: {BLACK}{COMMA16} -STR_1357 :{WINDOW_COLOUR_2}Holes: {BLACK}{COMMA16} -STR_1358 :{WINDOW_COLOUR_2}Total 'air' time: {BLACK}{COMMA2DP32}secs -STR_1359 :{WINDOW_COLOUR_2}Queue time: {BLACK}{COMMA16} minute -STR_1360 :{WINDOW_COLOUR_2}Queue time: {BLACK}{COMMA16} minutes -STR_1361 :Can't change speed... -STR_1362 :Can't change launch speed... -STR_1363 :Too high for supports! -STR_1364 :Supports for track above can't be extended any further! -STR_1365 :In-line Twist (left) -STR_1366 :In-line Twist (right) -STR_1367 :Half Loop -STR_1368 :Half Corkscrew (left) -STR_1369 :Half Corkscrew (right) -STR_1370 :Barrel Roll (left) -STR_1371 :Barrel Roll (right) -STR_1372 :Launched Lift Hill -STR_1373 :Large Half Loop (left) -STR_1374 :Large Half Loop (right) -STR_1375 :Upper Transfer -STR_1376 :Lower Transfer -STR_1377 :Heartline Roll (left) -STR_1378 :Heartline Roll (right) -STR_1379 :Reverser (left) -STR_1380 :Reverser (right) -STR_1381 :Curved Lift Hill (left) -STR_1382 :Curved Lift Hill (right) -STR_1383 :Quarter Loop +STR_1347 :{WINDOW_COLOUR_2}平均速度: {BLACK}{VELOCITY} +STR_1348 :{WINDOW_COLOUR_2}最大正垂直重力: {BLACK}{COMMA2DP32}g +STR_1349 :{WINDOW_COLOUR_2}最大正垂直重力: {OUTLINE}{RED}{COMMA2DP32}g +STR_1350 :{WINDOW_COLOUR_2}最大负垂直重力: {BLACK}{COMMA2DP32}g +STR_1351 :{WINDOW_COLOUR_2}最大负垂直重力: {OUTLINE}{RED}{COMMA2DP32}g +STR_1352 :{WINDOW_COLOUR_2}最大横向重力: {BLACK}{COMMA2DP32}g +STR_1353 :{WINDOW_COLOUR_2}最大横向重力: {OUTLINE}{RED}{COMMA2DP32}g +STR_1354 :{WINDOW_COLOUR_2}最高下落高度: {BLACK}{LENGTH} +STR_1355 :{WINDOW_COLOUR_2}下落次数: {BLACK}{COMMA16} +STR_1356 :{WINDOW_COLOUR_2}反转次数: {BLACK}{COMMA16} +STR_1357 :{WINDOW_COLOUR_2}杆洞次数: {BLACK}{COMMA16} +STR_1358 :{WINDOW_COLOUR_2}总 '悬空' 时间: {BLACK}{COMMA2DP32}secs +STR_1359 :{WINDOW_COLOUR_2}等待时间: {BLACK}{COMMA16} minute +STR_1360 :{WINDOW_COLOUR_2}等待时间: {BLACK}{COMMA16} minutes +STR_1361 :不能改变速度... +STR_1362 :不能改变发车速度... +STR_1363 :高度过高无法支撑! +STR_1364 :无法再扩展轨道支撑! +STR_1365 :中心线翻滚 (向左转) +STR_1366 :中心线翻滚 (向右转) +STR_1367 :半环 +STR_1368 :半螺旋 (向左转) +STR_1369 :半螺旋 (向右转) +STR_1370 :油桶滚 (向左转) +STR_1371 :油桶滚 (向右转) +STR_1372 :加速提升坡 +STR_1373 :巨型半环 (向左转) +STR_1374 :巨型半环 (向右转) +STR_1375 :向上传输 +STR_1376 :向下传输 +STR_1377 :心形线滚 (向左转) +STR_1378 :心形线滚 (向右转) +STR_1379 :逆向(向左转) +STR_1380 :逆向 (向右转) +STR_1381 :曲面提升坡 (向左转) +STR_1382 :曲面提升坡 (向右转) +STR_1383 :四分之一回环 STR_1384 :{YELLOW}{STRINGID} -STR_1385 :{SMALLFONT}{BLACK}Other track configurations -STR_1386 :Special... -STR_1387 :Can't change land type... +STR_1385 :{SMALLFONT}{BLACK}其他轨道选项 +STR_1386 :特殊... +STR_1387 :无法改变土地类型... STR_1388 :{OUTLINE}{GREEN}+ {CURRENCY} STR_1389 :{OUTLINE}{RED}- {CURRENCY} STR_1390 :{CURRENCY2DP} STR_1391 :{RED}{CURRENCY2DP} -STR_1392 :{SMALLFONT}{BLACK}View of ride/attraction -STR_1393 :{SMALLFONT}{BLACK}Vehicle details and options -STR_1394 :{SMALLFONT}{BLACK}Operating options -STR_1395 :{SMALLFONT}{BLACK}Maintenance options -STR_1396 :{SMALLFONT}{BLACK}Colour scheme options -STR_1397 :{SMALLFONT}{BLACK}Sound & music options -STR_1398 :{SMALLFONT}{BLACK}Measurements and test data -STR_1399 :{SMALLFONT}{BLACK}Graphs -STR_1400 :Entrance -STR_1401 :Exit -STR_1402 :{SMALLFONT}{BLACK}Build or move entrance to ride/attraction -STR_1403 :{SMALLFONT}{BLACK}Build or move exit from ride/attraction -STR_1404 :{SMALLFONT}{BLACK}Rotate 90° -STR_1405 :{SMALLFONT}{BLACK}Mirror image -STR_1406 :{SMALLFONT}{BLACK}Toggle scenery on/off (if available for this design) -STR_1407 :{WINDOW_COLOUR_2}Build this... -STR_1408 :{WINDOW_COLOUR_2}Cost: {BLACK}{CURRENCY} -STR_1409 :Entry/Exit Platform -STR_1410 :Vertical Tower -STR_1411 :{STRINGID} in the way -STR_1412 :{WINDOW_COLOUR_3}Data logging not available for this type of ride -STR_1413 :{WINDOW_COLOUR_3}Data logging will start when next {STRINGID} leaves {STRINGID} +STR_1392 :{SMALLFONT}{BLACK}观看游乐设施/ 店铺 +STR_1393 :{SMALLFONT}{BLACK}车辆详细与选项 +STR_1394 :{SMALLFONT}{BLACK}运行选项 +STR_1395 :{SMALLFONT}{BLACK}维修选项 +STR_1396 :{SMALLFONT}{BLACK}配色选项 +STR_1397 :{SMALLFONT}{BLACK}声音与音乐选项 +STR_1398 :{SMALLFONT}{BLACK}统计与测试数据 +STR_1399 :{SMALLFONT}{BLACK}图表 +STR_1400 :入口 +STR_1401 :出口 +STR_1402 :{SMALLFONT}{BLACK}建造或移动游乐设施入口 +STR_1403 :{SMALLFONT}{BLACK}建造或移动游乐设施出口 +STR_1404 :{SMALLFONT}{BLACK}旋转 90° +STR_1405 :{SMALLFONT}{BLACK}镜像 +STR_1406 :{SMALLFONT}{BLACK}启用/弃用 景物 (如果设计附带景物) +STR_1407 :{WINDOW_COLOUR_2}建造此... +STR_1408 :{WINDOW_COLOUR_2}费用: {BLACK}{CURRENCY} +STR_1409 :出/入 口 +STR_1410 :垂直高塔 +STR_1411 :{STRINGID}挡道 +STR_1412 :{WINDOW_COLOUR_3}无该类型游乐设施数据记录 +STR_1413 :{WINDOW_COLOUR_3}数据将于下一个 {STRINGID} 离开 {STRINGID}后记录 STR_1414 :{SMALLFONT}{BLACK}{DURATION} -STR_1415 :{WINDOW_COLOUR_2}Velocity -STR_1416 :{WINDOW_COLOUR_2}Altitude -STR_1417 :{WINDOW_COLOUR_2}Vert.G's -STR_1418 :{WINDOW_COLOUR_2}Lat.G's +STR_1415 :{WINDOW_COLOUR_2}速度 +STR_1416 :{WINDOW_COLOUR_2}高度 +STR_1417 :{WINDOW_COLOUR_2}垂直重力 +STR_1418 :{WINDOW_COLOUR_2}水平重力 STR_1419 :{SMALLFONT}{BLACK}{VELOCITY} STR_1420 :{SMALLFONT}{BLACK}{LENGTH} STR_1421 :{SMALLFONT}{BLACK}{COMMA16}g -STR_1422 :{SMALLFONT}{BLACK}Logging data from {POP16}{STRINGID} -STR_1423 :{SMALLFONT}{BLACK}Queue line path -STR_1424 :{SMALLFONT}{BLACK}Footpath -STR_1425 :Footpath -STR_1426 :Queue Line -STR_1427 :{WINDOW_COLOUR_2}Customers: {BLACK}{COMMA32} per hour -STR_1428 :{WINDOW_COLOUR_2}Admission price: +STR_1422 :{SMALLFONT}{BLACK}来自 {POP16}{STRINGID}的记录数据 +STR_1423 :{SMALLFONT}{BLACK}队列线路 +STR_1424 :{SMALLFONT}{BLACK}道路 +STR_1425 :道路 +STR_1426 :队列线 +STR_1427 :{WINDOW_COLOUR_2}乘客: {BLACK}{COMMA32} /小时 +STR_1428 :{WINDOW_COLOUR_2}门票价格: STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} -STR_1430 :Free -STR_1431 :Walking -STR_1432 :Heading for {STRINGID} -STR_1433 :Queuing for {STRINGID} -STR_1434 :Drowning -STR_1435 :On {STRINGID} -STR_1436 :In {STRINGID} -STR_1437 :At {STRINGID} -STR_1438 :Sitting -STR_1439 :(select location) -STR_1440 :修剪草皮中 -STR_1441 :Sweeping footpath -STR_1442 :Emptying litter bin -STR_1443 :Watering gardens -STR_1444 :Watching {STRINGID} -STR_1445 :Watching construction of {STRINGID} -STR_1446 :Looking at scenery -STR_1447 :Leaving the park -STR_1448 :Watching new ride being constructed +STR_1430 :免费 +STR_1431 :行走中 +STR_1432 :前往{STRINGID} +STR_1433 :等待{STRINGID}中 +STR_1434 :溺水 +STR_1435 :在{STRINGID}上 +STR_1436 :在{STRINGID}中 +STR_1437 :在{STRINGID} +STR_1438 :坐下 +STR_1439 :(选择位置) +STR_1440 :正在修剪草皮 +STR_1441 :正在清扫道路 +STR_1442 :正在清空垃圾桶 +STR_1443 :正在灌溉花园 +STR_1444 :正在观看{STRINGID} +STR_1445 :正在观看{STRINGID}的建造 +STR_1446 :正在欣赏景物 +STR_1447 :正在离开游乐园 +STR_1448 :正在观看新游乐设施的建造过程 STR_1449 :{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1450 :{INLINE_SPRITE}{09}{20}{00}{00}{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1451 :{STRINGID}{NEWLINE}({STRINGID}) -STR_1452 :Guest's name -STR_1453 :Enter name for this guest: -STR_1454 :Can't name guest... -STR_1455 :Invalid name for guest -STR_1456 :{WINDOW_COLOUR_2}Cash spent: {BLACK}{CURRENCY2DP} -STR_1457 :{WINDOW_COLOUR_2}Cash in pocket: {BLACK}{CURRENCY2DP} -STR_1458 :{WINDOW_COLOUR_2}Time in park: {BLACK}{REALTIME} +STR_1452 :游客命名 +STR_1453 :请输入这名游客的姓名: +STR_1454 :不能命名该游客... +STR_1455 :无效的游客名字 +STR_1456 :{WINDOW_COLOUR_2}花费金额: {BLACK}{CURRENCY2DP} +STR_1457 :{WINDOW_COLOUR_2}钱包中金额: {BLACK}{CURRENCY2DP} +STR_1458 :{WINDOW_COLOUR_2}逗留时间: {BLACK}{REALTIME} STR_1459 :Track style -STR_1460 :{SMALLFONT}{BLACK}'U' shaped open track -STR_1461 :{SMALLFONT}{BLACK}'O' shaped enclosed track -STR_1462 :Too steep for lift hill +STR_1460 :{SMALLFONT}{BLACK}U型开放式轨道 +STR_1461 :{SMALLFONT}{BLACK}O型封闭式轨道 +STR_1462 :提升坡太陡了 STR_1463 :游客 -STR_1464 :Helix up (small) -STR_1465 :Helix up (large) -STR_1466 :Helix down (small) -STR_1467 :Helix down (large) +STR_1464 :螺旋向上 (小) +STR_1465 :螺旋向上 (大) +STR_1466 :螺旋向下 (小) +STR_1467 :螺旋向下 (大) STR_1468 :职员 -STR_1469 :Ride must start and end with stations -STR_1470 :Station not long enough -STR_1471 :{WINDOW_COLOUR_2}Speed: -STR_1472 :{SMALLFONT}{BLACK}Speed of this ride -STR_1473 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1474 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}Not yet available -STR_1475 :{WINDOW_COLOUR_2}Intensity rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1476 :{WINDOW_COLOUR_2}Intensity rating: {BLACK}Not yet available -STR_1477 :{WINDOW_COLOUR_2}Intensity rating: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) -STR_1478 :{WINDOW_COLOUR_2}Nausea rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1479 :{WINDOW_COLOUR_2}Nausea rating: {BLACK}Not yet available -STR_1480 :{SMALLFONT}“I can't afford {STRINGID}” -STR_1481 :{SMALLFONT}“I've spent all my money” +STR_1469 :设施必须要开始和结束于车站 +STR_1470 :车站长度过短 +STR_1471 :{WINDOW_COLOUR_2}速度: +STR_1472 :{SMALLFONT}{BLACK}此车速度 +STR_1473 :{WINDOW_COLOUR_2}兴奋度: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1474 :{WINDOW_COLOUR_2}兴奋度: {BLACK}暂无 +STR_1475 :{WINDOW_COLOUR_2}刺激度: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1476 :{WINDOW_COLOUR_2}刺激度: {BLACK}暂无 +STR_1477 :{WINDOW_COLOUR_2}刺激度: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) +STR_1478 :{WINDOW_COLOUR_2}恶心度: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1479 :{WINDOW_COLOUR_2}恶心度: {BLACK}暂无 +STR_1480 :{SMALLFONT}“我负担不起{STRINGID}” +STR_1481 :{SMALLFONT}“这个月又要吃土了” STR_1482 :{SMALLFONT}“我感到不舒服” -STR_1483 :{SMALLFONT}“我感到非常不舒服” -STR_1484 :{SMALLFONT}“I want to go on something more thrilling than {STRINGID}” -STR_1485 :{SMALLFONT}“{STRINGID} looks too intense for me” -STR_1486 :{SMALLFONT}“I haven't finished my {STRINGID} yet” -STR_1487 :{SMALLFONT}“Just looking at {STRINGID} makes me feel sick” -STR_1488 :{SMALLFONT}“I'm not paying that much to go on {STRINGID}” +STR_1483 :{SMALLFONT}“香菇蓝瘦” +STR_1484 :{SMALLFONT}“我想试试比{STRINGID}更刺激的” +STR_1485 :{SMALLFONT}“对我来说,{STRINGID}看起来太过刺激了” +STR_1486 :{SMALLFONT}“等等,我还没试过{STRINGID}” +STR_1487 :{SMALLFONT}“看看{STRINGID}就让我感到不适” +STR_1488 :{SMALLFONT}“{STRINGID}太贵了吧,这个乐园真坑爹” STR_1489 :{SMALLFONT}“我想回家” -STR_1490 :{SMALLFONT}“{STRINGID} is really good value” -STR_1491 :{SMALLFONT}“I've already got {STRINGID}” -STR_1492 :{SMALLFONT}“I can't afford {STRINGID}” -STR_1493 :{SMALLFONT}“I'm not hungry” -STR_1494 :{SMALLFONT}“I'm not thirsty” -STR_1495 :{SMALLFONT}“Help! I'm drowning!” -STR_1496 :{SMALLFONT}“I'm lost!” -STR_1497 :{SMALLFONT}“{STRINGID} was great” -STR_1498 :{SMALLFONT}“I've been queuing for {STRINGID} for ages” +STR_1490 :{SMALLFONT}“{STRINGID}真是超值”” +STR_1491 :{SMALLFONT}“我已经有{STRINGID}了” +STR_1492 :{SMALLFONT}“我负担不起{STRINGID}” +STR_1493 :{SMALLFONT}“我不饿” +STR_1494 :{SMALLFONT}“我不渴” +STR_1495 :{SMALLFONT}“救命! 我溺水了!” +STR_1496 :{SMALLFONT}“我迷路了!” +STR_1497 :{SMALLFONT}“{STRINGID}棒棒哒” +STR_1498 :{SMALLFONT}“我等候在这{STRINGID}老久了,啥时才轮到我啊 ” STR_1499 :{SMALLFONT}“我累了” STR_1500 :{SMALLFONT}“我饿了” STR_1501 :{SMALLFONT}“我渴了” STR_1502 :{SMALLFONT}“我需要去厕所” STR_1503 :{SMALLFONT}“我找不到 {STRINGID}” -STR_1504 :{SMALLFONT}“我没有那么多钱去 {STRINGID}” -STR_1505 :{SMALLFONT}“我不去 {STRINGID} 因为在下雨” -STR_1506 :{SMALLFONT}“这里的垃圾真的很糟糕” -STR_1507 :{SMALLFONT}“我找不到乐园的出口” +STR_1504 :{SMALLFONT}“我才没有那么多钱去 {STRINGID}” +STR_1505 :{SMALLFONT}“我不想去 {STRINGID} 因为那里在下雨” +STR_1506 :{SMALLFONT}“这里是垃圾场吗?” +STR_1507 :{SMALLFONT}“哇塞!这个乐园的出口在哪?” STR_1508 :{SMALLFONT}“我想下车 {STRINGID}” STR_1509 :{SMALLFONT}“我想离开 {STRINGID}” -STR_1510 :{SMALLFONT}“我不想去{STRINGID} - 它不安全” -STR_1511 :{SMALLFONT}“这条路是令人厌恶的” -STR_1512 :{SMALLFONT}“这里太拥挤了” +STR_1510 :{SMALLFONT}“我不想去{STRINGID},感觉它随时都会出问题” +STR_1511 :{SMALLFONT}“这路有点恶心啊!” +STR_1512 :{SMALLFONT}“这里怎么这么挤啊!” STR_1513 :{SMALLFONT}“这里的损坏是非常糟糕的” STR_1514 :{SMALLFONT}“壮丽的景色!” STR_1515 :{SMALLFONT}“这个公园真的很干净” STR_1516 :{SMALLFONT}“跳跃喷泉太好了” STR_1517 :{SMALLFONT}“这里的音乐很好” -STR_1518 :{SMALLFONT}“这个{STRINGID}的热气球真是便宜” -STR_1519 :{SMALLFONT}“这个{STRINGID}的可爱的玩具真是便宜” -STR_1520 :{SMALLFONT}“这个{STRINGID}的乐园地图真是便宜” -STR_1521 :{SMALLFONT}“这个{STRINGID}的在乘坐时的照片真是便宜” -STR_1522 :{SMALLFONT}“这个{STRINGID}的伞真是便宜” -STR_1523 :{SMALLFONT}“这个{STRINGID}的饮料真是便宜” -STR_1524 :{SMALLFONT}“这个{STRINGID}的汉堡真是便宜” -STR_1525 :{SMALLFONT}“这个{STRINGID}的薯条真是便宜” -STR_1526 :{SMALLFONT}“这个{STRINGID}的冰激凌真是便宜” -STR_1527 :{SMALLFONT}“这个{STRINGID}的棉花糖真是便宜” +STR_1518 :{SMALLFONT}“这个{STRINGID}的气球好便宜” +STR_1519 :{SMALLFONT}“这个{STRINGID}的毛绒公仔好便宜” +STR_1520 :{SMALLFONT}“这个{STRINGID}的乐园地图好便宜” +STR_1521 :{SMALLFONT}“这个{STRINGID}的即时照片好便宜” +STR_1522 :{SMALLFONT}“这个{STRINGID}的伞好便宜” +STR_1523 :{SMALLFONT}“这个{STRINGID}的饮料好便宜” +STR_1524 :{SMALLFONT}“这个{STRINGID}的汉堡好便宜” +STR_1525 :{SMALLFONT}“这个{STRINGID}的薯条好便宜” +STR_1526 :{SMALLFONT}“这个{STRINGID}的冰激好是便宜” +STR_1527 :{SMALLFONT}“这个{STRINGID}的棉花糖好便宜” STR_1528 : STR_1529 : STR_1530 : -STR_1531 :{SMALLFONT}“这个{STRINGID}的披萨真是便宜” +STR_1531 :{SMALLFONT}“这个{STRINGID}的披萨好便宜” STR_1532 : -STR_1533 :{SMALLFONT}“这个{STRINGID}的爆米花真是便宜” -STR_1534 :{SMALLFONT}“这个{STRINGID}的热狗真是便宜” -STR_1535 :{SMALLFONT}“这个{STRINGID}的触手真是便宜” -STR_1536 :{SMALLFONT}“这个{STRINGID}的帽子真是便宜” -STR_1537 :{SMALLFONT}“这个{STRINGID}的太妃糖苹果真是便宜” -STR_1538 :{SMALLFONT}“这个{STRINGID}的T恤真是便宜” -STR_1539 :{SMALLFONT}“这个{STRINGID}的甜甜圈真是便宜” -STR_1540 :{SMALLFONT}“这个{STRINGID}的咖啡真是便宜” +STR_1533 :{SMALLFONT}“这个{STRINGID}的爆米花好便宜” +STR_1534 :{SMALLFONT}“这个{STRINGID}的热狗好便宜” +STR_1535 :{SMALLFONT}“这个{STRINGID}的触手好便宜” +STR_1536 :{SMALLFONT}“这个{STRINGID}的帽子好便宜” +STR_1537 :{SMALLFONT}“这个{STRINGID}的太妃糖苹果好便宜” +STR_1538 :{SMALLFONT}“这个{STRINGID}的T恤好便宜” +STR_1539 :{SMALLFONT}“这个{STRINGID}的甜甜圈好便宜” +STR_1540 :{SMALLFONT}“这个{STRINGID}的咖啡好便宜” STR_1541 : -STR_1542 :{SMALLFONT}“这个{STRINGID}的炸鸡真是便宜” -STR_1543 :{SMALLFONT}“这个{STRINGID}的柠檬水真是便宜” +STR_1542 :{SMALLFONT}“这个{STRINGID}的炸鸡好便宜” +STR_1543 :{SMALLFONT}“这个{STRINGID}的柠檬水好便宜” STR_1544 : STR_1545 : STR_1546 : @@ -938,20 +938,20 @@ STR_1548 : STR_1549 : STR_1550 :{SMALLFONT}“哇!” STR_1551 :{SMALLFONT}“我有种奇怪的感觉, 像是有人在监视我” -STR_1552 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一个气球” -STR_1553 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一只毛绒公仔” -STR_1554 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一份游乐园地图” -STR_1555 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一张即时照片” -STR_1556 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一把雨伞” -STR_1557 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一杯饮料” -STR_1558 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一个汉堡” -STR_1559 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一份薯条” -STR_1560 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一个冰激淋” -STR_1561 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一球棉花糖” +STR_1552 :{SMALLFONT}“{STRINGID}的气球里充的是仙气吧,怎么这么贵” +STR_1553 :{SMALLFONT}“我相信{STRINGID}的毛绒公仔里面塞的不是棉花,是钱” +STR_1554 :{SMALLFONT}“{STRINGID}的游乐园地图是都精确,居然卖的这么贵” +STR_1555 :{SMALLFONT}“都什么年代了,{STRINGID}的即时照片还这么贵” +STR_1556 :{SMALLFONT}“我宁可淋雨,也不会买{STRINGID}的天价雨伞” +STR_1557 :{SMALLFONT}“{STRINGID}的饮料,可真是滴水寸金” +STR_1558 :{SMALLFONT}“{STRINGID}的汉堡比上海迪斯尼的包子还贵” +STR_1559 :{SMALLFONT}“{STRINGID}的薯条使用什么土豆做的?怎么这么贵” +STR_1560 :{SMALLFONT}“{STRINGID}的冰淇淋贵的有点离谱” +STR_1561 :{SMALLFONT}“{STRINGID}的棉花糖是真滴贵” STR_1562 : STR_1563 : STR_1564 : -STR_1565 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一份披萨” +STR_1565 :{SMALLFONT}“{STRINGID}的披萨真的贵” STR_1566 : STR_1567 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一份爆米花” STR_1568 :{SMALLFONT}“我不会花那么多钱去{STRINGID}购买一个热狗” @@ -990,7 +990,7 @@ STR_1600 :{SMALLFONT}“这份从{STRINGID}购买的曲奇饼干真是超值 STR_1601 : STR_1602 : STR_1603 : -STR_1604 :{SMALLFONT}“这条从{STRINGID}购买的烤香肠真是超值” +STR_1604 :{SMALLFONT}“这根从{STRINGID}购买的烤香肠真是超值” STR_1605 : STR_1606 : STR_1607 : @@ -1068,16 +1068,16 @@ STR_1679 :向上盘旋 (向左) STR_1680 :向上盘旋 (向右) STR_1681 :向下盘旋 (向左) STR_1682 :向下盘旋 (向右) -STR_1683 :Base size 2 x 2 -STR_1684 :Base size 4 x 4 -STR_1685 :Base size 2 x 4 -STR_1686 :Base size 5 x 1 -STR_1687 :Water splash -STR_1688 :Base size 4 x 1 -STR_1689 :Block brakes +STR_1683 :2 x 2地基 +STR_1684 :4 x 4地基 +STR_1685 :2 x 4地基 +STR_1686 :5 x 1地基 +STR_1687 :水溅 +STR_1688 :4 x 1地基 +STR_1689 :刹车装置 STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID} -STR_1691 :{WINDOW_COLOUR_2} Cost: {BLACK}{CURRENCY} -STR_1692 :{WINDOW_COLOUR_2} Cost: {BLACK}from {CURRENCY} +STR_1691 :{WINDOW_COLOUR_2} 费用: {BLACK}{CURRENCY} +STR_1692 :{WINDOW_COLOUR_2} 费用: {BLACK}from {CURRENCY} STR_1693 :{SMALLFONT}{BLACK}游客 STR_1694 :{SMALLFONT}{BLACK}职员 STR_1695 :{SMALLFONT}{BLACK}收入和支出 @@ -1090,50 +1090,50 @@ STR_1701 :雇佣新的机械师 STR_1702 :雇佣新的安保人员 STR_1703 :雇佣新的表演人员 STR_1704 :不能雇佣新职员... -STR_1705 :{SMALLFONT}{BLACK}Sack this staff member -STR_1706 :{SMALLFONT}{BLACK}Move this person to a new location -STR_1707 :Too many staff in game -STR_1708 :{SMALLFONT}{BLACK}Set patrol area for this staff member -STR_1709 :Sack staff -STR_1710 :Yes -STR_1711 :{WINDOW_COLOUR_1}Are you sure you want to sack {STRINGID}? -STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Sweep footpaths -STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Water gardens -STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Empty litter bins -STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}Mow grass -STR_1716 :Invalid name for park -STR_1717 :Can't rename park... -STR_1718 :Park Name -STR_1719 :Enter name for park: -STR_1720 :{SMALLFONT}{BLACK}Name park +STR_1705 :{SMALLFONT}{BLACK}解雇该员工 +STR_1706 :{SMALLFONT}{BLACK}移动该人物到新的位置 +STR_1707 :游戏里员工太多了 +STR_1708 :{SMALLFONT}{BLACK}为该员工设置巡逻区域 +STR_1709 :解雇员工 +STR_1710 :确认 +STR_1711 :{WINDOW_COLOUR_1}你确定解雇{STRINGID}? +STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}清扫道路 +STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}灌溉花园 +STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}清空垃圾桶 +STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}修剪草地 +STR_1716 :无效的游乐园名称 +STR_1717 :不能重命名乐园... +STR_1718 :乐园命名 +STR_1719 :请输入乐园的名称: +STR_1720 :{SMALLFONT}{BLACK}命名乐园 STR_1721 :游乐园已关闭 STR_1722 :游乐园开放中 -STR_1723 :Can't open park... -STR_1724 :Can't close park... -STR_1725 :Can't buy land... -STR_1726 :Land not for sale! -STR_1727 :Construction rights not for sale! -STR_1728 :Can't buy construction rights here... -STR_1729 :Land not owned by park! -STR_1730 :{RED}Closed - - +STR_1723 :不能开放乐园... +STR_1724 :不能关闭乐园... +STR_1725 :不能购买地块... +STR_1726 :地块不供购买! +STR_1727 :建筑权不供购买! +STR_1728 :不能在此购买建权... +STR_1729 :非乐园所属地块! +STR_1730 :{RED}已关闭 - - STR_1731 :{WHITE}{STRINGID} - - -STR_1732 :Build -STR_1733 :Mode -STR_1734 :{WINDOW_COLOUR_2}Number of laps: -STR_1735 :{SMALLFONT}{BLACK}Number of laps of circuit +STR_1732 :建造 +STR_1733 :模式 +STR_1734 :{WINDOW_COLOUR_2}圈数: +STR_1735 :{SMALLFONT}{BLACK}每次循环的圈数 STR_1736 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1738 :Can't change number of laps... -STR_1739 :Race won by guest {INT32} -STR_1740 :Race won by {STRINGID} -STR_1741 :Not yet constructed ! -STR_1742 :{WINDOW_COLOUR_2}Max. people on ride: -STR_1743 :{SMALLFONT}{BLACK}Maximum number of people allowed on this ride at one time +STR_1738 :不能更改圈数... +STR_1739 :游客{INT32}赢得本比赛 +STR_1740 :{STRINGID}赢得本比赛 +STR_1741 :尚未建造 ! +STR_1742 :{WINDOW_COLOUR_2}设施最大载客量: +STR_1743 :{SMALLFONT}{BLACK}该游乐设施同时最多可以乘坐的乘客数量、 STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1746 :Can't change this... -STR_1747 :{WINDOW_COLOUR_2}Time limit: -STR_1748 :{SMALLFONT}{BLACK}Time limit for ride +STR_1746 :不能更改... +STR_1747 :{WINDOW_COLOUR_2}时间限制: +STR_1748 :{SMALLFONT}{BLACK}此游乐设施的游玩时间限制 STR_1749 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{DURATION} -STR_1751 :Can't change time limit for ride... +STR_1751 :不能更改此游乐设施的游玩时间限制... STR_1752 :{SMALLFONT}{BLACK}Show list of individual guests in park STR_1753 :{SMALLFONT}{BLACK}Show summarised list of guests in park STR_1754 :{BLACK}{COMMA16}名游客 @@ -1142,17 +1142,17 @@ STR_1756 :{WINDOW_COLOUR_2}门票价格: STR_1757 :{WINDOW_COLOUR_2}可靠性: {MOVE_X}{255}{BLACK}{COMMA16}% STR_1758 :{SMALLFONT}{BLACK}建造模式 STR_1759 :{SMALLFONT}{BLACK}移动模式 -STR_1760 :{SMALLFONT}{BLACK}Fill-in mode -STR_1761 :{SMALLFONT}{BLACK}Build maze in this direction -STR_1762 :Waterfalls -STR_1763 :Rapids -STR_1764 :Log Bumps -STR_1765 :On-ride photo section -STR_1766 :Reverser turntable -STR_1767 :Spinning tunnel -STR_1768 :Can't change number of swings... -STR_1769 :{WINDOW_COLOUR_2}Number of swings: -STR_1770 :{SMALLFONT}{BLACK}Number of complete swings +STR_1760 :{SMALLFONT}{BLACK}填补模式 +STR_1761 :{SMALLFONT}{BLACK}以此方向建造迷宫 +STR_1762 :瀑布 +STR_1763 :急流 +STR_1764 :漩涡 +STR_1765 :即时拍照区域 +STR_1766 :反向转盘 +STR_1767 :旋转隧道 +STR_1768 :不能改变摇摆次数... +STR_1769 :{WINDOW_COLOUR_2}摇摆次数: +STR_1770 :{SMALLFONT}{BLACK}完全摇摆次数 STR_1771 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_1773 :每个游乐设施只能建造一个照相区域 STR_1774 :每个游乐设施只能建造一个牵引轨道 @@ -1225,8 +1225,8 @@ STR_1843 :{COMMA16}游客最喜爱的游乐设施 STR_1844 :{SMALLFONT}{BLACK}选择要在游乐设施/店面列表中显示的信息类别 STR_1845 :{MONTHYEAR} STR_1846 :{COMMA16}游客 -STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16} guests -STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16} guests +STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16}游客 +STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16}游客 STR_1849 :{WINDOW_COLOUR_2}播放音乐 STR_1850 :{SMALLFONT}{BLACK}选择此游乐设施是否播放音乐 STR_1851 :{WINDOW_COLOUR_2}运行成本: {BLACK}每小时{CURRENCY2DP} @@ -1237,24 +1237,24 @@ STR_1855 :{WINDOW_COLOUR_2}建造年份: {BLACK}{COMMA16}年前 STR_1856 :{WINDOW_COLOUR_2}每件产品售出的利润: {BLACK}{CURRENCY2DP} STR_1857 :{WINDOW_COLOUR_2}每件产品售出的亏损: {BLACK}{CURRENCY2DP} STR_1858 :{WINDOW_COLOUR_2}成本: {BLACK}每个月{CURRENCY2DP} -STR_1859 :位清洁工 -STR_1860 :位机械师 -STR_1861 :位警卫 -STR_1862 :位演员 -STR_1863 :位清洁工 -STR_1864 :位机械师 -STR_1865 :位警卫 -STR_1866 :位演员 +STR_1859 :位环保工人 +STR_1860 :位维修人员 +STR_1861 :位安保警卫 +STR_1862 :位表演人员 +STR_1863 :位环保工人 +STR_1864 :位维修人员 +STR_1865 :位安保警卫 +STR_1866 :位表演人员 STR_1867 :{BLACK}{COMMA16} {STRINGID} STR_1868 :不能改变旋转次数... STR_1869 :{WINDOW_COLOUR_2}旋转次数: STR_1870 :{SMALLFONT}{BLACK}完整旋转次数 STR_1871 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1873 :{WINDOW_COLOUR_2}Income: {BLACK}{CURRENCY2DP} per hour -STR_1874 :{WINDOW_COLOUR_2}Profit: {BLACK}{CURRENCY2DP} per hour +STR_1873 :{WINDOW_COLOUR_2}收入: {BLACK}{CURRENCY2DP}/时 +STR_1874 :{WINDOW_COLOUR_2}盈利: {BLACK}{CURRENCY2DP}/时 STR_1875 :{BLACK} {SPRITE}{BLACK} {STRINGID} -STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}Inspect Rides -STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}Fix Rides +STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}检查游乐设施 +STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}维修游乐设施 STR_1878 :{WINDOW_COLOUR_2}检查时间间隔: STR_1879 :每10分钟 STR_1880 :每20分钟 @@ -1263,11 +1263,11 @@ STR_1882 :每45分钟 STR_1883 :每小时 STR_1884 :每2小时 STR_1885 :从不 -STR_1886 :Inspecting {STRINGID} +STR_1886 :检查 {STRINGID} STR_1887 :{WINDOW_COLOUR_2}上次检查时间: {BLACK}{COMMA16}分钟前 STR_1888 :{WINDOW_COLOUR_2}上次检查时间: {BLACK}大于4小时 STR_1889 :{WINDOW_COLOUR_2}故障度: {MOVE_X}{255}{BLACK}{COMMA16}% -STR_1890 :{SMALLFONT}{BLACK}选择机械师检查此游乐设施的时间间隔 +STR_1890 :{SMALLFONT}{BLACK}选择维修人员检查此游乐设施的时间间隔 STR_1891 :在乐园里暂未有{STRINGID}! # The following two strings were used to display an error when the disc was missing. # This has been replaced in OpenRCT2. @@ -1288,12 +1288,12 @@ STR_1907 :{WINDOW_COLOUR_2}员工薪金 STR_1908 :{WINDOW_COLOUR_2}营销费用 STR_1909 :{WINDOW_COLOUR_2}研发费用 STR_1910 :{WINDOW_COLOUR_2}贷款利息 -STR_1911 :{BLACK} at {COMMA16}% per year +STR_1911 :{BLACK} 每年{COMMA16}% STR_1912 :{MONTH} STR_1913 :{BLACK}+{CURRENCY2DP} STR_1914 :{BLACK}{CURRENCY2DP} STR_1915 :{RED}{CURRENCY2DP} -STR_1916 :{WINDOW_COLOUR_2}Loan: +STR_1916 :{WINDOW_COLOUR_2}贷款: STR_1917 :{POP16}{POP16}{POP16}{CURRENCY} STR_1918 :不能再借贷更多钱! STR_1919 :没有足够的现金! @@ -1378,7 +1378,7 @@ STR_1998 :空罐子 STR_1999 :垃圾 STR_2000 :空汉堡包装盒 STR_2001 :披萨 -STR_2002 :Voucher +STR_2002 :优惠券 STR_2003 :爆米花 STR_2004 :热狗 STR_2005 :触手 @@ -1406,7 +1406,7 @@ STR_2026 :空罐子 STR_2027 :垃圾 STR_2028 :空汉堡包装盒 STR_2029 :披萨 -STR_2030 :Voucher +STR_2030 :优惠券 STR_2031 :爆米花 STR_2032 :热狗 STR_2033 :触手 @@ -1579,7 +1579,7 @@ STR_2214 :游戏暂停时无法建造任何物体! STR_2215 :{STRINGID}{NEWLINE}({STRINGID}) STR_2216 :{WINDOW_COLOUR_2}{COMMA16}°C STR_2217 :{WINDOW_COLOUR_2}{COMMA16}°F -STR_2218 :{RED}{STRINGID}, {STRINGID}的一部份, 尚未返回到{STRINGID}!{NEWLINE}检查是否被卡住或被停止了 +STR_2218 :{RED}{STRINGID}, {STRINGID}的一部份,尚未返回到{STRINGID}!{NEWLINE}检查是否被卡住或被停止了 STR_2219 :{RED}{COMMA16}人已丧生于{STRINGID}的意外中 STR_2220 :{WINDOW_COLOUR_2}乐园评价: {BLACK}{COMMA16} STR_2221 :{SMALLFONT}{BLACK}乐园评价: {COMMA16} @@ -1616,9 +1616,9 @@ STR_2251 :只可以在道路上建造! STR_2252 :只可以横过道路建造! STR_2253 :运输类游乐设施 STR_2254 :温和类游乐设施 -STR_2255 :云霄飞车 +STR_2255 :过山车 STR_2256 :剌激类游乐设施 -STR_2257 :水文类游乐设施 +STR_2257 :水上乐园设施 STR_2258 :商店及摊贩 STR_2259 :景物及主题景物 STR_2260 :无资金 @@ -1641,9 +1641,9 @@ STR_2276 :{SMALLFONT}{BLACK}显示研发项目进度 STR_2277 :未知 STR_2278 :运输类游乐设施 STR_2279 :温和类游乐设施 -STR_2280 :云霄飞车 +STR_2280 :过山车 STR_2281 :剌激类游乐设施 -STR_2282 :水文类游乐设施 +STR_2282 :水上游乐设施 STR_2283 :商店及摊贩 STR_2284 :景物及主题景物 STR_2285 :初始研发 @@ -1709,7 +1709,7 @@ STR_2350 :{WINDOW_COLOUR_2}雇用日期: {BLACK}{MONTHYEAR} STR_2351 :{WINDOW_COLOUR_2}除草次数: {BLACK}{COMMA16} STR_2352 :{WINDOW_COLOUR_2}灌溉次数: {BLACK}{COMMA16} STR_2353 :{WINDOW_COLOUR_2}扫地次数: {BLACK}{COMMA16} -STR_2354 :{WINDOW_COLOUR_2}清空拉坡筒次数: {BLACK}{COMMA16} +STR_2354 :{WINDOW_COLOUR_2}清空垃圾桶次数: {BLACK}{COMMA16} STR_2355 :{WINDOW_COLOUR_2}修理游乐设施次数: {BLACK}{COMMA16} STR_2356 :{WINDOW_COLOUR_2}检验游乐设施次数: {BLACK}{COMMA16} STR_2358 :单位 @@ -1740,15 +1740,15 @@ STR_2382 :土地 STR_2383 :水面 STR_2384 :{WINDOW_COLOUR_2}你的目标 STR_2385 :{BLACK}无 -STR_2386 :{BLACK}在 {MONTHYEAR} 之前乐园内至少有 {COMMA16} 游客, 并且乐园评分不低于 600 -STR_2387 :{BLACK}在 {PUSH16}{PUSH16}{PUSH16}{MONTHYEAR} 之前乐园价值不低于 {POP16}{POP16}{CURRENCY} +STR_2386 :{BLACK}在{MONTHYEAR} 之前乐园内至少有 {COMMA16} 游客, 并且乐园评分不低于 600 +STR_2387 :{BLACK}在{PUSH16}{PUSH16}{PUSH16}{MONTHYEAR}之前乐园价值不低于{POP16}{POP16}{CURRENCY} STR_2388 :{BLACK}尽情玩吧! STR_2389 :{BLACK}建造你的最佳{STRINGID}吧! STR_2390 :{BLACK}在你的乐园中运营10种类型的过山车, 并且每一个的兴奋度不低于 6.00 STR_2391 :{BLACK}乐园内至少有 {COMMA16} 游客,并且在任何时候你都不能让公园评分低于700 ! STR_2392 :{BLACK}每个月的门票收入至少 {POP16}{POP16}{CURRENCY} STR_2393 :{BLACK}在你的乐园中运营10种类型的过山车, 每一个的长度至少 {LENGTH}, 并且每一个的兴奋度不低于 7.00 -STR_2394 :{BLACK}建造好五座未完成的云霄飞车, 将他们每座设计成兴奋度至少达到{POP16}{POP16}{COMMA2DP32} +STR_2394 :{BLACK}建造好五座未完成的过山车, 将他们每座设计成兴奋度至少达到{POP16}{POP16}{COMMA2DP32} STR_2395 :{BLACK}还清乐园的贷款, 并令其价值至少达到{POP16}{POP16}{CURRENCY} STR_2396 :{BLACK}食物, 饮料及纪念品的销售收入至少要达到每月{POP16}{POP16}{CURRENCY} STR_2397 :无 @@ -1756,11 +1756,11 @@ STR_2398 :指定日期要达到的游客数量 STR_2399 :指定日期要达到的乐园评价 STR_2400 :尽情玩吧 STR_2401 :建造你的最佳游乐设施 -STR_2402 :建造十座云霄飞车 +STR_2402 :建造十座过山车 STR_2403 :乐园内游客数量 STR_2404 :游乐设施门票的每月收入 -STR_2405 :建造十座指定长度的云霄飞车 -STR_2406 :完成建造五座云霄飞车 +STR_2405 :建造十座指定长度的过山车 +STR_2406 :完成建造五座过山车 STR_2407 :付清贷款及达到指定乐园评价 STR_2408 :食物/饮料或其他商品的每月收入 STR_2409 :{WINDOW_COLOUR_2}实行中的营销计划 @@ -1816,7 +1816,7 @@ STR_2468 :{SMALLFONT} {BLACK}显示这个乐园最近获得的奖项 STR_2469 :{SMALLFONT} {BLACK}选择投放多少资金到研发当中 STR_2470 :{SMALLFONT} {BLACK}研发新的运输类游游设施 STR_2471 :{SMALLFONT} {BLACK}研发新的温和类游乐设施 -STR_2472 :{SMALLFONT} {BLACK}研发新的云霄飞车 +STR_2472 :{SMALLFONT} {BLACK}研发新的过山车 STR_2473 :{SMALLFONT} {BLACK}研发新的刺激类游乐设施 STR_2474 :{SMALLFONT} {BLACK}研发新的水文类游乐设施 STR_2475 :{SMALLFONT} {BLACK}研发新的商店及摊贩 @@ -2023,21 +2023,21 @@ STR_2676 :??? STR_2677 :??? STR_2678 :??? STR_2679 :??? -STR_2680 :All research complete -STR_2681 :{MEDIUMFONT}{BLACK}Increases your money by {CURRENCY} -STR_2684 :{SMALLFONT}{BLACK}Large group of guests arrive -STR_2685 :Simplex Noise Parameters -STR_2686 :Low: -STR_2687 :High: -STR_2688 :Base Frequency: -STR_2689 :Octaves: -STR_2690 :Map Generation -STR_2691 :Base height: -STR_2692 :Water level: -STR_2693 :Terrain: -STR_2694 :Generate -STR_2695 :Random terrain -STR_2696 :Place trees +STR_2680 :所有项目已研发完毕 +STR_2681 :{MEDIUMFONT}{BLACK}增加{CURRENCY}到你的账上 +STR_2684 :{SMALLFONT}{BLACK}一大批游客到访 +STR_2685 :单形噪声参数 +STR_2686 :低值: +STR_2687 :高值: +STR_2688 :基础频率: +STR_2689 :八音度: +STR_2690 :生成地图 +STR_2691 :土地基础高度: +STR_2692 :水面高度: +STR_2693 :地形: +STR_2694 :生成 +STR_2695 :随机地形 +STR_2696 :放置树木 STR_2697 :??? STR_2698 :??? STR_2699 :??? @@ -2049,9 +2049,9 @@ STR_2704 :每30分钟 STR_2705 :每小时 STR_2706 :从不 STR_2707 :使用系统的文件浏览器 -STR_2708 :{WINDOW_COLOUR_1}Are you sure you want to overwrite {STRINGID}? -STR_2709 :Overwrite -STR_2710 :Type the name of the file. +STR_2708 :{WINDOW_COLOUR_1}你确定要覆盖存档{STRINGID}? +STR_2709 :覆盖 +STR_2710 :请输入存档名称: STR_2711 :; STR_2712 := STR_2713 :, @@ -2059,8 +2059,8 @@ STR_2714 :- STR_2715 :. STR_2716 :/ STR_2717 :' -STR_2718 :Up -STR_2719 :New file +STR_2718 :向上一层 +STR_2719 :新存档 STR_2720 :{UINT16}秒 STR_2721 :{UINT16}秒 STR_2722 :{UINT16}分:{UINT16}秒 @@ -2089,17 +2089,17 @@ STR_2744 :[ STR_2745 :\ STR_2746 :] STR_2747 :” -STR_2749 :My new scenario +STR_2749 :我的新剧情 # New strings used in the cheats window previously these were ??? -STR_2750 :Move all items to top -STR_2751 :Move all items to bottom -STR_2752 :Clear grass -STR_2753 :修剪好的草地 +STR_2750 :移动全部物品到顶部 +STR_2751 :移动全部物品到底部 +STR_2752 :清理草地 +STR_2753 :已修剪的草地 STR_2754 :浇灌植物 STR_2755 :修复路面设施破损 STR_2756 :去除路面垃圾 STR_2763 :??? -STR_2765 :Large Tram +STR_2765 :添加超多游客到访 STR_2766 :完成剧情目标 STR_2767 :冻结天气 STR_2768 :解除冻结天气 @@ -2119,7 +2119,7 @@ STR_2782 :SHIFT + STR_2783 :CTRL + STR_2784 :变更快捷键 STR_2785 :{WINDOW_COLOUR_2}Press new shortcut key for:{NEWLINE}“{STRINGID}” -STR_2786 :{SMALLFONT}{BLACK}Click on shortcut description to select new key +STR_2786 :{SMALLFONT}{BLACK}点击快捷键描述来设置新的快捷键 STR_2787 :{WINDOW_COLOUR_2}乐园价值: {BLACK}{CURRENCY} STR_2788 :{WINDOW_COLOUR_2}恭喜您!{NEWLINE}{BLACK}你已经达到你的目标, 并令公司价值增至 {CURRENCY} ! STR_2789 :{WINDOW_COLOUR_2}你未达成目标 ! @@ -2129,58 +2129,58 @@ STR_2792 :请输入你要在剧情列表显示的名字: STR_2793 :{SMALLFONT}(由{STRINGID}达成) STR_2794 :{WINDOW_COLOUR_2}完成者: {BLACK}{STRINGID}{NEWLINE}{WINDOW_COLOUR_2} 公司价值: {BLACK}{CURRENCY} STR_2795 :排序 -STR_2796 :{SMALLFONT}{BLACK}Sort the ride list into order using the information type displayed +STR_2796 :{SMALLFONT}{BLACK}将游乐设施按照不同类别排列 STR_2797 :当鼠标位于屏幕边缘时滚动视图 STR_2798 :{SMALLFONT}{BLACK}当鼠标位于屏幕边缘时滚动视图 STR_2799 :{SMALLFONT}{BLACK}查看或改变控制按键分配 -STR_2800 :{WINDOW_COLOUR_2}Total admissions: {BLACK}{COMMA32} -STR_2801 :{WINDOW_COLOUR_2}Income from admissions: {BLACK}{CURRENCY2DP} +STR_2800 :{WINDOW_COLOUR_2}总购票人数: {BLACK}{COMMA32} +STR_2801 :{WINDOW_COLOUR_2}门票收入: {BLACK}{CURRENCY2DP} STR_2802 :地图 STR_2803 :{SMALLFONT}{BLACK}高亮显示游客 STR_2804 :{SMALLFONT}{BLACK}高亮显示雇员 STR_2805 :{SMALLFONT}{BLACK}显示游乐园地图 -STR_2806 :{RED}游客都在投诉乐园里的道路十分肮脏及恶心{NEWLINE}请检查你的清洁工人位置, 并考虑以更好的方法管理他们 -STR_2807 :{RED}游客都在投诉乐园里十分多随地抛弃的垃圾{NEWLINE}请检查你的清洁工人位置, 并考虑以更好的方法管理他们 -STR_2808 :{RED}游客都在投诉乐园里的公物被毁坏{NEWLINE}请检查你的安全警卫位置, 并考虑以更好的方法管理他们 -STR_2809 :{RED}游客都饿了, 但他们找不到卖食物的店舖 -STR_2810 :{RED}游客都渴了, 但他们找不到卖饮料的店舖 -STR_2811 :{RED}游客都在抱怨于乐园里找不到厕所 -STR_2812 :{RED}游客都被卡住或迷失了{NEWLINE}请检查乐园的道路设计是否需要改善, 以便游客找到出路 -STR_2813 :{RED}你的乐园入场费太贵了!{NEWLINE}减低入场费或增加乐团价值来吸引更多游客来访 -STR_2814 :{WINDOW_COLOUR_2}最杂乱无章乐园奖 +STR_2806 :{RED}大量游客投诉乐园里的道路非常肮脏及恶心{NEWLINE}请检查你的清洁工人位置, 并考虑调整的管理方法 +STR_2807 :{RED}大量游客投诉乐园里随处可见的垃圾{NEWLINE}请检查你的清洁工人位置, 并考虑调整管理方法 +STR_2808 :{RED}大量游客投诉乐园里的公物被毁坏{NEWLINE}请检查你的安保人员位置, 并考虑调整管理方法 +STR_2809 :{RED}游客都饿了, 因为他们找不到卖食物的店舖 +STR_2810 :{RED}游客都渴了, 因为他们找不到卖饮料的店舖 +STR_2811 :{RED}游客都在抱怨乐园里找不到厕所 +STR_2812 :{RED}乐园内有游客被卡住或迷路{NEWLINE}请检查乐园的道路设计是否需要改善, 以便游客找到出路 +STR_2813 :{RED}你的游乐园门票太贵了!{NEWLINE}减低门费或增加乐园价值来吸引更多游客来访 +STR_2814 :{WINDOW_COLOUR_2}最肮脏乐园奖 STR_2815 :{WINDOW_COLOUR_2}最整洁乐园奖 -STR_2816 :{WINDOW_COLOUR_2}拥有最棒过山车乐园奖 +STR_2816 :{WINDOW_COLOUR_2}拥有最棒过山车奖 STR_2817 :{WINDOW_COLOUR_2}最有价值乐园奖 STR_2818 :{WINDOW_COLOUR_2}最美乐园奖 STR_2819 :{WINDOW_COLOUR_2}最差价值乐园奖 STR_2820 :{WINDOW_COLOUR_2}最安全乐园奖 -STR_2821 :{WINDOW_COLOUR_2}拥有最佳员工乐园奖 -STR_2822 :{WINDOW_COLOUR_2}拥有最佳食物乐园奖 -STR_2823 :{WINDOW_COLOUR_2}拥有最差食物乐园奖 -STR_2824 :{WINDOW_COLOUR_2}拥有最佳厕所乐园奖 +STR_2821 :{WINDOW_COLOUR_2}拥有最佳员工奖 +STR_2822 :{WINDOW_COLOUR_2}拥有最佳食物奖 +STR_2823 :{WINDOW_COLOUR_2}拥有最差食物奖 +STR_2824 :{WINDOW_COLOUR_2}拥有最佳厕所奖 STR_2825 :{WINDOW_COLOUR_2}最让人失望乐园奖 -STR_2826 :{WINDOW_COLOUR_2}拥有最佳水上游乐设施乐园奖 -STR_2827 :{WINDOW_COLOUR_2}拥有最佳自行设计的游乐设施乐园奖 -STR_2828 :{WINDOW_COLOUR_2}拥有最大胆色彩搭配乐园奖 -STR_2829 :{WINDOW_COLOUR_2}拥有最令人迷失布局乐园奖 -STR_2830 :{WINDOW_COLOUR_2}拥有最温和游乐设施乐园奖 -STR_2831 :{TOPAZ}你的游乐园获得了'全国最杂乱无章乐园奖'! +STR_2826 :{WINDOW_COLOUR_2}拥有最佳水上游乐设施奖 +STR_2827 :{WINDOW_COLOUR_2}拥有最佳自行设计的游乐设施奖 +STR_2828 :{WINDOW_COLOUR_2}拥有最大胆色彩搭配奖 +STR_2829 :{WINDOW_COLOUR_2}拥有最令人迷失布局奖 +STR_2830 :{WINDOW_COLOUR_2}拥有最温和游乐设施奖 +STR_2831 :{TOPAZ}你的游乐园获得了'全国最肮脏乐园奖'! STR_2832 :{TOPAZ}你的游乐园获得了'全国最整洁乐园奖'! -STR_2833 :{TOPAZ}你的游乐园获得了'拥有最棒过山车乐园奖'! +STR_2833 :{TOPAZ}你的游乐园获得了'拥有最棒过山车奖'! STR_2834 :{TOPAZ}你的游乐园获得了'全国最有价值乐园奖'! STR_2835 :{TOPAZ}你的游乐园获得了'全国最美乐园奖'! STR_2836 :{TOPAZ}你的游乐园获得了'全国最差价值乐园奖'! STR_2837 :{TOPAZ}你的游乐园获得了'全国最安全乐园奖'! -STR_2838 :{TOPAZ}你的游乐园获得了'拥有最佳员工乐园奖'! -STR_2839 :{TOPAZ}你的游乐园获得了'拥有最佳食物乐园奖'! -STR_2840 :{TOPAZ}你的游乐园获得了'拥有最差食物乐园奖'! -STR_2841 :{TOPAZ}你的游乐园获得了'拥有最佳厕所乐园奖'! +STR_2838 :{TOPAZ}你的游乐园获得了'拥有最佳员工奖'! +STR_2839 :{TOPAZ}你的游乐园获得了'拥有最佳食物奖'! +STR_2840 :{TOPAZ}你的游乐园获得了'拥有最差食物奖'! +STR_2841 :{TOPAZ}你的游乐园获得了'拥有最佳厕所奖'! STR_2842 :{TOPAZ}你的游乐园获得了'全国最让人失望乐园奖'! -STR_2843 :{TOPAZ}你的游乐园获得了'拥有最佳水上游乐设施乐园奖'! -STR_2844 :{TOPAZ}你的游乐园获得了'拥有最佳自行设计的游乐设施乐园奖'! -STR_2845 :{TOPAZ}你的游乐园获得了'拥有最大胆色彩搭配乐园奖'! -STR_2846 :{TOPAZ}你的游乐园获得了'拥有最令人迷失布局乐园奖'! -STR_2847 :{TOPAZ}你的游乐园获得了'拥有最温和游乐设施乐园奖'! +STR_2843 :{TOPAZ}你的游乐园获得了'拥有最佳水上游乐设施奖'! +STR_2844 :{TOPAZ}你的游乐园获得了'拥有最佳自行设计的游乐设施奖'! +STR_2845 :{TOPAZ}你的游乐园获得了'拥有最大胆色彩搭配奖'! +STR_2846 :{TOPAZ}你的游乐园获得了'拥有最令人迷失布局奖'! +STR_2847 :{TOPAZ}你的游乐园获得了'拥有最温和游乐设施奖'! STR_2848 :{WINDOW_COLOUR_2}暂无获得任何奖项 STR_2849 :新的剧情副本安装完毕 STR_2850 :新的轨道设计安装完毕 @@ -2193,74 +2193,74 @@ STR_2858 :不能开始实行营销计划... STR_2861 :{WINDOW_COLOUR_2}Licensed to Infogrames Interactive Inc. STR_2862 :音乐鸣谢列表... STR_2863 :音乐鸣谢列表 -STR_2864 :{WINDOW_COLOUR_2}March - Children of the Regiment: (Fucik) non copyright +STR_2864 :{WINDOW_COLOUR_2}March - Children of the Regiment: (Fucik) 无版权 STR_2865 :{WINDOW_COLOUR_2}Heyken's Serenade: (J.Heyken) British Standard Music Coy; GEMA, BRITICO -STR_2866 :{WINDOW_COLOUR_2}La Belle Espagnole: (Robert Vollstedt) Copyright Control +STR_2866 :{WINDOW_COLOUR_2}La Belle Espagnole: (Robert Vollstedt) 版权控制 STR_2867 :{WINDOW_COLOUR_2}Wedding Journey: (Traditional) -STR_2868 :{WINDOW_COLOUR_2}Tales from the Vienna Woods: (Johann Strauss) non copyright +STR_2868 :{WINDOW_COLOUR_2}Tales from the Vienna Woods: (Johann Strauss) 无版权 STR_2869 :{WINDOW_COLOUR_2}Slavonic Dance: (Traditional) STR_2870 :{WINDOW_COLOUR_2}Das Alpenhorn: (Traditional) STR_2871 :{WINDOW_COLOUR_2}The Blond Sailor: (Traditional) -STR_2872 :{WINDOW_COLOUR_2}Overture - Poet and Peasant: (Suppe) non copyright -STR_2873 :{WINDOW_COLOUR_2}Waltz Medley: (Johann Strauss) non copyright +STR_2872 :{WINDOW_COLOUR_2}Overture - Poet and Peasant: (Suppe) 无版权 +STR_2873 :{WINDOW_COLOUR_2}Waltz Medley: (Johann Strauss) 无版权 STR_2874 :{WINDOW_COLOUR_2}Bella Bella Bimba: (Traditional) STR_2875 :{WINDOW_COLOUR_2}Original recordings (P) 1976 C.J.Mears Organization, used with consent -STR_2876 :{WINDOW_COLOUR_2}RollerCoaster Tycoon 2 Title Music: (Allister Brimble) copyright © Chris Sawyer -STR_2877 :{WINDOW_COLOUR_2}Dodgems Beat: (Allister Brimble) copyright © Chris Sawyer -STR_2878 :{WINDOW_COLOUR_2}Mid Summer's Heat: (Allister Brimble) copyright © Chris Sawyer -STR_2879 :{WINDOW_COLOUR_2}Pharaoh's Tomb: (Allister Brimble) copyright © Chris Sawyer -STR_2880 :{WINDOW_COLOUR_2}Caesar's March: (Allister Brimble) copyright © Chris Sawyer -STR_2881 :{WINDOW_COLOUR_2}Drifting To Heaven: (Allister Brimble) copyright © Chris Sawyer -STR_2882 :{WINDOW_COLOUR_2}Invaders: (Allister Brimble) copyright © Chris Sawyer -STR_2883 :{WINDOW_COLOUR_2}Eternal Toybox: (Allister Brimble) copyright © Chris Sawyer -STR_2884 :{WINDOW_COLOUR_2}Jungle Juice: (Allister Brimble) copyright © Chris Sawyer -STR_2885 :{WINDOW_COLOUR_2}Ninja's Noodles: (Allister Brimble) copyright © Chris Sawyer -STR_2886 :{WINDOW_COLOUR_2}Voyage to Andromeda: (Allister Brimble) copyright © Chris Sawyer -STR_2887 :{WINDOW_COLOUR_2}Brimble's Beat: (Allister Brimble) copyright © Chris Sawyer -STR_2888 :{WINDOW_COLOUR_2}Atlantis: (Allister Brimble) copyright © Chris Sawyer -STR_2889 :{WINDOW_COLOUR_2}Wild West Kid: (Allister Brimble) copyright © Chris Sawyer -STR_2890 :{WINDOW_COLOUR_2}Vampire's Lair: (Allister Brimble) copyright © Chris Sawyer -STR_2891 :{WINDOW_COLOUR_2}Blockbuster: (Allister Brimble) copyright © Chris Sawyer -STR_2892 :{WINDOW_COLOUR_2}Airtime Rock: (Allister Brimble) copyright © Chris Sawyer -STR_2893 :{WINDOW_COLOUR_2}Searchlight Rag: (Scott Joplin/Allister Brimble) copyright © Chris Sawyer -STR_2894 :{WINDOW_COLOUR_2}Flight of Fantasy: (Steve Blenkinsopp) copyright © Chris Sawyer -STR_2895 :{WINDOW_COLOUR_2}Big Rock: (Allister Brimble) copyright © Chris Sawyer -STR_2896 :{WINDOW_COLOUR_2}Hypothermia: (Allister Brimble) copyright © Chris Sawyer -STR_2897 :{WINDOW_COLOUR_2}Last Sleigh Ride: (Allister Brimble) copyright © Chris Sawyer -STR_2898 :{WINDOW_COLOUR_2}Pipes of Glencairn: (Allister Brimble) copyright © Chris Sawyer -STR_2899 :{WINDOW_COLOUR_2}Traffic Jam: (Allister Brimble) copyright © Chris Sawyer +STR_2876 :{WINDOW_COLOUR_2}RollerCoaster Tycoon 2 Title Music: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2877 :{WINDOW_COLOUR_2}Dodgems Beat: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2878 :{WINDOW_COLOUR_2}Mid Summer's Heat: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2879 :{WINDOW_COLOUR_2}Pharaoh's Tomb: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2880 :{WINDOW_COLOUR_2}Caesar's March: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2881 :{WINDOW_COLOUR_2}Drifting To Heaven: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2882 :{WINDOW_COLOUR_2}Invaders: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2883 :{WINDOW_COLOUR_2}Eternal Toybox: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2884 :{WINDOW_COLOUR_2}Jungle Juice: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2885 :{WINDOW_COLOUR_2}Ninja's Noodles: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2886 :{WINDOW_COLOUR_2}Voyage to Andromeda: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2887 :{WINDOW_COLOUR_2}Brimble's Beat: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2888 :{WINDOW_COLOUR_2}Atlantis: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2889 :{WINDOW_COLOUR_2}Wild West Kid: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2890 :{WINDOW_COLOUR_2}Vampire's Lair: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2891 :{WINDOW_COLOUR_2}Blockbuster: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2892 :{WINDOW_COLOUR_2}Airtime Rock: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2893 :{WINDOW_COLOUR_2}Searchlight Rag: (Scott Joplin/Allister Brimble) 版权所有 © Chris Sawyer +STR_2894 :{WINDOW_COLOUR_2}Flight of Fantasy: (Steve Blenkinsopp) 版权所有 © Chris Sawyer +STR_2895 :{WINDOW_COLOUR_2}Big Rock: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2896 :{WINDOW_COLOUR_2}Hypothermia: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2897 :{WINDOW_COLOUR_2}Last Sleigh Ride: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2898 :{WINDOW_COLOUR_2}Pipes of Glencairn: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2899 :{WINDOW_COLOUR_2}Traffic Jam: (Allister Brimble) 版权所有 © Chris Sawyer STR_2901 :{WINDOW_COLOUR_2}(Samples courtesy of Spectrasonics “Liquid Grooves”) STR_2902 :{WINDOW_COLOUR_2}Toccata: (C.M.Widor, played by Peter James Adcock) recording © Chris Sawyer -STR_2903 :{WINDOW_COLOUR_2}Space Rock: (Allister Brimble) copyright © Chris Sawyer -STR_2904 :{WINDOW_COLOUR_2}Manic Mechanic: (Allister Brimble) copyright © Chris Sawyer -STR_2905 :{WINDOW_COLOUR_2}Techno Torture: (Allister Brimble) copyright © Chris Sawyer -STR_2906 :{WINDOW_COLOUR_2}Sweat Dreams: (Allister Brimble) copyright © Chris Sawyer -STR_2907 :{WINDOW_COLOUR_2}What shall we do with the Drunken Sailor: (Anon/Allister Brimble) copyright © Chris Sawyer -STR_2971 :Main colour scheme -STR_2972 :Alternative colour scheme 1 -STR_2973 :Alternative colour scheme 2 -STR_2974 :Alternative colour scheme 3 -STR_2975 :{SMALLFONT}{BLACK}Select which colour scheme to change, or paint ride with -STR_2976 :{SMALLFONT}{BLACK}Paint an individual area of this ride using the selected colour scheme -STR_2977 :Staff member name -STR_2978 :Enter new name for this member of staff: -STR_2979 :Can't name staff member... -STR_2980 :Too many banners in game -STR_2981 :{RED}No entry - - -STR_2982 :Banner text -STR_2983 :Enter new text for this banner: -STR_2984 :Can't set new text for banner... -STR_2985 :Banner -STR_2986 :{SMALLFONT}{BLACK}Change text on banner -STR_2987 :{SMALLFONT}{BLACK}Set this banner as a 'no-entry' sign for guests -STR_2988 :{SMALLFONT}{BLACK}Demolish this banner -STR_2989 :{SMALLFONT}{BLACK}Select main colour -STR_2990 :{SMALLFONT}{BLACK}Select text colour -STR_2991 :Sign -STR_2992 :Sign text -STR_2993 :Enter new text for this sign: -STR_2994 :{SMALLFONT}{BLACK}Change text on sign -STR_2995 :{SMALLFONT}{BLACK}Demolish this sign +STR_2903 :{WINDOW_COLOUR_2}Space Rock: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2904 :{WINDOW_COLOUR_2}Manic Mechanic: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2905 :{WINDOW_COLOUR_2}Techno Torture: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2906 :{WINDOW_COLOUR_2}Sweat Dreams: (Allister Brimble) 版权所有 © Chris Sawyer +STR_2907 :{WINDOW_COLOUR_2}What shall we do with the Drunken Sailor: (Anon/Allister Brimble) 版权所有 © Chris Sawyer +STR_2971 :主要配色主题 +STR_2972 :额外配色主题1 +STR_2973 :额外配色主题2 +STR_2974 :额外配色主题3 +STR_2975 :{SMALLFONT}{BLACK}选取游乐设施的配色选项来修改 +STR_2976 :{SMALLFONT}{BLACK}将指定区域使用目前选择的配色主题 +STR_2977 :员工命名 +STR_2978 :请输入该员工的新名字: +STR_2979 :不能更改该员工姓名... +STR_2980 :游戏中有过多的横幅 +STR_2981 :{RED}游客止步 - - +STR_2982 :横幅内容 +STR_2983 :请输入新的内容: +STR_2984 :不能设置新的横幅内容... +STR_2985 :横幅 +STR_2986 :{SMALLFONT}{BLACK}修改横幅内容 +STR_2987 :{SMALLFONT}{BLACK}设置当前横幅为“游客止步” +STR_2988 :{SMALLFONT}{BLACK}拆除该横幅 +STR_2989 :{SMALLFONT}{BLACK}选择横幅配色 +STR_2990 :{SMALLFONT}{BLACK}选择文字配色 +STR_2991 :标志 +STR_2992 :标志内容 +STR_2993 :请输入新的标志内容: +STR_2994 :{SMALLFONT}{BLACK}修改标志的内容 +STR_2995 :{SMALLFONT}{BLACK}拆除该标志 STR_2996 :{BLACK}ABC STR_2997 :{GREY}ABC STR_2998 :{WHITE}ABC @@ -2288,10 +2288,10 @@ STR_3019 :童真风格 STR_3020 : STR_3021 :太空风格 STR_3022 :恐怖风格 -STR_3023 :Techno style +STR_3023 :科幻风格 STR_3024 :温和风格 STR_3025 :夏日风格 -STR_3026 :Water style +STR_3026 :水上风格 STR_3027 :西部荒野风格 STR_3028 :侏罗纪风格 STR_3029 :摇滚风格 @@ -2323,7 +2323,7 @@ STR_3058 :砖墙 STR_3059 :树篱 STR_3060 :冰砖墙 STR_3061 :木栅栏 -STR_3062 :{SMALLFONT}{BLACK}标准云霄飞车轨道 +STR_3062 :{SMALLFONT}{BLACK}标准过山车轨道 STR_3063 :{SMALLFONT}{BLACK}水溅轨道 (轨道半浸于水中) STR_3064 :新手级乐园 STR_3065 :挑战级乐园 @@ -2344,9 +2344,9 @@ STR_3091 :你无法删除此轨道! STR_3092 :你无法移动或修改这个游乐设施的车站! STR_3093 :{WINDOW_COLOUR_2}最爱: {BLACK}{STRINGID} STR_3094 :N/A -STR_3095 :{WINDOW_COLOUR_2}链条坡道的链条速度: +STR_3095 :{WINDOW_COLOUR_2}提升坡的上升速度: STR_3096 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VELOCITY} -STR_3097 :{SMALLFONT}{BLACK}选择链条坡道的链条上拉速度 +STR_3097 :{SMALLFONT}{BLACK}选择提升坡的链条上拉速度 STR_3099 :{SMALLFONT}{BLACK}选择颜色 STR_3100 :{SMALLFONT}{BLACK}选择第二颜色 STR_3101 :{SMALLFONT}{BLACK}选择第三颜色 @@ -2369,7 +2369,7 @@ STR_3117 :{BLACK}调用维修人员中... STR_3118 :{BLACK}{STRINGID}正在前往到这个游乐设施 STR_3119 :{BLACK}{STRINGID}正在修复这个游乐设施 STR_3120 :{SMALLFONT}{BLACK}将最邻近, 或在维修此游乐设施的维修人员定位 -STR_3121 :无法将维修人员定位, 或者附近的维修人员都在工作中 +STR_3121 :无法定位维修人员, 或者附近的维修人员都在工作中 STR_3122 :{WINDOW_COLOUR_2}游客的最爱: {BLACK}{COMMA16}位游客 STR_3123 :{WINDOW_COLOUR_2}游客的最爱: {BLACK}{COMMA16}位游客 STR_3124 :故障的{STRINGID} @@ -2461,7 +2461,7 @@ STR_3227 :太多乐园入口! STR_3228 :{SMALLFONT}{BLACK}设置游客的开始步行位置 STR_3229 :区域煞车不能建造在车站之后 STR_3230 :区域煞车不能建造在另一个区域煞车之后 -STR_3231 :区域煞车不能建造在这个链条坡道的顶部之后 +STR_3231 :区域煞车不能建造在这个提升坡的顶部之后 STR_3232 :选项 - 财政 STR_3233 :选项 - 游客 STR_3234 :选项 - 乐园 @@ -2543,7 +2543,7 @@ STR_3309 :{WINDOW_COLOUR_2}{COMMA16} STR_3310 :{WINDOW_COLOUR_2}{LENGTH} STR_3311 :{WINDOW_COLOUR_2}{COMMA2DP32} STR_3312 :{WINDOW_COLOUR_2}请选取要保留的游乐设施/店铺: -STR_3313 :剧情名称 +STR_3313 :剧情命名 STR_3314 :请输入这个剧情的名称: STR_3315 :乐园/剧情的简介 STR_3316 :请输入这个乐园/剧情的简介: @@ -2561,35 +2561,35 @@ STR_3330 :乐园必需有一些己拥有的土地 STR_3331 :由地图边缘到乐园入口的道路尚未连接好, 或者太复杂 - 这些道路必需是一格宽度, 并以越少交界及弯位越好 STR_3332 :乐园入口倒转了, 或没有道路连接至地图边缘 STR_3333 :在存档中导出附加物 -STR_3334 :{SMALLFONT}{BLACK}Select whether to save any additional plug-in object data required (add-in data not supplied with the main product) in saved game or scenario files, allowing them to be loaded by someone who doesn't have the additional object data +STR_3334 :{SMALLFONT}{BLACK}选择是否存储插件的储存文件,以便那些没有插件的玩家载入存档 STR_3335 :轨道设计工具 - 选择游乐设施的类型及车辆种类 STR_3336 :轨道设计管理工具 - 选择游乐设施的类型 -STR_3338 :{BLACK}Custom-designed layout -STR_3339 :{BLACK}{COMMA16} design available, or custom-designed layout -STR_3340 :{BLACK}{COMMA16} designs available, or custom-designed layout +STR_3338 :{BLACK}自定义布局 +STR_3339 :{BLACK}{COMMA16} 预设设计 或者 自定布局 +STR_3340 :{BLACK}{COMMA16} 预设设计 或者 自定布局 STR_3341 :{SMALLFONT}{BLACK}游戏工具 STR_3342 :剧情编辑器 STR_3343 :将游戏存档转换成剧情关 STR_3344 :轨道设计工具 STR_3345 :轨道设计管理工具 STR_3346 :不能保存轨道设计... -STR_3347 :Ride is too large, contains too many elements, or scenery is too spread out +STR_3347 :游乐设施过于庞大,包含太多要素或者景物过于分散 STR_3348 :重命名 STR_3349 :删除 -STR_3350 :轨道设计名称 +STR_3350 :轨道设计命名 STR_3351 :请输入此轨道设计的新名称: STR_3352 :不能重命名此轨道设计... STR_3353 :新名称包含不可用的字符 -STR_3354 :Another file exists with this name, or file is write-protected -STR_3355 :File is write-protected or locked -STR_3356 :Delete File -STR_3357 :{WINDOW_COLOUR_2}Are you sure you want to permanently delete {STRING} ? -STR_3358 :Can't delete track design... -STR_3359 :{BLACK}No track designs of this type -STR_3360 :Warning! -STR_3361 :Too many track designs of this type - Some will not be listed. -STR_3364 :Advanced -STR_3365 :{SMALLFONT}{BLACK}Allow selection of individual items of scenery in addition to scenery groups +STR_3354 :已有相同名称的文件,或文件有写入保护 +STR_3355 :文件有写入保护或被锁定 +STR_3356 :删除文件 +STR_3357 :{WINDOW_COLOUR_2}你确定要永久删除{STRING} ? +STR_3358 :无法删除轨道设计... +STR_3359 :{BLACK}该设施没有已设计好的轨道设计 +STR_3360 :警告! +STR_3361 :该设施有太多设计-列表不会完全列出 +STR_3364 :进阶 +STR_3365 :{SMALLFONT}{BLACK}在选择景物类别之外,允许选择单项景物 STR_3366 :{BLACK}= 游乐设施 STR_3367 :{BLACK}= 食品店 STR_3368 :{BLACK}= 饮品店 @@ -2613,39 +2613,39 @@ STR_3389 :无法选择额外的景观对象... STR_3390 :选取了太多对象 # Start of tutorial strings. Not used at the moment, so not necessary to translate. # End of tutorial strings -STR_3437 :{SMALLFONT}{BLACK}在地形中清理大范围内的景物Clear large areas of scenery from landscape -STR_3438 :Unable to remove all scenery from here... -STR_3439 :Clear Scenery -STR_3440 :Page 1 -STR_3441 :Page 2 -STR_3442 :Page 3 -STR_3443 :Page 4 -STR_3444 :Page 5 -STR_3445 :Set Patrol Area -STR_3446 :Cancel Patrol Area +STR_3437 :{SMALLFONT}{BLACK}在地形中清理大范围内的景物 +STR_3438 :无法移除这里的所有景物... +STR_3439 :移除景物 +STR_3440 :第1页 +STR_3441 :第2页 +STR_3442 :第3页 +STR_3443 :第4页 +STR_3444 :第5页 +STR_3445 :设置巡逻范围 +STR_3446 :取消巡逻范围 # New strings, cleaner STR_5120 :财务 STR_5121 :研发 STR_5122 :根据轨道类型选择游乐设施 (像RCT1一样) -STR_5123 :Renew rides -STR_5125 :All destructable +STR_5123 :翻新游乐设施 +STR_5125 :全可拆除 STR_5126 :随机主题音乐 -STR_5127 :{SMALLFONT}{BLACK}While dragging, paint landscape instead of changing elevation -STR_5128 :Selection size -STR_5129 :Enter selection size between {COMMA16} and {COMMA16} -STR_5130 :Map size -STR_5131 :Enter map size between {COMMA16} and {COMMA16} -STR_5132 :Fix all rides +STR_5127 :{SMALLFONT}{BLACK}拖曳调整地形, 而不调整地势 +STR_5128 :选择大小 +STR_5129 :请输入介于{COMMA16}-{COMMA16}之间的数字 +STR_5130 :地图大小 +STR_5131 :请输入介于{COMMA16}-{COMMA16}之间的数字 +STR_5132 :维修全部游乐设施 STR_5133 :{SMALLFONT}{BLACK}选择较小一些的土地范围 STR_5134 :{SMALLFONT}{BLACK}选择较大一些的土地范围 -STR_5135 :{SMALLFONT}{BLACK}Buy land rights and construction rights -STR_5136 :Land rights -STR_5137 :Unlock operating limits +STR_5135 :{SMALLFONT}{BLACK}购买土地权和建造权 +STR_5136 :土地权 +STR_5137 :解锁操作限制 STR_5138 :{SMALLFONT}{WINDOW_COLOUR_2}{STRINGID} STR_5139 :{WHITE}{STRINGID} -STR_5140 :Disable brakes failure -STR_5141 :Disable all breakdowns +STR_5140 :禁用制动器故障 +STR_5141 :禁用所有故障 STR_5142 :正常速度 STR_5143 :稍快速度 STR_5144 :加快速度 @@ -2681,10 +2681,10 @@ STR_5174 :{SMALLFONT}{BLACK}将Twitch聊天中所有标'!news'的内容以通 STR_5175 :请输入你的Twitch频道名称 STR_5176 :允许Twitch与游戏集成 STR_5177 :显示模式: -STR_5178 :{SMALLFONT}{BLACK}Show financial cheats -STR_5179 :{SMALLFONT}{BLACK}Show guest cheats -STR_5180 :{SMALLFONT}{BLACK}Show park cheats -STR_5181 :{SMALLFONT}{BLACK}Show ride cheats +STR_5178 :{SMALLFONT}{BLACK}显示财务秘籍 +STR_5179 :{SMALLFONT}{BLACK}显示游客秘籍 +STR_5180 :{SMALLFONT}{BLACK}显示乐园秘籍 +STR_5181 :{SMALLFONT}{BLACK}显示设备秘籍 STR_5182 :{INT32} STR_5183 :地面高度 STR_5184 :请输入介乎{COMMA16}及{COMMA16}的地面高度 @@ -2712,7 +2712,7 @@ STR_5205 :游客 STR_5206 :游客列表 STR_5207 :员工 STR_5208 :员工列表 -STR_5209 :横额 +STR_5209 :横幅 STR_5210 :选取对象 STR_5211 :研发列表 STR_5212 :剧情选项 @@ -2742,33 +2742,33 @@ STR_5235 :{SMALLFONT}{BLACK}设置 STR_5236 :Window STR_5237 :调色板 STR_5238 :当前主题: -STR_5239 :Duplicate -STR_5240 :Enter a name for the theme -STR_5241 :Can't change this theme -STR_5242 :Theme name already exists -STR_5243 :Invalid characters used +STR_5239 :复制 +STR_5240 :请输入该主题的名称 +STR_5241 :不能更改主题 +STR_5242 :主题名称已使用 +STR_5243 :使用了无效字符 STR_5244 :主题 -STR_5245 :Top Toolbar -STR_5246 :Bottom Toolbar -STR_5247 :Track Editor Bottom Toolbar -STR_5248 :Scenario Editor Bottom Toolbar -STR_5249 :Title Menu Buttons -STR_5250 :Title Exit Button -STR_5251 :Title Options Button -STR_5252 :Title Scenario Selection -STR_5253 :Park Information -STR_5254 :Create -STR_5255 :{SMALLFONT}{BLACK}Create a new title sequence from scratch -STR_5256 :Create a new theme to make changes to -STR_5257 :{SMALLFONT}{BLACK}Create a new theme based on the current one -STR_5258 :{SMALLFONT}{BLACK}Delete the current theme -STR_5259 :{SMALLFONT}{BLACK}Rename the current theme +STR_5245 :顶部工具栏 +STR_5246 :底部工具栏 +STR_5247 :轨道编辑器底部工具栏 +STR_5248 :场景编辑器底部工具栏 +STR_5249 :主界面菜单按钮 +STR_5250 :主界面退出按钮 +STR_5251 :主界面选项按钮 +STR_5252 :主界面剧情选择按钮 +STR_5253 :乐园信息 +STR_5254 :创建 +STR_5255 :{SMALLFONT}{BLACK}建立全新的主界面动画 +STR_5256 :创建新的主题用于 +STR_5257 :{SMALLFONT}{BLACK}基于当前主题创建新主题 +STR_5258 :{SMALLFONT}{BLACK}删除当前主题 +STR_5259 :{SMALLFONT}{BLACK}重命名当前主题 STR_5260 :大型截图 -STR_5261 :Filter -STR_5262 :Wacky Worlds -STR_5263 :Time Twister -STR_5264 :Custom -STR_5265 :{SMALLFONT}{BLACK}Select which content sources are visible +STR_5261 :过滤 +STR_5262 :怪诞世界 +STR_5263 :扭曲时间 +STR_5264 :自定义 +STR_5265 :{SMALLFONT}{BLACK}选择哪些内容为可视 STR_5266 :{SMALLFONT}{BLACK}显示 STR_5267 :{SMALLFONT}{BLACK}语言及单位 STR_5268 :{SMALLFONT}{BLACK}音效 @@ -2783,74 +2783,74 @@ STR_5276 :输入名称以搜索物件 STR_5277 :清除 STR_5278 :沙盒模式 STR_5279 :关闭沙盒模式 -STR_5280 :{SMALLFONT}{BLACK}Allow editing land ownership settings through the Map window and other options that are normally restricted to the Scenario Editor -STR_5281 :{SMALLFONT}{BLACK}Features -STR_5282 :RCT1 Ride Open/Close Lights -STR_5283 :RCT1 Park Open/Close Lights -STR_5284 :RCT1 Scenario Selection Font +STR_5280 :{SMALLFONT}{BLACK}允许从地图视窗中修改土地拥有权, 以及其他平常只适用于剧情编辑工具的选项 +STR_5281 :{SMALLFONT}{BLACK}功能 +STR_5282 :过山车大亨1式游乐设施开关灯 +STR_5283 :过山车大亨1式乐园开关开关灯 +STR_5284 :过山车大亨1式选择剧情字体 STR_5285 :爆炸!!! STR_5286 :{SMALLFONT}{BLACK}让一些游客爆炸 -STR_5287 :Ride is already broken down -STR_5288 :Ride is closed -STR_5289 :No breakdowns available for this ride -STR_5290 :Fix ride -STR_5291 :Can't force breakdown -STR_5292 :{SMALLFONT}{BLACK}Force a breakdown -STR_5293 :{SMALLFONT}{BLACK}Close ride/attraction -STR_5294 :{SMALLFONT}{BLACK}Test ride/attraction -STR_5295 :{SMALLFONT}{BLACK}Open ride/attraction -STR_5296 :{SMALLFONT}{BLACK}Close park -STR_5297 :{SMALLFONT}{BLACK}Open park +STR_5287 :游乐设施已经故障 +STR_5288 :游乐设施已关闭 +STR_5289 :没有故障适用于该设施 +STR_5290 :维修游乐设施 +STR_5291 :不能强制设施故障 +STR_5292 :{SMALLFONT}{BLACK}强制故障 +STR_5293 :{SMALLFONT}{BLACK}关闭游乐设施/店铺 +STR_5294 :{SMALLFONT}{BLACK}测试游乐设施/店铺 +STR_5295 :{SMALLFONT}{BLACK}开启游乐设施/店铺 +STR_5296 :{SMALLFONT}{BLACK}关闭乐园 +STR_5297 :{SMALLFONT}{BLACK}开启乐园 STR_5298 :{RED}{STRINGID} STR_5299 :{LIGHTPINK}{STRINGID} -STR_5300 :{SMALLFONT}{BLACK}Quick fire staff -STR_5301 :{MEDIUMFONT}{BLACK}Clear your loan -STR_5302 :Clear loan -STR_5303 :Allow building in pause mode +STR_5300 :{SMALLFONT}{BLACK}快速解雇员工 +STR_5301 :{MEDIUMFONT}{BLACK}清除你的贷款 +STR_5302 :清除贷款 +STR_5303 :允许在暂停模式下继续建造 STR_5304 :主菜单动画: STR_5305 :过山车大亨1(RCT1) STR_5306 :过山车大亨1 (+资料片1 - AA) STR_5307 :过山车大亨1 (+资料片1&2 - AA+LL) STR_5308 :过山车大亨2(RCT2) STR_5309 :OpenRCT2 -STR_5310 :Random +STR_5310 :随机 STR_5311 :{SMALLFONT}{BLACK}调试工具 STR_5312 :显示控制台 -STR_5313 :Show tile inspector -STR_5314 :Tile inspector +STR_5313 :显示地图网格检查工具 +STR_5314 :地图网格检查工具 STR_5315 :草地 STR_5316 :沙地 STR_5317 :泥地 STR_5318 :石地 -STR_5319 :火星地 -STR_5320 :Checkerboard -STR_5321 :Grass clumps -STR_5322 :Ice -STR_5323 :Grid (red) -STR_5324 :Grid (yellow) -STR_5325 :Grid (blue) -STR_5326 :Grid (green) -STR_5327 :Sand (dark) -STR_5328 :Sand (light) -STR_5329 :Checkerboard (inverted) -STR_5330 :Underground view -STR_5331 :Rock -STR_5332 :Wood (red) -STR_5333 :Wood (black) -STR_5334 :Ice -STR_5335 :Ride entrance -STR_5336 :Ride exit -STR_5337 :Park entrance -STR_5338 :Element type -STR_5339 :{SMALLFONT}{BLACK}Base height -STR_5340 :{SMALLFONT}{BLACK}Clearance height +STR_5319 :火星 +STR_5320 :棋盘 +STR_5321 :草丛 +STR_5322 :雪地 +STR_5323 :网格 (红) +STR_5324 :网格 (黄) +STR_5325 :网格 (蓝) +STR_5326 :网格 (绿) +STR_5327 :沙地 (较暗) +STR_5328 :沙地 (较浅) +STR_5329 :棋盘 (反转) +STR_5330 :地下视图 +STR_5331 :石地 +STR_5332 :森林 (红) +STR_5333 :森林 (黑) +STR_5334 :雪地 +STR_5335 :设施入口 +STR_5336 :设施出口 +STR_5337 :乐园入口 +STR_5338 :元素类型 +STR_5339 :{SMALLFONT}{BLACK}基础高度 +STR_5340 :{SMALLFONT}{BLACK}清理高度 STR_5343 :自动放置员工 STR_5344 :更新日志 -STR_5345 :Financial cheats -STR_5346 :Guest cheats -STR_5347 :Park cheats -STR_5348 :Ride cheats -STR_5349 :{SMALLFONT}{BLACK}All Rides +STR_5345 :财政秘籍 +STR_5346 :游客秘籍 +STR_5347 :乐园秘籍 +STR_5348 :设施秘籍 +STR_5349 :{SMALLFONT}{BLACK}全部游乐设施 STR_5350 :最大 STR_5351 :最小 STR_5352 :{BLACK}兴奋度: @@ -2878,50 +2878,50 @@ STR_5373 :名称 {STRINGID} STR_5374 :日期 {STRINGID} STR_5375 :▲ STR_5376 :▼ -STR_5377 :{SMALLFONT}{BLACK}Saves -STR_5378 :{SMALLFONT}{BLACK}Script -STR_5379 :{SMALLFONT}{BLACK}Skip to next wait command -STR_5380 :{SMALLFONT}{BLACK}Start playing title sequence -STR_5381 :{SMALLFONT}{BLACK}Stop playing title sequence -STR_5382 :{SMALLFONT}{BLACK}Restart title sequence -STR_5383 :{SMALLFONT}{BLACK}Create a new title sequence based on the current one -STR_5384 :{SMALLFONT}{BLACK}Delete the current title sequence -STR_5385 :{SMALLFONT}{BLACK}Rename the current title sequence -STR_5386 :{SMALLFONT}{BLACK}Insert a new command -STR_5387 :{SMALLFONT}{BLACK}Edit the selected command -STR_5388 :{SMALLFONT}{BLACK}Delete the selected command -STR_5389 :{SMALLFONT}{BLACK}Skip to the selected command in the title sequence -STR_5390 :{SMALLFONT}{BLACK}Move the selected command down -STR_5391 :{SMALLFONT}{BLACK}Move the selected command up -STR_5392 :{SMALLFONT}{BLACK}Add a save to the title sequence -STR_5393 :{SMALLFONT}{BLACK}Remove the selected save from the title sequence -STR_5394 :{SMALLFONT}{BLACK}Rename the selected save -STR_5395 :{SMALLFONT}{BLACK}Load the selected save in game -STR_5396 :{SMALLFONT}{BLACK}Reload the title sequence if changes have been made to it outside of the game -STR_5397 :Can only be used on the title screen -STR_5398 :Cannot edit title sequence while it's playing -STR_5399 :Press the stop button to continue editing -STR_5400 :Can't change this title sequence -STR_5401 :Create a new title sequence to make changes to -STR_5402 :Failed to load title sequence -STR_5403 :There may be no Load or Wait command or a save may be invalid -STR_5404 :Name already exists -STR_5405 :Enter a name for the save -STR_5406 :Enter a name for the title sequence -STR_5407 :Add -STR_5408 :Remove -STR_5409 :Insert -STR_5410 :Edit -STR_5411 :Reload -STR_5412 :Skip to -STR_5413 :Load -STR_5414 :Load{MOVE_X}{87}Six Flags Magic Mountain.SC6 -STR_5415 :Load{MOVE_X}{87}{STRING} -STR_5416 :Load{MOVE_X}{87}No save selected -STR_5417 :Location -STR_5418 :Location{MOVE_X}{87}{COMMA16} {COMMA16} -STR_5419 :Rotate -STR_5420 :Rotate{MOVE_X}{87}{COMMA16} +STR_5377 :{SMALLFONT}{BLACK}保存 +STR_5378 :{SMALLFONT}{BLACK}脚本 +STR_5379 :{SMALLFONT}{BLACK}跳到下一个等待命令 +STR_5380 :{SMALLFONT}{BLACK}开始播放此菜单动画 +STR_5381 :{SMALLFONT}{BLACK}停止播放此菜单动画 +STR_5382 :{SMALLFONT}{BLACK}重新开始播放此菜单动画 +STR_5383 :{SMALLFONT}{BLACK}基于当前菜单动画创建新菜单动画 +STR_5384 :{SMALLFONT}{BLACK}删除当前菜单动画 +STR_5385 :{SMALLFONT}{BLACK}重命名当前菜单动画 +STR_5386 :{SMALLFONT}{BLACK}插入新命令 +STR_5387 :{SMALLFONT}{BLACK}编辑选择的命令 +STR_5388 :{SMALLFONT}{BLACK}删除选择的命令 +STR_5389 :{SMALLFONT}{BLACK}跳过选择的命令 +STR_5390 :{SMALLFONT}{BLACK}向下移动选择的命令 +STR_5391 :{SMALLFONT}{BLACK}向上移动选择的命令 +STR_5392 :{SMALLFONT}{BLACK}在菜单动画上添加存档 +STR_5393 :{SMALLFONT}{BLACK}移除选中的存档 +STR_5394 :{SMALLFONT}{BLACK}重命名选择的存档 +STR_5395 :{SMALLFONT}{BLACK}在游戏中载入选中的存档 +STR_5396 :{SMALLFONT}{BLACK}重载菜单动画,以便显示游戏外所做的改动 +STR_5397 :只能用在主菜单中 +STR_5398 :不能在菜单动画播放时修改 +STR_5399 :点击停止按钮来继续编辑 +STR_5400 :不能修改改菜单动画 +STR_5401 :创建新的菜单动画来 +STR_5402 :载入菜单动画失败 +STR_5403 :无效存档或者没有“载入”或“等待”命令 +STR_5404 :名称已被使用 +STR_5405 :请输入存档名称: +STR_5406 :请输入菜单动画存档名称 +STR_5407 :添加 +STR_5408 :移除 +STR_5409 :插入 +STR_5410 :编辑 +STR_5411 :重载 +STR_5412 :转跳至 +STR_5413 :加载 +STR_5414 :加载{MOVE_X}{87}大型六旗游乐园.SC6 +STR_5415 :加载{MOVE_X}{87}{STRING} +STR_5416 :加载{MOVE_X}{87}无存档被选中 +STR_5417 :定位 +STR_5418 :定位{MOVE_X}{87}{COMMA16} {COMMA16} +STR_5419 :旋转 +STR_5420 :旋转{MOVE_X}{87}{COMMA16} STR_5421 :放大 STR_5422 :放大{MOVE_X}{87}{COMMA16} STR_5423 :等待 @@ -2934,16 +2934,16 @@ STR_5429 :放大级别: STR_5430 :等待毫秒数: STR_5431 :要读取的存档: STR_5432 :命令: -STR_5433 :Title Sequences +STR_5433 :菜单动画 STR_5434 :命令编辑器 STR_5435 :重命名存档 STR_5436 :编辑主菜单动画... STR_5437 :暂无存档被选中 STR_5438 :当命令编辑器打开时不能做出改变 -STR_5439 :A wait command with at least 4 seconds is required with a restart command +STR_5439 :重新开始(Restart)命令需要加上4秒以上的等待(Wait)命令 STR_5440 :当焦点失去时最小化全屏幕的游戏 STR_5441 :{SMALLFONT}{BLACK}根据轨道类型区分游乐设施{NEWLINE}使得车辆类型可以在建造后更改{NEWLINE}(过山车大亨1行为). -STR_5442 :Force park rating: +STR_5442 :强制乐园评价: STR_5443 :速度{MOVE_X}{87}{STRINGID} STR_5444 :速度: STR_5445 :速度 @@ -2976,7 +2976,7 @@ STR_5471 :向下滚动地图 STR_5472 :向右滚动地图 STR_5473 :日夜循环 STR_5474 :横幅上显示全大写英文 -STR_5475 :{COMMA16} weeks +STR_5475 :{COMMA16} 周 STR_5476 :硬件 STR_5477 :地图显示 STR_5478 :控制 @@ -3047,7 +3047,7 @@ STR_5544 :{SMALLFONT}{BLACK}亮红色 STR_5545 :{SMALLFONT}{BLACK}暗红色 STR_5546 :{SMALLFONT}{BLACK}亮粉色 STR_5547 :{SMALLFONT}{BLACK}浅粉色 -STR_5548 :Show all operating modes +STR_5548 :显示所有运行模式 STR_5549 :年/月/日 STR_5550 :{POP16}{POP16}{COMMA16}年, {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID} STR_5551 :年/日/月 @@ -3066,10 +3066,10 @@ STR_5563 :此功能暂未稳定地使用,请多加留意. STR_5564 :插入已损坏元素 STR_5565 :{SMALLFONT}{BLACK}在一个网格的最上插入一个已损坏的地图元素.此插入会隐藏其他元素. STR_5566 :密码: -STR_5567 :Advertise +STR_5567 :广告 STR_5568 :需要密码 STR_5569 :此服务器需要密码 -STR_5570 :Fetch Servers +STR_5570 :获取服务器 STR_5571 :加入游戏 STR_5572 :添加至收藏 STR_5573 :从收藏中去除 @@ -3111,7 +3111,7 @@ STR_5608 :BH STR_5609 :CH STR_5610 :{SMALLFONT}{BLACK}移除选中的地图元素. 使用时请注意. 因为强制移除地图元素并不会对游戏中的现金做成影响. STR_5611 :G -STR_5612 :{SMALLFONT}{BLACK}Ghost flag +STR_5612 :{SMALLFONT}{BLACK}鬼旗 STR_5613 :B STR_5614 :{SMALLFONT}{BLACK}损坏标记 STR_5615 :L @@ -3134,8 +3134,8 @@ STR_5631 :原版DLC游乐园 STR_5632 :修建你自己的... STR_5633 :CMD + STR_5634 :OPTION + -STR_5635 :{WINDOW_COLOUR_2}Money spent: {BLACK}{CURRENCY2DP} -STR_5636 :{WINDOW_COLOUR_2}Commands ran: {BLACK}{COMMA16} +STR_5635 :{WINDOW_COLOUR_2}花费: {BLACK}{CURRENCY2DP} +STR_5636 :{WINDOW_COLOUR_2}命令运行: {BLACK}{COMMA16} STR_5637 :不能做此行为... STR_5638 :权限不够 STR_5639 :{SMALLFONT}{BLACK}显示玩家列表 @@ -3145,9 +3145,9 @@ STR_5642 :组 STR_5643 :添加组 STR_5644 :删除组 STR_5645 :聊天 -STR_5646 :Terraform +STR_5646 :修改地势 STR_5647 :切换暂停 -STR_5648 :Set Water Level +STR_5648 :设置水位 STR_5649 :创建游乐设施 STR_5650 :移除游乐设施 STR_5651 :修建游乐设施 @@ -3165,10 +3165,10 @@ STR_5661 :设置玩家组 STR_5662 :N/A STR_5663 :清除景物 STR_5664 :作弊 -STR_5665 :Toggle Scenery Cluster +STR_5665 :切换风景群集 STR_5666 :无密码登录 STR_5701 :{WINDOW_COLOUR_2}最近的行为: {BLACK}{STRINGID} -STR_5702 :{SMALLFONT}{BLACK}Locate player's most recent action +STR_5702 :{SMALLFONT}{BLACK}定位玩家最近的动作 STR_5703 :不能踢出创建者 STR_5704 :最近的行为 STR_5705 :不能将此玩家分配到该组 @@ -3206,10 +3206,10 @@ STR_5737 :已关闭, {COMMA16} 个游客仍在此游乐设施上 STR_5738 :已关闭, {COMMA16} 个游客仍在此游乐设施上 STR_5739 :{WINDOW_COLOUR_2}此游乐设施上的游客: {BLACK}{COMMA16} STR_5740 :永不结束的市场推广计划 -STR_5741 :{SMALLFONT}{BLACK}Marketing campaigns never end +STR_5741 :{SMALLFONT}{BLACK}推广计划将不断进行下去 STR_5742 :认证中 ... STR_5743 :连接中 ... -STR_5744 :Resolving ... +STR_5744 :解析中 ... STR_5745 :检测到网络不同步 STR_5746 :已断线 STR_5747 :已断线: {STRING} @@ -3412,7 +3412,7 @@ STR_5945 :{WINDOW_COLOUR_2}已连接的边缘: STR_5946 :{WINDOW_COLOUR_2}游乐设施种类:{BLACK}{STRINGID} STR_5947 :{WINDOW_COLOUR_2}游乐设施ID:{BLACK}{COMMA16} STR_5948 :{WINDOW_COLOUR_2}游乐设施名称:{BLACK}{STRINGID} -STR_5949 :{WINDOW_COLOUR_2}链条坡道 +STR_5949 :{WINDOW_COLOUR_2}提升坡 STR_5950 :{WINDOW_COLOUR_2}将改变应用于整个轨道组件中 STR_5951 :{WINDOW_COLOUR_2}轨道组件ID:{BLACK}{COMMA16} STR_5952 :{WINDOW_COLOUR_2}编号:{BLACK}{COMMA16} @@ -3568,12 +3568,12 @@ STR_6101 :游乐设施不会随时间流逝而贬值 STR_6102 :{SMALLFONT}{BLACK}游乐设施的价值不会随时间流逝而贬值, 因此游客不会产生玩此游乐设施太贵的想法. STR_6103 :{SMALLFONT}{BLACK}此选项在联网模式下被禁用. STR_6104 :螺旋过山车 -STR_6105 :Hypercoaster +STR_6105 :超级过山车 STR_6106 :轨道小车 -STR_6107 :Monster Trucks +STR_6107 :怪兽卡车 STR_6108 :钢架旋转式 STR_6109 :超旋转式 -STR_6110 :Junior过山车 +STR_6110 :儿童过山车 STR_6111 :经典迷你过山车 STR_6112 :一种紧凑的钢制轨道过山车, 其车厢穿越螺旋轨道和回旋轨道 STR_6113 :一种高大的非翻转的过山车, 拥有巨大降落, 高速和只有围栏限制的舒适的车厢 @@ -3685,7 +3685,7 @@ STR_6217 :游乐设施 / 轨道可用性 STR_6218 :OpenRCT2官方 STR_6219 :高亮道路相关物 STR_6220 :使之可用 -STR_6221 :{SMALLFONT}{BLACK}This will set the ride's known entrance or exit location to the currently selected tile. 每个站台只能有一个入口或出口使之可用. +STR_6221 :{SMALLFONT}{BLACK}每个站台只能有一个入口或出口可用. STR_6222 :无法在此放置游客入口... STR_6223 :必须在游乐园边界外! STR_6224 :{STRING}放置一个游客入口. @@ -3738,7 +3738,7 @@ STR_6270 :地表 STR_6271 :地表边缘 STR_6272 :站台 STR_6273 :音乐 -STR_6274 :无法设置配色方案... +STR_6274 :无法设置配色主题... STR_6275 :{WINDOW_COLOUR_2}车站类型: STR_6276 :{RED}{STRINGID} 有游客被困住了,这可能是因为无效的设施类型或者运行模式 STR_6277 :{WINDOW_COLOUR_2}车站编号: {BLACK}{COMMA16} From eb6ea8e81d628e905eeb6cb6a176d07e4b2a0a34 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Mon, 15 Apr 2019 14:03:24 +0200 Subject: [PATCH 211/506] Fix #5893: Invalidate widget only if it's visible Remove the widget_invalidate() call after changing a guest's guest_heading_to_ride_id, because that call fails a debug assertion if the guest window is open and the currently active tab is not the "overview" tab. In Release builds (if assertion is disabled), widget_invalidate() might access the widgets array out of bounds. Instead, introduce a new flag PEEP_INVALIDATE_PEEP_ACTION for window_invalidate_flags in the peep struct and set that flag. The guest window update function then makes sure to invalidate the label if the flag is set. The flag could be used in other places to reduce libopenrct2 dependency on window_*() calls (see #6808), but this commit only cares about cases where the assertion would fail. --- src/openrct2-ui/windows/Guest.cpp | 10 +++++++-- src/openrct2/interface/Window.h | 1 - src/openrct2/peep/Guest.cpp | 35 ++++--------------------------- src/openrct2/peep/Peep.h | 1 + 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 0913983a95..1f11beff28 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -62,7 +62,6 @@ enum WINDOW_GUEST_WIDGET_IDX { WIDX_RIDE_SCROLL = 10 }; -validate_global_widx(WC_PEEP, WIDX_ACTION_LBL); validate_global_widx(WC_PEEP, WIDX_PICKUP); static rct_widget window_guest_overview_widgets[] = { @@ -1090,6 +1089,8 @@ void window_guest_overview_invalidate(rct_window* w) */ void window_guest_overview_update(rct_window* w) { + Peep* peep = GET_PEEP(w->number); + int32_t var_496 = w->var_496; var_496++; var_496 %= 24; @@ -1098,6 +1099,12 @@ void window_guest_overview_update(rct_window* w) widget_invalidate(w, WIDX_TAB_1); widget_invalidate(w, WIDX_TAB_2); + if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_ACTION) + { + peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_ACTION; + widget_invalidate(w, WIDX_ACTION_LBL); + } + w->list_information_type += 2; if ((w->highlighted_item & 0xFFFF) == 0xFFFF) @@ -1116,7 +1123,6 @@ void window_guest_overview_update(rct_window* w) int32_t random = util_rand() & 0xFFFF; if (random <= 0x2AAA) { - Peep* peep = GET_PEEP(w->number); peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, PEEP_THOUGHT_ITEM_NONE); } } diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 6835f620cf..613109b785 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -489,7 +489,6 @@ enum #define WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON 25 #define WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON 30 #define WC_PEEP__WIDX_PATROL 11 -#define WC_PEEP__WIDX_ACTION_LBL 12 #define WC_PEEP__WIDX_PICKUP 13 #define WC_TRACK_DESIGN_LIST__WIDX_ROTATE 8 #define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3 diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index e952c3ada1..38d863bf43 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1485,13 +1485,7 @@ void Guest::OnExitRide(ride_id_t rideIndex) guest_heading_to_ride_id = rideIndex; peep_is_lost_countdown = 200; peep_reset_pathfind_goal(this); - - rct_window* w = window_find_by_number(WC_PEEP, sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; } if (peep_should_preferred_intensity_increase(this)) @@ -1550,14 +1544,7 @@ void Guest::PickRideToGoOn() guest_heading_to_ride_id = ride->id; peep_is_lost_countdown = 200; peep_reset_pathfind_goal(this); - - // Invalidate windows - auto w = window_find_by_number(WC_PEEP, sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; // Make peep look at their map if they have one if (item_standard_flags & PEEP_ITEM_MAP) @@ -2133,15 +2120,8 @@ static void peep_tried_to_enter_full_queue(Peep* peep, Ride* ride) static void peep_reset_ride_heading(Peep* peep) { - rct_window* w; - peep->guest_heading_to_ride_id = RIDE_ID_NULL; - w = window_find_by_number(WC_PEEP, peep->sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; } static void peep_ride_is_too_intense(Guest* peep, Ride* ride, bool peepAtRide) @@ -2956,14 +2936,7 @@ static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType) peep->guest_heading_to_ride_id = closestRideIndex; peep->peep_is_lost_countdown = 200; peep_reset_pathfind_goal(peep); - - // Invalidate windows - rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); - if (w != nullptr) - { - window_event_invalidate_call(w); - widget_invalidate(w, WC_PEEP__WIDX_ACTION_LBL); - } + peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_ACTION; peep->time_lost = 0; } diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 1d6550a47f..035a60b6d4 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -511,6 +511,7 @@ enum PeepInvalidate PEEP_INVALIDATE_PEEP_2 = 1 << 2, PEEP_INVALIDATE_PEEP_INVENTORY = 1 << 3, PEEP_INVALIDATE_STAFF_STATS = 1 << 4, + PEEP_INVALIDATE_PEEP_ACTION = 1 << 5 // Currently set only when guest_heading_to_ride_id is changed }; // Flags used by peep_should_go_on_ride() From 35ff10e480e4a2cd4ea98817825b339be733c6e7 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Mon, 15 Apr 2019 15:51:01 +0200 Subject: [PATCH 212/506] Fix format issue and add myself to contributors.md --- contributors.md | 1 + src/openrct2/peep/Peep.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contributors.md b/contributors.md index 2aa925ae12..9af5276289 100644 --- a/contributors.md +++ b/contributors.md @@ -125,6 +125,7 @@ The following people are not part of the development team, but have been contrib * Brandon Dupree (Bdupree5) * Zetao Ye (ZbrettonYe) * Jordan Arevalos (Jarevalos2017) +* Florian Will (w-flo) ## Toolchain * (Balletie) - macOS diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 035a60b6d4..0dc1540386 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -511,7 +511,7 @@ enum PeepInvalidate PEEP_INVALIDATE_PEEP_2 = 1 << 2, PEEP_INVALIDATE_PEEP_INVENTORY = 1 << 3, PEEP_INVALIDATE_STAFF_STATS = 1 << 4, - PEEP_INVALIDATE_PEEP_ACTION = 1 << 5 // Currently set only when guest_heading_to_ride_id is changed + PEEP_INVALIDATE_PEEP_ACTION = 1 << 5, // Currently set only when guest_heading_to_ride_id is changed }; // Flags used by peep_should_go_on_ride() From 6e9a9448a2835db55e687e825ee23bd407c530f8 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Mon, 15 Apr 2019 16:10:57 +0200 Subject: [PATCH 213/506] Fix format issue, second attempt Let's see if I can get this right. --- src/openrct2/peep/Peep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 0dc1540386..ecebd78f3f 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -511,7 +511,7 @@ enum PeepInvalidate PEEP_INVALIDATE_PEEP_2 = 1 << 2, PEEP_INVALIDATE_PEEP_INVENTORY = 1 << 3, PEEP_INVALIDATE_STAFF_STATS = 1 << 4, - PEEP_INVALIDATE_PEEP_ACTION = 1 << 5, // Currently set only when guest_heading_to_ride_id is changed + PEEP_INVALIDATE_PEEP_ACTION = 1 << 5, // Currently set only when guest_heading_to_ride_id is changed }; // Flags used by peep_should_go_on_ride() From 0d3f287447a674dec433c988643cb0cb4d9a3124 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Mon, 15 Apr 2019 19:11:30 +0200 Subject: [PATCH 214/506] Add changelog entry, minor code improvements --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/Guest.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index db6780ec30..b41c9335e9 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -8,6 +8,7 @@ - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. +- Fix: [#5893] Looking at guest window tabs other than the main tab eventually causes assertion. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 1f11beff28..35221ccd01 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1089,8 +1089,6 @@ void window_guest_overview_invalidate(rct_window* w) */ void window_guest_overview_update(rct_window* w) { - Peep* peep = GET_PEEP(w->number); - int32_t var_496 = w->var_496; var_496++; var_496 %= 24; @@ -1099,7 +1097,8 @@ void window_guest_overview_update(rct_window* w) widget_invalidate(w, WIDX_TAB_1); widget_invalidate(w, WIDX_TAB_2); - if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_ACTION) + Peep* peep = GET_PEEP(w->number); + if (peep != nullptr && peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_ACTION) { peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_ACTION; widget_invalidate(w, WIDX_ACTION_LBL); From 70fc620ebee6363430ed4fa1c077bfd04e6cd09f Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Thu, 11 Apr 2019 22:51:08 +0200 Subject: [PATCH 215/506] Fix #9083: Wrong sign index is set for clients This issue was caused by the ghost for banners, which already create an entry on the banner. The game command is then received while the ghost still exists, giving the placed banner another ID. This fix is basically a copy of the fix that is also `game_do_command_p` that tackles this same issue. --- src/openrct2/network/Network.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 32a355c775..94e737183d 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1976,6 +1976,17 @@ void Network::ProcessGameCommands() if (gc.action != nullptr) { + // Remove ghost scenery so it doesn't interfere with incoming network command + switch (gc.action->GetType()) + { + case GAME_COMMAND_PLACE_WALL: + case GAME_COMMAND_PLACE_LARGE_SCENERY: + case GAME_COMMAND_PLACE_BANNER: + case GAME_COMMAND_PLACE_SCENERY: + scenery_remove_ghost_tool_placement(); + break; + } + GameAction* action = gc.action.get(); action->SetFlags(action->GetFlags() | GAME_COMMAND_FLAG_NETWORKED); From 8cb50432de5f3582f5abcd575f70bd9d116921f0 Mon Sep 17 00:00:00 2001 From: Trevor Harkness Date: Wed, 17 Apr 2019 22:55:37 -0400 Subject: [PATCH 216/506] Fix #9053. Remove instances of gSceneryGroundFlags Created subclass of GameActionResult in LargeSceneryPlaceAction and SmallSceneryPlaceAction. Removed references to global variable in other files. --- src/openrct2-ui/windows/TopToolbar.cpp | 6 +- .../actions/LargeSceneryPlaceAction.hpp | 81 +++++++++++++------ .../actions/SmallSceneryPlaceAction.hpp | 57 +++++++++---- src/openrct2/world/Scenery.cpp | 2 - src/openrct2/world/Scenery.h | 2 - 5 files changed, 98 insertions(+), 50 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 7ad88c914d..06a2d52693 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2487,7 +2487,7 @@ static money32 try_place_ghost_scenery( tileElement = gSceneryTileElement; gSceneryGhostPosition.z = tileElement->base_height; gSceneryQuadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant(); - if (gSceneryGroundFlags & ELEMENT_IS_UNDERGROUND) + if (dynamic_cast(res.get())->GroundFlags & ELEMENT_IS_UNDERGROUND) { // Set underground on viewport_set_visibility(4); @@ -2581,8 +2581,8 @@ static money32 try_place_ghost_scenery( tileElement = gSceneryTileElement; gSceneryGhostPosition.z = tileElement->base_height; - - if (gSceneryGroundFlags & ELEMENT_IS_UNDERGROUND) + + if (dynamic_cast(res.get())->GroundFlags & ELEMENT_IS_UNDERGROUND) { // Set underground on viewport_set_visibility(4); diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 80111a85cf..3b6128bd80 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -19,7 +19,30 @@ #include "../world/Scenery.h" #include "GameAction.h" -DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GAME_COMMAND_PLACE_LARGE_SCENERY, GameActionResult) +class LargeSceneryPlaceActionResult final : public GameActionResult // new class to be changed +{ +public: + LargeSceneryPlaceActionResult() + : GameActionResult(GA_ERROR::OK, STR_CANT_POSITION_THIS_HERE) + { + } + LargeSceneryPlaceActionResult(GA_ERROR error) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE) + { + } + LargeSceneryPlaceActionResult(GA_ERROR error, rct_string_id message) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE, message) + { + } + LargeSceneryPlaceActionResult(GA_ERROR error, rct_string_id message, uint8_t* args) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE, message, args) + { + } + + uint8_t GroundFlags{ 0 }; +}; + +DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GAME_COMMAND_PLACE_LARGE_SCENERY, LargeSceneryPlaceActionResult) { private: CoordsXYZD _loc; @@ -52,7 +75,7 @@ public: GameActionResult::Ptr Query() const override { - auto res = MakeResult(); + auto res = std::make_unique(); res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; @@ -60,7 +83,8 @@ public: res->Position.y = _loc.y + 16; res->Position.z = surfaceHeight; - gSceneryGroundFlags = 0; + res->GroundFlags = 0; + BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; @@ -69,20 +93,20 @@ public: 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); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } 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); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } 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); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } uint32_t totalNumTiles = GetTotalNumTiles(sceneryEntry->large_scenery.tiles); @@ -102,14 +126,14 @@ public: if (bannerId == BANNER_INDEX_NULL) { log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } } 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); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } uint8_t tileNum = 0; @@ -131,8 +155,8 @@ public: 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); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } int32_t tempSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); @@ -140,25 +164,29 @@ public: { if ((gMapGroundFlags & ELEMENT_IS_UNDERWATER) || (gMapGroundFlags & ELEMENT_IS_UNDERGROUND)) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_THIS_UNDERWATER); } - if (gSceneryGroundFlags && !(gSceneryGroundFlags & tempSceneryGroundFlags)) + if (res->GroundFlags && !(res->GroundFlags & tempSceneryGroundFlags)) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); } } - gSceneryGroundFlags = tempSceneryGroundFlags; + + res->GroundFlags = tempSceneryGroundFlags; if (curTile.x >= gMapSizeUnits || curTile.y >= gMapSizeUnits) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_OFF_EDGE_OF_MAP); } if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned(curTile.x, curTile.y, zLow * 8) && !gCheatsSandboxMode) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); } } @@ -171,7 +199,7 @@ public: GameActionResult::Ptr Execute() const override { - auto res = MakeResult(); + auto res = std::make_unique(); res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; @@ -179,7 +207,8 @@ public: res->Position.y = _loc.y + 16; res->Position.z = surfaceHeight; - gSceneryGroundFlags = 0; + res->GroundFlags = 0; + BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; @@ -187,13 +216,13 @@ public: 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); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } 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); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } uint32_t totalNumTiles = GetTotalNumTiles(sceneryEntry->large_scenery.tiles); @@ -213,7 +242,7 @@ public: if (bannerId == BANNER_INDEX_NULL) { log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } rct_banner* banner = &gBanners[bannerId]; @@ -233,7 +262,7 @@ public: 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); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } uint8_t tileNum = 0; @@ -255,11 +284,11 @@ public: 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); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } - gSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + res->GroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index f20db46d2d..c27926ef05 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -27,6 +27,29 @@ #include "../world/TileElement.h" #include "GameAction.h" +class SmallSceneryPlaceActionResult final : public GameActionResult // new class to be changed +{ +public: + SmallSceneryPlaceActionResult() + : GameActionResult(GA_ERROR::OK, STR_CANT_POSITION_THIS_HERE) + { + } + SmallSceneryPlaceActionResult(GA_ERROR error) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE) + { + } + SmallSceneryPlaceActionResult(GA_ERROR error, rct_string_id message) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE, message) + { + } + SmallSceneryPlaceActionResult(GA_ERROR error, rct_string_id message, uint8_t* args) + : GameActionResult(error, STR_CANT_POSITION_THIS_HERE, message, args) + { + } + + uint8_t GroundFlags{ 0 }; +}; + DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GAME_COMMAND_PLACE_SCENERY, GameActionResult) { private: @@ -81,7 +104,7 @@ public: { baseHeight >>= 16; } - auto res = MakeResult(); + auto res = std::make_unique(); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; res->Position.z = baseHeight; @@ -93,18 +116,18 @@ public: if (!map_check_free_elements_and_reorganise(1)) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } if (!byte_9D8150 && (_loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)) { - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } rct_scenery_entry* sceneryEntry = get_small_scenery_entry(_sceneryType); if (sceneryEntry == nullptr) { - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } auto quadrant = _quadrant; @@ -152,7 +175,7 @@ public: if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned(_loc.x, _loc.y, targetHeight)) { - return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + return std::make_unique(GA_ERROR::NOT_OWNED, STR_LAND_NOT_OWNED_BY_PARK); } TileElement* surfaceElement = map_get_surface_element_at({ _loc.x, _loc.y }); @@ -162,7 +185,7 @@ public: int32_t water_height = (surfaceElement->AsSurface()->GetWaterHeight() * 16) - 1; if (water_height > targetHeight) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_BUILD_THIS_UNDERWATER); } } @@ -170,14 +193,14 @@ public: { if (isOnWater) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } if (surfaceElement != nullptr && surfaceElement->AsSurface()->GetWaterHeight() > 0) { if (static_cast((surfaceElement->AsSurface()->GetWaterHeight() * 16)) > targetHeight) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } } } @@ -186,7 +209,7 @@ public: && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) && !supportsRequired && !isOnWater && surfaceElement != nullptr && (surfaceElement->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED); + return std::make_unique(GA_ERROR::DISALLOWED, STR_LEVEL_LAND_REQUIRED); } if (!gCheatsDisableSupportLimits && !(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_STACKABLE)) @@ -198,13 +221,13 @@ public: { if (surfaceElement->AsSurface()->GetWaterHeight() || (surfaceElement->base_height * 8) != targetHeight) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED); + return std::make_unique(GA_ERROR::DISALLOWED, STR_LEVEL_LAND_REQUIRED); } } } else { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } } @@ -252,10 +275,10 @@ public: _loc.x, _loc.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags(), &clearCost, CREATE_CROSSING_MODE_NONE)) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique(GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); } - gSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + res->GroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; res->Cost = (sceneryEntry->small_scenery.price * 10) + clearCost; @@ -276,7 +299,7 @@ public: { baseHeight >>= 16; } - auto res = MakeResult(); + auto res = std::make_unique(); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; res->Position.z = baseHeight; @@ -289,7 +312,7 @@ public: rct_scenery_entry* sceneryEntry = get_small_scenery_entry(_sceneryType); if (sceneryEntry == nullptr) { - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } auto quadrant = _quadrant; @@ -383,10 +406,10 @@ public: _loc.x, _loc.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags() | GAME_COMMAND_FLAG_APPLY, &clearCost, CREATE_CROSSING_MODE_NONE)) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_POSITION_THIS_HERE, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique(GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); } - gSceneryGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + res->GroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; res->Cost = (sceneryEntry->small_scenery.price * 10) + clearCost; diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 022197a0f4..77eb443ad6 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -63,8 +63,6 @@ int16_t gSceneryShiftPressZOffset; int16_t gSceneryCtrlPressed; int16_t gSceneryCtrlPressZ; -uint8_t gSceneryGroundFlags; - money32 gClearSceneryCost; // rct2: 0x009A3E74 diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h index 528524b672..9fd3c62581 100644 --- a/src/openrct2/world/Scenery.h +++ b/src/openrct2/world/Scenery.h @@ -279,8 +279,6 @@ extern int16_t gSceneryShiftPressZOffset; extern int16_t gSceneryCtrlPressed; extern int16_t gSceneryCtrlPressZ; -extern uint8_t gSceneryGroundFlags; - extern const LocationXY8 ScenerySubTileOffsets[]; extern money32 gClearSceneryCost; From 6df19daa020b709ff3546789f030ba6d4518e909 Mon Sep 17 00:00:00 2001 From: Trevor Harkness Date: Wed, 17 Apr 2019 23:03:37 -0400 Subject: [PATCH 217/506] Remove comments from subclass --- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 2 +- src/openrct2/actions/SmallSceneryPlaceAction.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 3b6128bd80..a9cc764e74 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -19,7 +19,7 @@ #include "../world/Scenery.h" #include "GameAction.h" -class LargeSceneryPlaceActionResult final : public GameActionResult // new class to be changed +class LargeSceneryPlaceActionResult final : public GameActionResult { public: LargeSceneryPlaceActionResult() diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index c27926ef05..43f25d817d 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -27,7 +27,7 @@ #include "../world/TileElement.h" #include "GameAction.h" -class SmallSceneryPlaceActionResult final : public GameActionResult // new class to be changed +class SmallSceneryPlaceActionResult final : public GameActionResult { public: SmallSceneryPlaceActionResult() From 844a28f3f5f621bd5a871f1b09301c2e1c423b76 Mon Sep 17 00:00:00 2001 From: Trevor Harkness Date: Fri, 19 Apr 2019 02:18:55 -0400 Subject: [PATCH 218/506] Fix formatting and added to contributors.md Adjusted formatting for CI tests --- contributors.md | 2 ++ src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 12 +++++------- src/openrct2/actions/SmallSceneryPlaceAction.hpp | 14 ++++++++------ 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/contributors.md b/contributors.md index 9af5276289..b22ee9eda9 100644 --- a/contributors.md +++ b/contributors.md @@ -126,6 +126,8 @@ The following people are not part of the development team, but have been contrib * Zetao Ye (ZbrettonYe) * Jordan Arevalos (Jarevalos2017) * Florian Will (w-flo) +* Trevor Harkness (tharkne) +* Steve Xu (stevexu-umich) ## Toolchain * (Balletie) - macOS diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 06a2d52693..1b385efef5 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2581,7 +2581,7 @@ static money32 try_place_ghost_scenery( tileElement = gSceneryTileElement; gSceneryGhostPosition.z = tileElement->base_height; - + if (dynamic_cast(res.get())->GroundFlags & ELEMENT_IS_UNDERGROUND) { // Set underground on diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index a9cc764e74..ff3f2e4090 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -24,7 +24,7 @@ class LargeSceneryPlaceActionResult final : public GameActionResult public: LargeSceneryPlaceActionResult() : GameActionResult(GA_ERROR::OK, STR_CANT_POSITION_THIS_HERE) - { + { } LargeSceneryPlaceActionResult(GA_ERROR error) : GameActionResult(error, STR_CANT_POSITION_THIS_HERE) @@ -84,7 +84,7 @@ public: res->Position.z = surfaceHeight; res->GroundFlags = 0; - + BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; @@ -170,7 +170,7 @@ public: if (res->GroundFlags && !(res->GroundFlags & tempSceneryGroundFlags)) { return std::make_unique( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); + GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND); } } @@ -178,15 +178,13 @@ public: if (curTile.x >= gMapSizeUnits || curTile.y >= gMapSizeUnits) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_OFF_EDGE_OF_MAP); + return std::make_unique(GA_ERROR::DISALLOWED, STR_OFF_EDGE_OF_MAP); } if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !map_is_location_owned(curTile.x, curTile.y, zLow * 8) && !gCheatsSandboxMode) { - return std::make_unique( - GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); + return std::make_unique(GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); } } diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index 43f25d817d..40aca0778c 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -32,7 +32,7 @@ class SmallSceneryPlaceActionResult final : public GameActionResult public: SmallSceneryPlaceActionResult() : GameActionResult(GA_ERROR::OK, STR_CANT_POSITION_THIS_HERE) - { + { } SmallSceneryPlaceActionResult(GA_ERROR error) : GameActionResult(error, STR_CANT_POSITION_THIS_HERE) @@ -193,7 +193,7 @@ public: { if (isOnWater) { - return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } if (surfaceElement != nullptr && surfaceElement->AsSurface()->GetWaterHeight() > 0) @@ -209,7 +209,7 @@ public: && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) && !supportsRequired && !isOnWater && surfaceElement != nullptr && (surfaceElement->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)) { - return std::make_unique(GA_ERROR::DISALLOWED, STR_LEVEL_LAND_REQUIRED); + return std::make_unique(GA_ERROR::DISALLOWED, STR_LEVEL_LAND_REQUIRED); } if (!gCheatsDisableSupportLimits && !(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_STACKABLE)) @@ -275,7 +275,8 @@ public: _loc.x, _loc.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags(), &clearCost, CREATE_CROSSING_MODE_NONE)) { - return std::make_unique(GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique( + GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); } res->GroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); @@ -312,7 +313,7 @@ public: rct_scenery_entry* sceneryEntry = get_small_scenery_entry(_sceneryType); if (sceneryEntry == nullptr) { - return std::make_unique(GA_ERROR::INVALID_PARAMETERS); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } auto quadrant = _quadrant; @@ -406,7 +407,8 @@ public: _loc.x, _loc.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, GetFlags() | GAME_COMMAND_FLAG_APPLY, &clearCost, CREATE_CROSSING_MODE_NONE)) { - return std::make_unique(GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique( + GA_ERROR::DISALLOWED, gGameCommandErrorText, gCommonFormatArgs); } res->GroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); From 0dfa079002dc65c1a2fb29aa0da17b54107924d2 Mon Sep 17 00:00:00 2001 From: Trevor Harkness Date: Fri, 19 Apr 2019 02:38:38 -0400 Subject: [PATCH 219/506] Fix remaining formatting issue Remaining formatting error adjusted in SmallSceneryPlaceAction for CI tests --- src/openrct2/actions/SmallSceneryPlaceAction.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index 40aca0778c..da3e4b501e 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -200,7 +200,8 @@ public: { if (static_cast((surfaceElement->AsSurface()->GetWaterHeight() * 16)) > targetHeight) { - return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } } } From 8035127acd3c1da5e07498bf3c7a88f2e3795b8c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 10 Apr 2019 18:45:54 +0100 Subject: [PATCH 220/506] Allocate banner index in the constructor. Note this does not fix the issue as ghosts still break placement --- .../actions/LargeSceneryPlaceAction.hpp | 39 ++++++++++---- src/openrct2/actions/WallPlaceAction.hpp | 51 ++++++++++++++----- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 80111a85cf..60796a24ca 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -26,6 +26,7 @@ private: uint8_t _sceneryType{ std::numeric_limits::max() }; uint8_t _primaryColour; uint8_t _secondaryColour; + BannerIndex _bannerId{ BANNER_INDEX_NULL }; public: LargeSceneryPlaceAction() = default; @@ -36,6 +37,14 @@ public: , _primaryColour(primaryColour) , _secondaryColour(secondaryColour) { + rct_scenery_entry* sceneryEntry = get_large_scenery_entry(_sceneryType); + if (sceneryEntry != nullptr) + { + if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) + { + _bannerId = create_new_banner(0); + } + } } uint16_t GetActionFlags() const override @@ -47,7 +56,8 @@ public: { GameAction::Serialise(stream); - stream << DS_TAG(_loc) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour); + stream << DS_TAG(_loc) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour) + << DS_TAG(_bannerId); } GameActionResult::Ptr Query() const override @@ -61,7 +71,6 @@ public: 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) @@ -97,9 +106,13 @@ public: if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) { - bannerId = create_new_banner(0); + if (_bannerId == BANNER_INDEX_NULL) + { + log_error("Banner Index not specified."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_POSITION_THIS_HERE); + } - if (bannerId == BANNER_INDEX_NULL) + if (gBanners[_bannerId].type != BANNER_NULL) { log_error("No free banners available"); return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); @@ -180,7 +193,6 @@ public: res->Position.z = surfaceHeight; gSceneryGroundFlags = 0; - BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; rct_scenery_entry* sceneryEntry = get_large_scenery_entry(_sceneryType); @@ -208,16 +220,23 @@ public: 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_TOO_MANY_BANNERS_IN_GAME, STR_CANT_POSITION_THIS_HERE); + } - if (bannerId == BANNER_INDEX_NULL) + if (gBanners[_bannerId].type != BANNER_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; + rct_banner* banner = &gBanners[_bannerId]; + banner->string_idx = STR_DEFAULT_SIGN; + banner->colour = 2; + banner->text_colour = 2; + banner->flags = BANNER_FLAG_IS_LARGE_SCENERY; banner->type = 0; banner->x = _loc.x / 32; banner->y = _loc.y / 32; @@ -278,7 +297,7 @@ public: newTileElement->clearance_height = zHigh; auto newSceneryElement = newTileElement->AsLargeScenery(); - SetNewLargeSceneryElement(*newSceneryElement, tileNum, bannerId); + SetNewLargeSceneryElement(*newSceneryElement, tileNum, _bannerId); if (tileNum == 0) { diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index e2c55ee387..12fd45d70d 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -32,6 +32,7 @@ private: int32_t _primaryColour; int32_t _secondaryColour; int32_t _tertiaryColour; + BannerIndex _bannerId{ BANNER_INDEX_NULL }; public: WallPlaceAction() @@ -47,6 +48,14 @@ public: , _secondaryColour(secondaryColour) , _tertiaryColour(tertiaryColour) { + rct_scenery_entry* sceneryEntry = get_wall_entry(_wallType); + if (sceneryEntry != nullptr) + { + if (sceneryEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) + { + _bannerId = create_new_banner(0); + } + } } uint16_t GetActionFlags() const override @@ -59,7 +68,7 @@ public: GameAction::Serialise(stream); stream << DS_TAG(_wallType) << DS_TAG(_loc) << DS_TAG(_edge) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour) - << DS_TAG(_tertiaryColour); + << DS_TAG(_tertiaryColour) << DS_TAG(_bannerId); } GameActionResult::Ptr Query() const override @@ -222,11 +231,17 @@ public: if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) { - auto bannerIndex = create_new_banner(0); - - if (bannerIndex == 0xFF) + if (_bannerId == BANNER_INDEX_NULL) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + log_error("Banner Index not specified."); + return MakeResult( + GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + if (gBanners[_bannerId].type != BANNER_NULL) + { + log_error("No free banners available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); } } @@ -297,7 +312,6 @@ public: } } - BannerIndex bannerIndex = BANNER_INDEX_NULL; rct_scenery_entry* wallEntry = get_wall_entry(_wallType); if (wallEntry == nullptr) @@ -308,15 +322,24 @@ public: if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) { - bannerIndex = create_new_banner(GAME_COMMAND_FLAG_APPLY); - - if (bannerIndex == 0xFF) + if (_bannerId == BANNER_INDEX_NULL) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + log_error("Banner Index not specified."); + return MakeResult( + GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_BUILD_PARK_ENTRANCE_HERE); } - rct_banner* banner = &gBanners[bannerIndex]; - banner->flags |= BANNER_FLAG_IS_WALL; + if (gBanners[_bannerId].type != BANNER_NULL) + { + log_error("No free banners available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + } + + rct_banner* banner = &gBanners[_bannerId]; + banner->string_idx = STR_DEFAULT_SIGN; + banner->colour = 2; + banner->text_colour = 2; + banner->flags = BANNER_FLAG_IS_WALL; banner->type = 0; banner->x = _loc.x / 32; banner->y = _loc.y / 32; @@ -372,9 +395,9 @@ public: } wallElement->SetEntryIndex(_wallType); - if (bannerIndex != 0xFF) + if (_bannerId != BANNER_INDEX_NULL) { - wallElement->SetBannerIndex(bannerIndex); + wallElement->SetBannerIndex(_bannerId); } if (wallEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) From 71af88fc5c85a9d5278c0b55f2373b094b983f0f Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Sat, 20 Apr 2019 14:47:45 +0200 Subject: [PATCH 221/506] Bump 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 94e737183d..074e8c8d2d 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 "18" +#define NETWORK_STREAM_VERSION "19" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 82c73e18c7ffba179db20e557f034e7c1ad262ed Mon Sep 17 00:00:00 2001 From: Liam Parker Date: Sun, 21 Apr 2019 02:10:15 +1000 Subject: [PATCH 222/506] Fix #9067 - Prices rendering in unlimited money game state --- contributors.md | 1 + src/openrct2-ui/windows/ClearScenery.cpp | 7 +-- src/openrct2-ui/windows/Land.cpp | 58 +++++++++++++----------- src/openrct2-ui/windows/LandRights.cpp | 6 +-- src/openrct2-ui/windows/Water.cpp | 22 +++++---- 5 files changed, 52 insertions(+), 42 deletions(-) diff --git a/contributors.md b/contributors.md index 9af5276289..e091a8a6a2 100644 --- a/contributors.md +++ b/contributors.md @@ -104,6 +104,7 @@ The following people are not part of the development team, but have been contrib * (telk5093) * Ethan Smith (ethanhs) - Refactor MAX_PATH * Robert Lewicki (rlewicki) +* Liam Parker (elInfidel) * Tyler Ruckinger (TyPR124) * Justin Gottula (jgottula) * Seongsik Park (pss9205) diff --git a/src/openrct2-ui/windows/ClearScenery.cpp b/src/openrct2-ui/windows/ClearScenery.cpp index 81f46e46ca..95360993af 100644 --- a/src/openrct2-ui/windows/ClearScenery.cpp +++ b/src/openrct2-ui/windows/ClearScenery.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include // clang-format off @@ -244,10 +245,10 @@ static void window_clear_scenery_paint(rct_window* w, rct_drawpixelinfo* dpi) } // Draw cost amount - x = (window_clear_scenery_widgets[WIDX_PREVIEW].left + window_clear_scenery_widgets[WIDX_PREVIEW].right) / 2 + w->x; - y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + w->y + 5 + 27; - if (gClearSceneryCost != MONEY32_UNDEFINED && gClearSceneryCost != 0) + if (gClearSceneryCost != MONEY32_UNDEFINED && gClearSceneryCost != 0 && !(gParkFlags & PARK_FLAGS_NO_MONEY)) { + x = (window_clear_scenery_widgets[WIDX_PREVIEW].left + window_clear_scenery_widgets[WIDX_PREVIEW].right) / 2 + w->x; + y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + w->y + 5 + 27; gfx_draw_string_centred(dpi, STR_COST_AMOUNT, x, y, COLOUR_BLACK, &gClearSceneryCost); } } diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index 83bf68207b..93dc64cc39 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -360,35 +360,39 @@ static void window_land_paint(rct_window* w, rct_drawpixelinfo* dpi) x = w->x + (previewWidget->left + previewWidget->right) / 2; y = w->y + previewWidget->bottom + 5; - // Draw raise cost amount - if (gLandToolRaiseCost != MONEY32_UNDEFINED && gLandToolRaiseCost != 0) - gfx_draw_string_centred(dpi, STR_RAISE_COST_AMOUNT, x, y, COLOUR_BLACK, &gLandToolRaiseCost); - y += 10; - - // Draw lower cost amount - if (gLandToolLowerCost != MONEY32_UNDEFINED && gLandToolLowerCost != 0) - gfx_draw_string_centred(dpi, STR_LOWER_COST_AMOUNT, x, y, COLOUR_BLACK, &gLandToolLowerCost); - y += 50; - - // Draw paint price - numTiles = gLandToolSize * gLandToolSize; - price = 0; - if (gLandToolTerrainSurface != 255) + if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) { - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( - objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, gLandToolTerrainSurface)); - if (surfaceObj != nullptr) + // Draw raise cost amount + if (gLandToolRaiseCost != MONEY32_UNDEFINED && gLandToolRaiseCost != 0) + gfx_draw_string_centred(dpi, STR_RAISE_COST_AMOUNT, x, y, COLOUR_BLACK, &gLandToolRaiseCost); + y += 10; + + // Draw lower cost amount + if (gLandToolLowerCost != MONEY32_UNDEFINED && gLandToolLowerCost != 0) + gfx_draw_string_centred(dpi, STR_LOWER_COST_AMOUNT, x, y, COLOUR_BLACK, &gLandToolLowerCost); + y += 50; + + // Draw paint price + numTiles = gLandToolSize * gLandToolSize; + price = 0; + if (gLandToolTerrainSurface != 255) { - price += numTiles * surfaceObj->Price; + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, gLandToolTerrainSurface)); + if (surfaceObj != nullptr) + { + price += numTiles * surfaceObj->Price; + } + } + + if (gLandToolTerrainEdge != 255) + price += numTiles * 100; + + if (price != 0) + { + set_format_arg(0, money32, price); + gfx_draw_string_centred(dpi, STR_COST_AMOUNT, x, y, COLOUR_BLACK, gCommonFormatArgs); } } - if (gLandToolTerrainEdge != 255) - price += numTiles * 100; - - if (price != 0 && !(gParkFlags & PARK_FLAGS_NO_MONEY)) - { - set_format_arg(0, money32, price); - gfx_draw_string_centred(dpi, STR_COST_AMOUNT, x, y, COLOUR_BLACK, gCommonFormatArgs); - } } diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index 1e3f5c9473..ff97ba56c3 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -281,10 +281,10 @@ static void window_land_rights_paint(rct_window* w, rct_drawpixelinfo* dpi) } // Draw cost amount - x = (window_land_rights_widgets[WIDX_PREVIEW].left + window_land_rights_widgets[WIDX_PREVIEW].right) / 2 + w->x; - y = window_land_rights_widgets[WIDX_PREVIEW].bottom + w->y + 32; - if (_landRightsCost != MONEY32_UNDEFINED && _landRightsCost != 0) + if (_landRightsCost != MONEY32_UNDEFINED && _landRightsCost != 0 && !(gParkFlags & PARK_FLAGS_NO_MONEY)) { + x = (window_land_rights_widgets[WIDX_PREVIEW].left + window_land_rights_widgets[WIDX_PREVIEW].right) / 2 + w->x; + y = window_land_rights_widgets[WIDX_PREVIEW].bottom + w->y + 32; gfx_draw_string_centred(dpi, STR_COST_AMOUNT, x, y, COLOUR_BLACK, &_landRightsCost); } } diff --git a/src/openrct2-ui/windows/Water.cpp b/src/openrct2-ui/windows/Water.cpp index afe55d8305..779bfab5bf 100644 --- a/src/openrct2-ui/windows/Water.cpp +++ b/src/openrct2-ui/windows/Water.cpp @@ -14,6 +14,7 @@ #include #include #include +#include // clang-format off enum WINDOW_WATER_WIDGET_IDX { @@ -220,14 +221,17 @@ static void window_water_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string_centred(dpi, STR_LAND_TOOL_SIZE_VALUE, x, y - 2, COLOUR_BLACK, &gLandToolSize); } - // Draw raise cost amount - x = (window_water_widgets[WIDX_PREVIEW].left + window_water_widgets[WIDX_PREVIEW].right) / 2 + w->x; - y = window_water_widgets[WIDX_PREVIEW].bottom + w->y + 5; - if (gWaterToolRaiseCost != MONEY32_UNDEFINED && gWaterToolRaiseCost != 0) - gfx_draw_string_centred(dpi, STR_RAISE_COST_AMOUNT, x, y, COLOUR_BLACK, &gWaterToolRaiseCost); - y += 10; + if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) + { + // Draw raise cost amount + x = (window_water_widgets[WIDX_PREVIEW].left + window_water_widgets[WIDX_PREVIEW].right) / 2 + w->x; + y = window_water_widgets[WIDX_PREVIEW].bottom + w->y + 5; + if (gWaterToolRaiseCost != MONEY32_UNDEFINED && gWaterToolRaiseCost != 0) + gfx_draw_string_centred(dpi, STR_RAISE_COST_AMOUNT, x, y, COLOUR_BLACK, &gWaterToolRaiseCost); + y += 10; - // Draw lower cost amount - if (gWaterToolLowerCost != MONEY32_UNDEFINED && gWaterToolLowerCost != 0) - gfx_draw_string_centred(dpi, STR_LOWER_COST_AMOUNT, x, y, COLOUR_BLACK, &gWaterToolLowerCost); + // Draw lower cost amount + if (gWaterToolLowerCost != MONEY32_UNDEFINED && gWaterToolLowerCost != 0) + gfx_draw_string_centred(dpi, STR_LOWER_COST_AMOUNT, x, y, COLOUR_BLACK, &gWaterToolLowerCost); + } } From abf416a5a9615d83f2762f104f49ff9d997d5309 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 20 Apr 2019 18:37:50 +0200 Subject: [PATCH 223/506] Fix string_to_money rounding errors in 4.10, 5.10... --- src/openrct2/localisation/Localisation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index 99ae0930be..fcaf9b28a6 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -34,6 +34,7 @@ #include #include #include +#include char gCommonStringFormatBuffer[512]; uint8_t gCommonFormatArgs[80]; @@ -1513,7 +1514,7 @@ money32 string_to_money(const char* string_to_monetise) auto number = std::stod(processedString, nullptr); number /= (currencyDesc->rate / 10.0); auto whole = static_cast(number); - auto fraction = static_cast((number - whole) * 100); + auto fraction = static_cast(ceil((number - whole) * 100.0)); money32 result = MONEY(whole, fraction); // Check if MONEY resulted in overflow From 28ad78f2047e23abbacbdc8d8b0098e205501f30 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 20 Apr 2019 18:42:06 +0200 Subject: [PATCH 224/506] Allow entry of numbers up to 10 million in string_to_money --- src/openrct2/localisation/Localisation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index fcaf9b28a6..b157518c7a 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -1513,7 +1513,7 @@ money32 string_to_money(const char* string_to_monetise) auto number = std::stod(processedString, nullptr); number /= (currencyDesc->rate / 10.0); - auto whole = static_cast(number); + auto whole = static_cast(number); auto fraction = static_cast(ceil((number - whole) * 100.0)); money32 result = MONEY(whole, fraction); From 8a4d90038dc0044d3318436ed909d06a5a3f1ddd Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 20 Apr 2019 18:43:02 +0200 Subject: [PATCH 225/506] Update changelog --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 100951106b..760b2d4194 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Fix: [#5579] Network desync immediately after connecting. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). +- Fix: [#7729] Money Input Prompt break on certain values. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#8219] Faulty folder recreation in "save" folder. From 60225211186788c4e404cb241d97ca20d2fea3df Mon Sep 17 00:00:00 2001 From: hokasha2016 <46494088+hokasha2016@users.noreply.github.com> Date: Sat, 20 Apr 2019 12:55:27 -0400 Subject: [PATCH 226/506] Fix #7871: String::StartsWith() returns true if source is shorter than match --- src/openrct2/core/String.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index 6406728e98..68da671696 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -184,9 +184,9 @@ namespace String { if (ignoreCase) { - while (*str != '\0' && *match != '\0') + while (*match != '\0') { - if (tolower(*str++) != tolower(*match++)) + if (*str == '\0' || tolower(*str++) != tolower(*match++)) { return false; } @@ -195,9 +195,9 @@ namespace String } else { - while (*str != '\0' && *match != '\0') + while (*match != '\0') { - if (*str++ != *match++) + if (*str == '\0' || *str++ != *match++) { return false; } From 61a402b913b2f8e13c7fb27e807c4253a571a919 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 20 Apr 2019 19:19:33 +0200 Subject: [PATCH 227/506] Fix formatting --- src/openrct2/localisation/Localisation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index b157518c7a..fa5f8e75d4 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -30,11 +30,11 @@ #include "Localisation.h" #include +#include #include #include #include #include -#include char gCommonStringFormatBuffer[512]; uint8_t gCommonFormatArgs[80]; From 42a1a8704d9f54ae2a5406c2475818e66af0d598 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 20 Apr 2019 20:39:47 +0200 Subject: [PATCH 228/506] Use empty() for vectors; clean up bool comparisons (#9118) --- .../drawing/engines/opengl/OpenGLDrawingEngine.cpp | 4 ++-- .../drawing/engines/opengl/TextureCache.cpp | 4 ++-- src/openrct2-ui/windows/EditorObjectSelection.cpp | 2 +- src/openrct2-ui/windows/Park.cpp | 2 +- src/openrct2-ui/windows/Staff.cpp | 4 ++-- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2-ui/windows/TrackList.cpp | 4 ++-- src/openrct2/Editor.cpp | 4 ++-- src/openrct2/Game.cpp | 2 +- src/openrct2/actions/FootpathPlaceAction.hpp | 2 +- src/openrct2/actions/GameAction.cpp | 6 +++--- src/openrct2/actions/LargeSceneryRemoveAction.hpp | 2 +- src/openrct2/actions/StaffHireNewAction.hpp | 4 ++-- src/openrct2/actions/TrackSetBrakeSpeedAction.hpp | 2 +- src/openrct2/interface/Viewport.cpp | 2 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/object/ObjectJsonHelpers.cpp | 4 ++-- src/openrct2/object/ObjectManager.cpp | 6 +++--- src/openrct2/paint/tile_element/Paint.Surface.cpp | 2 +- src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/peep/Staff.cpp | 6 +++--- src/openrct2/ride/CableLift.cpp | 4 ++-- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/Vehicle.cpp | 12 ++++++------ src/openrct2/scenario/Scenario.cpp | 2 +- src/openrct2/world/Footpath.cpp | 4 ++-- src/openrct2/world/MapGen.cpp | 6 +++--- src/openrct2/world/Park.cpp | 2 +- src/openrct2/world/TileElement.cpp | 2 +- test/testpaint/generate.cpp | 4 ++-- test/testpaint/main.cpp | 2 +- 31 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 7b79d116e6..7dfaac808e 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -881,7 +881,7 @@ void OpenGLDrawingContext::FlushCommandBuffers() void OpenGLDrawingContext::FlushLines() { - if (_commandBuffers.lines.size() == 0) + if (_commandBuffers.lines.empty()) return; _drawLineShader->Use(); @@ -892,7 +892,7 @@ void OpenGLDrawingContext::FlushLines() void OpenGLDrawingContext::FlushRectangles() { - if (_commandBuffers.rects.size() == 0) + if (_commandBuffers.rects.empty()) return; OpenGLAPI::SetTexture(0, GL_TEXTURE_2D_ARRAY, _textureCache->GetAtlasesTexture()); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 3c9eb8d86c..65b2f09459 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -197,7 +197,7 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) { // Retrieve current array data, growing buffer. oldPixels.resize(_atlasesTextureDimensions * _atlasesTextureDimensions * _atlasesTextureCapacity); - if (oldPixels.size() > 0) + if (!oldPixels.empty()) { glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data()); } @@ -212,7 +212,7 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries) GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr); // Restore old data - if (oldPixels.size() > 0) + if (!oldPixels.empty()) { glTexSubImage3D( GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, _atlasesTextureDimensions, _atlasesTextureDimensions, _atlasesTextureIndices, diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 6781550df1..d751d2b33f 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -324,7 +324,7 @@ static void visible_list_refresh(rct_window* w) } } - if (_listItems.size() == 0) + if (_listItems.empty()) { visible_list_dispose(); } diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index 060ed9ba2e..4042c34dc5 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -876,7 +876,7 @@ static void window_park_init_viewport(rct_window* w) if (w->page != WINDOW_PARK_PAGE_ENTRANCE) return; - if (gParkEntrances.size() > 0) + if (!gParkEntrances.empty()) { const auto& entrance = gParkEntrances[0]; x = entrance.x + 16; diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 4cd448f91b..6758034a3d 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -1218,7 +1218,7 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, if (peep.type != PEEP_TYPE_STAFF) return; - if (staff_is_patrol_area_set(peep.staff_id, dest_x, dest_y) == true) + if (staff_is_patrol_area_set(peep.staff_id, dest_x, dest_y)) { _staffPatrolAreaPaintValue = PatrolAreaValue::UNSET; } @@ -1260,7 +1260,7 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex, return; bool patrolAreaValue = staff_is_patrol_area_set(peep.staff_id, dest_x, dest_y); - if (_staffPatrolAreaPaintValue == PatrolAreaValue::SET && patrolAreaValue == true) + if (_staffPatrolAreaPaintValue == PatrolAreaValue::SET && patrolAreaValue) return; // Since area is already the value we want, skip... if (_staffPatrolAreaPaintValue == PatrolAreaValue::UNSET && patrolAreaValue == false) return; // Since area is already the value we want, skip... diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 7ad88c914d..6cd585c95a 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1758,7 +1758,7 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo } // Actually place - if (success == GA_ERROR::OK || ((q + 1 == quantity) && (forceError == true))) + if (success == GA_ERROR::OK || ((q + 1 == quantity) && forceError)) { auto smallSceneryPlaceAction = SmallSceneryPlaceAction( { cur_grid_x, cur_grid_y, gSceneryPlaceZ, gSceneryPlaceRotation }, quadrant, type, primaryColour, diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index 0f574a7aee..ea9d93a13d 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -499,7 +499,7 @@ static void window_track_list_paint(rct_window* w, rct_drawpixelinfo* dpi) int32_t listItemIndex = w->selected_list_item; if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { - if (_trackDesigns.size() == 0 || listItemIndex == -1) + if (_trackDesigns.empty() || listItemIndex == -1) return; } else @@ -718,7 +718,7 @@ static void window_track_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, size_t listIndex = 0; if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { - if (_trackDesigns.size() == 0) + if (_trackDesigns.empty()) { // No track designs gfx_draw_string_left(dpi, STR_NO_TRACK_DESIGNS_OF_THIS_TYPE, nullptr, COLOUR_BLACK, x, y - 1); diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 02c54eb959..511cb2491b 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -491,7 +491,7 @@ namespace Editor return false; } - if (gParkEntrances.size() == 0) + if (gParkEntrances.empty()) { gGameCommandErrorText = STR_NO_PARK_ENTRANCES; return false; @@ -520,7 +520,7 @@ namespace Editor } } - if (gPeepSpawns.size() == 0) + if (gPeepSpawns.empty()) { gGameCommandErrorText = STR_PEEP_SPAWNS_NOT_SET; return false; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 6f6470aee0..1b289cd05e 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -836,7 +836,7 @@ void game_fix_save_vars() } } - if (peepsToRemove.size() > 0) + if (!peepsToRemove.empty()) { // Some broken saves have broken spatial indexes reset_sprite_spatial_index(); diff --git a/src/openrct2/actions/FootpathPlaceAction.hpp b/src/openrct2/actions/FootpathPlaceAction.hpp index c52f73b337..be47524587 100644 --- a/src/openrct2/actions/FootpathPlaceAction.hpp +++ b/src/openrct2/actions/FootpathPlaceAction.hpp @@ -399,7 +399,7 @@ private: } } - if (gPeepSpawns.size() == 0) + if (gPeepSpawns.empty()) { gPeepSpawns.emplace_back(); } diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index b7e078d671..036f8aab3f 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -131,7 +131,7 @@ namespace GameActions Guard::ArgumentNotNull(action); uint16_t actionFlags = action->GetActionFlags(); - if (topLevel == true && !CheckActionInPausedMode(actionFlags)) + if (topLevel && !CheckActionInPausedMode(actionFlags)) { GameActionResult::Ptr result = std::make_unique(); @@ -358,7 +358,7 @@ namespace GameActions } // Only show errors when its not a ghost and not a preview and also top level action. - bool shouldShowError = !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND) && topLevel == true; + bool shouldShowError = !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND) && topLevel; // In network mode the error should be only shown to the issuer of the action. if (network_get_mode() != NETWORK_MODE_NONE) @@ -369,7 +369,7 @@ namespace GameActions } } - if (result->Error != GA_ERROR::OK && shouldShowError == true) + if (result->Error != GA_ERROR::OK && shouldShowError) { // Show the error box std::copy(result->ErrorMessageArgs.begin(), result->ErrorMessageArgs.end(), gCommonFormatArgs); diff --git a/src/openrct2/actions/LargeSceneryRemoveAction.hpp b/src/openrct2/actions/LargeSceneryRemoveAction.hpp index 7d2f567c01..b51adab4b3 100644 --- a/src/openrct2/actions/LargeSceneryRemoveAction.hpp +++ b/src/openrct2/actions/LargeSceneryRemoveAction.hpp @@ -121,7 +121,7 @@ public: } } - if (calculate_cost == true) + if (calculate_cost) res->Cost = scenery_entry->large_scenery.removal_price * 10; return res; diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index 78b98255d2..3051ab21dd 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -225,7 +225,7 @@ private: newPeep->sprite_height_negative = spriteBounds->sprite_height_negative; newPeep->sprite_height_positive = spriteBounds->sprite_height_positive; - if (_autoPosition == true) + if (_autoPosition) { AutoPositionNewStaff(newPeep); } @@ -320,7 +320,7 @@ private: else { // No walking guests; pick random park entrance - if (gParkEntrances.size() > 0) + if (!gParkEntrances.empty()) { auto rand = scenario_rand_max((uint32_t)gParkEntrances.size()); const auto& entrance = gParkEntrances[rand]; diff --git a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp index 297f2fd565..e1d671099c 100644 --- a/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp +++ b/src/openrct2/actions/TrackSetBrakeSpeedAction.hpp @@ -66,7 +66,7 @@ private: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - if (isExecuting == true) + if (isExecuting) { tileElement->AsTrack()->SetBrakeBoosterSpeed(_brakeSpeed); } diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 5ecf915dba..c77029438e 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -922,7 +922,7 @@ void viewport_paint( if (window_get_main() != nullptr && viewport != window_get_main()->viewport) useMultithreading = false; - if (useMultithreading == true && _paintJobs == nullptr) + if (useMultithreading && _paintJobs == nullptr) { _paintJobs = std::make_unique(); } diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 32a355c775..371db95100 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -2109,7 +2109,7 @@ void Network::RemoveClient(std::unique_ptr& connection) [connection_player](std::unique_ptr& player) { return player.get() == connection_player; }), player_list.end()); client_connection_list.remove(connection); - if (gConfigNetwork.pause_server_if_no_clients && game_is_not_paused() && client_connection_list.size() == 0) + if (gConfigNetwork.pause_server_if_no_clients && game_is_not_paused() && client_connection_list.empty()) { auto pauseToggleAction = PauseToggleAction(); GameActions::Execute(&pauseToggleAction); diff --git a/src/openrct2/object/ObjectJsonHelpers.cpp b/src/openrct2/object/ObjectJsonHelpers.cpp index d6c50ce969..cb14ae7a72 100644 --- a/src/openrct2/object/ObjectJsonHelpers.cpp +++ b/src/openrct2/object/ObjectJsonHelpers.cpp @@ -366,7 +366,7 @@ namespace ObjectJsonHelpers if (is_csg_loaded()) { auto range = ParseRange(s.substr(4)); - if (range.size() > 0) + if (!range.empty()) { for (auto i : range) { @@ -380,7 +380,7 @@ namespace ObjectJsonHelpers else if (String::StartsWith(s, "$G1")) { auto range = ParseRange(s.substr(3)); - if (range.size() > 0) + if (!range.empty()) { for (auto i : range) { diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 74838cc118..0cbe3cac9b 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -329,7 +329,7 @@ private: void SetNewLoadedObjectList(const std::vector& newLoadedObjects) { - if (newLoadedObjects.size() == 0) + if (newLoadedObjects.empty()) { UnloadAll(); } @@ -530,7 +530,7 @@ private: requiredObjects.push_back(ori); } - if (missingObjects.size() > 0) + if (!missingObjects.empty()) { throw ObjectLoadException(std::move(missingObjects)); } @@ -605,7 +605,7 @@ private: obj->Load(); } - if (badObjects.size() > 0) + if (!badObjects.empty()) { // Unload all the new objects we loaded for (auto object : loadedObjects) diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 9a74e4e411..e6d6a3b4a6 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -668,7 +668,7 @@ static void viewport_surface_draw_tile_side_bottom( tunnelIndex++; } - if (isWater == true || curHeight != tunnelArray[tunnelIndex].height) + if (isWater || curHeight != tunnelArray[tunnelIndex].height) { sub_98196C(session, base_image_id, offset.x, offset.y, bounds.x, bounds.y, 15, curHeight * 16); diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 498c4e5c01..e771e9ab2e 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -2736,7 +2736,7 @@ static void peep_footpath_move_forward(Peep* peep, int16_t x, int16_t y, TileEle // Advance the vandalised tiles by 1 uint8_t vandalisedTiles = (peep->vandalism_seen * 2) & 0x3F; - if (vandalism == true) + if (vandalism) { // Add one more to the vandalised tiles vandalisedTiles |= 1; diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 06e2e51c47..e4e19caaba 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -644,7 +644,7 @@ static bool staff_path_finding_handyman(Peep* peep) } } - if (chooseRandom == true) + if (chooseRandom) { do { @@ -701,10 +701,10 @@ static uint8_t staff_direction_surface(Peep* peep, uint8_t initialDirection) direction &= 3; - if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction) == true) + if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction)) continue; - if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction_reverse(direction)) == true) + if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction_reverse(direction))) continue; LocationXY16 chosenTile = { static_cast(peep->next_x + CoordsDirectionDelta[direction].x), diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index d332669938..9f670c498f 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -423,7 +423,7 @@ int32_t cable_lift_update_track_motion(rct_vehicle* cableLift) { if (vehicle->remaining_distance < 0) { - if (sub_6DF21B_loop(vehicle) == true) + if (sub_6DF21B_loop(vehicle)) { break; } @@ -439,7 +439,7 @@ int32_t cable_lift_update_track_motion(rct_vehicle* cableLift) } else { - if (sub_6DF01A_loop(vehicle) == true) + if (sub_6DF01A_loop(vehicle)) { break; } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 3a951724ac..b68ceb2c7d 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7362,7 +7362,7 @@ void sub_6CB945(Ride* ride) shouldRemove = false; } while (!(trackElement++)->IsLastForTile()); - if (shouldRemove == true) + if (shouldRemove) { footpath_queue_chain_reset(); maze_entrance_hedge_replacement(location.x, location.y, tileElement); diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index de890e09c5..e8a5667533 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2499,7 +2499,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) } bool skipCheck = false; - if (shouldBreak == true || ride->status != RIDE_STATUS_OPEN) + if (shouldBreak || ride->status != RIDE_STATUS_OPEN) { if (ride->mode == RIDE_MODE_FORWARD_ROTATION || ride->mode == RIDE_MODE_BACKWARD_ROTATION) { @@ -3756,7 +3756,7 @@ static void vehicle_update_travelling(rct_vehicle* vehicle) } else { - if (vehicle_current_tower_element_is_top(vehicle) == true) + if (vehicle_current_tower_element_is_top(vehicle)) { vehicle->velocity = 0; vehicle->sub_state = 2; @@ -4665,7 +4665,7 @@ static bool vehicle_boat_is_location_accessible(const TileCoordsXYZ& location) TileElement* tileElement = map_get_first_element_at(location.x, location.y); do { - if (tileElement->IsGhost() == true) + if (tileElement->IsGhost()) continue; if (tileElement->GetType() == TILE_ELEMENT_TYPE_SURFACE) @@ -4940,7 +4940,7 @@ static void vehicle_update_rotating(rct_vehicle* vehicle) shouldStop = false; } - if (shouldStop == true) + if (shouldStop) { if (vehicle->sub_state == 2) { @@ -7755,7 +7755,7 @@ static bool vehicle_update_motion_collision_detection( break; } } - if (mayCollide == true) + if (mayCollide) { break; } @@ -8407,7 +8407,7 @@ static bool vehicle_update_track_motion_backwards_get_new_track( break; } - if (nextTileBackwards == true) + if (nextTileBackwards) { // loc_6DBB7E:; track_begin_end trackBeginEnd; diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index ea10290d3d..83b84aca80 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -238,7 +238,7 @@ static void scenario_entrance_fee_too_high_check() if ((gParkFlags & PARK_FLAGS_PARK_OPEN) && park_get_entrance_fee() > max_fee) { - if (gParkEntrances.size() > 0) + if (!gParkEntrances.empty()) { const auto& entrance = gParkEntrances[0]; auto x = entrance.x + 16; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index b734b1cef0..95b08537fe 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1469,7 +1469,7 @@ bool PathElement::IsBroken() const void PathElement::SetIsBroken(bool isBroken) { - if (isBroken == true) + if (isBroken) { flags |= TILE_ELEMENT_FLAG_BROKEN; } @@ -1486,7 +1486,7 @@ bool PathElement::IsBlockedByVehicle() const void PathElement::SetIsBlockedByVehicle(bool isBlocked) { - if (isBlocked == true) + if (isBlocked) { flags |= TILE_ELEMENT_FLAG_BLOCKED_BY_VEHICLE; } diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index f8e535872e..33dbba1254 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -354,7 +354,7 @@ static void mapgen_place_trees() case TERRAIN_GRASS: case TERRAIN_DIRT: case TERRAIN_GRASS_CLUMPS: - if (grassTreeIds.size() == 0) + if (grassTreeIds.empty()) break; type = grassTreeIds[util_rand() % grassTreeIds.size()]; @@ -363,7 +363,7 @@ static void mapgen_place_trees() case TERRAIN_SAND: case TERRAIN_SAND_DARK: case TERRAIN_SAND_LIGHT: - if (desertTreeIds.size() == 0) + if (desertTreeIds.empty()) break; if (util_rand() % 4 == 0) @@ -371,7 +371,7 @@ static void mapgen_place_trees() break; case TERRAIN_ICE: - if (snowTreeIds.size() == 0) + if (snowTreeIds.empty()) break; type = snowTreeIds[util_rand() % snowTreeIds.size()]; diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index a4f8b51911..24ec7fa829 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -95,7 +95,7 @@ void reset_park_entry() */ static PeepSpawn* get_random_peep_spawn() { - if (gPeepSpawns.size() > 0) + if (!gPeepSpawns.empty()) { return &gPeepSpawns[scenario_rand() % gPeepSpawns.size()]; } diff --git a/src/openrct2/world/TileElement.cpp b/src/openrct2/world/TileElement.cpp index 4b42addf0b..09172082a8 100644 --- a/src/openrct2/world/TileElement.cpp +++ b/src/openrct2/world/TileElement.cpp @@ -56,7 +56,7 @@ bool TileElementBase::IsGhost() const void TileElementBase::SetGhost(bool isGhost) { - if (isGhost == true) + if (isGhost) { this->flags |= TILE_ELEMENT_FLAG_GHOST; } diff --git a/test/testpaint/generate.cpp b/test/testpaint/generate.cpp index dc06733518..28cd40dfee 100644 --- a/test/testpaint/generate.cpp +++ b/test/testpaint/generate.cpp @@ -606,7 +606,7 @@ private: WriteLine(tabs, "switch (direction) {"); for (int direction = 0; direction < 4; direction++) { - if (calls[direction].size() == 0) + if (calls[direction].empty()) continue; WriteLine(tabs, "case %d:", direction); @@ -720,7 +720,7 @@ private: function_call lastCall = calls[0].back(); for (int i = 0; i < 4; i++) { - if (calls[i].size() == 0 || !CompareFunctionCall(calls[i].back(), lastCall)) + if (calls[i].empty() || !CompareFunctionCall(calls[i].back(), lastCall)) { goto finished; } diff --git a/test/testpaint/main.cpp b/test/testpaint/main.cpp index 11328c5aca..ffa0666d71 100644 --- a/test/testpaint/main.cpp +++ b/test/testpaint/main.cpp @@ -620,7 +620,7 @@ int main(int argc, char* argv[]) Write(Verbosity::QUIET, CLIColour::GREEN, "[ PASSED ] "); Write(Verbosity::QUIET, "%d tests.\n", successCount); - if (failures.size() > 0) + if (!failures.empty()) { Write(Verbosity::QUIET, CLIColour::RED, "[ FAILED ] "); Write(Verbosity::QUIET, "%d tests, listed below:\n", (int)failures.size()); From 7f473a791cfb29db849854ce30ea03ac7de970de Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 20 Apr 2019 21:59:52 +0200 Subject: [PATCH 229/506] Fix typo Co-Authored-By: Gymnasiast --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 760b2d4194..865c11bf0f 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,7 +7,7 @@ - Fix: [#5579] Network desync immediately after connecting. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). -- Fix: [#7729] Money Input Prompt break on certain values. +- Fix: [#7729] Money Input Prompt breaks on certain values. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#8219] Faulty folder recreation in "save" folder. From 5a906b2378e594734f84d4a30528867c13ef650d Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 20 Apr 2019 22:22:39 +0200 Subject: [PATCH 230/506] Port more functions to Ride struct (#9119) --- src/openrct2-ui/windows/Ride.cpp | 34 ++-- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2-ui/windows/RideList.cpp | 8 +- src/openrct2/GameState.cpp | 2 +- src/openrct2/actions/LandSetHeightAction.hpp | 2 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/ride/Ride.cpp | 197 +++++++++---------- src/openrct2/ride/Ride.h | 28 ++- src/openrct2/ride/thrill/MagicCarpet.cpp | 2 +- src/openrct2/ride/thrill/MotionSimulator.cpp | 2 +- test/testpaint/Compat.cpp | 8 +- 11 files changed, 147 insertions(+), 140 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index b6bd0aa8ba..cb9f553c71 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1320,7 +1320,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo* dpi, rct_window* w) Ride* ride = get_ride(w->number); - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); if (rideEntry->flags & RIDE_ENTRY_FLAG_VEHICLE_TAB_SCALE_HALF) { clipDPI.zoom_level = 1; @@ -1856,7 +1856,7 @@ static void window_ride_init_viewport(rct_window* w) { focus.sprite.sprite_id = ride->vehicles[eax]; - rct_ride_entry* ride_entry = get_ride_entry_by_ride(ride); + rct_ride_entry* ride_entry = ride->GetRideEntry(); if (ride_entry && ride_entry->tab_vehicle != 0) { rct_vehicle* vehicle = GET_VEHICLE(focus.sprite.sprite_id); @@ -2250,7 +2250,7 @@ static void window_ride_show_ride_type_dropdown(rct_window* w, rct_widget* widge static void populate_vehicle_type_dropdown(Ride* ride) { - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); bool selectionShouldBeExpanded; int32_t rideTypeIterator, rideTypeIteratorMax; @@ -2882,7 +2882,7 @@ static void window_ride_vehicle_mousedown(rct_window* w, rct_widgetindex widgetI ride->SetNumCarsPerVehicle(ride->num_cars_per_train + 1); break; case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE: - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); if (ride->num_cars_per_train > rideEntry->zero_cars + 1) ride->SetNumCarsPerVehicle(ride->num_cars_per_train - 1); break; @@ -2947,7 +2947,7 @@ static void window_ride_vehicle_invalidate(rct_window* w) window_ride_set_pressed_tab(w); ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); set_format_arg(0, rct_string_id, ride->name); set_format_arg(2, uint32_t, ride->name_arguments); @@ -3042,7 +3042,7 @@ static void window_ride_vehicle_paint(rct_window* w, rct_drawpixelinfo* dpi) window_ride_draw_tab_images(dpi, w); ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); x = w->x + 8; y = w->y + 64; @@ -3104,7 +3104,7 @@ static rct_vehicle_paintinfo _sprites_to_draw[144]; static void window_ride_vehicle_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex) { Ride* ride = get_ride(w->number); - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); // Background gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height, PALETTE_INDEX_12); @@ -3534,7 +3534,7 @@ static void window_ride_operating_invalidate(rct_window* w) } // Number of circuits - if (ride_can_have_multiple_circuits(ride)) + if (ride->CanHaveMultipleCircuits()) { window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_LABEL].type = WWT_LABEL; window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS].type = WWT_SPINNER; @@ -4364,7 +4364,7 @@ static void window_ride_colour_mousedown(rct_window* w, rct_widgetindex widgetIn rct_string_id stringId; ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); colourSchemeIndex = w->ride_colour; dropdownWidget = widget - 1; @@ -4633,7 +4633,7 @@ static void window_ride_colour_invalidate(rct_window* w) window_ride_set_pressed_tab(w); ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); set_format_arg(0, rct_string_id, ride->name); set_format_arg(2, uint32_t, ride->name_arguments); @@ -4849,7 +4849,7 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi) rct_ride_entry* rideEntry; ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); window_draw_widgets(w, dpi); window_ride_draw_tab_images(dpi, w); @@ -4958,7 +4958,7 @@ static void window_ride_colour_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi vehicle_colour vehicleColour; ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); vehiclePreviewWidget = &window_ride_colour_widgets[WIDX_VEHICLE_PREVIEW]; vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex); @@ -6465,7 +6465,7 @@ static void window_ride_income_invalidate(rct_window* w) set_format_arg(0, rct_string_id, ride->name); set_format_arg(2, uint32_t, ride->name_arguments); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); // Primary item w->pressed_widgets &= ~(1 << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK); @@ -6563,7 +6563,7 @@ static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi) window_ride_draw_tab_images(dpi, w); ride = get_ride(w->number); - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); x = w->x + window_ride_income_widgets[WIDX_PAGE_BACKGROUND].left + 4; y = w->y + window_ride_income_widgets[WIDX_PAGE_BACKGROUND].top + 33; @@ -6820,14 +6820,14 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) // Queue time if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) { - queueTime = ride_get_max_queue_time(ride); + queueTime = ride->GetMaxQueueTime(); stringId = queueTime == 1 ? STR_QUEUE_TIME_MINUTE : STR_QUEUE_TIME_MINUTES; y += gfx_draw_string_left_wrapped(dpi, &queueTime, x, y, 308, stringId, COLOUR_BLACK); y += 5; } // Primary shop items sold - shopItem = get_ride_entry_by_ride(ride)->shop_item; + shopItem = ride->GetRideEntry()->shop_item; if (shopItem != SHOP_ITEM_NONE) { set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural); @@ -6838,7 +6838,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) // Secondary shop items sold / on-ride photos sold shopItem = (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) ? RidePhotoItems[ride->type] - : get_ride_entry_by_ride(ride)->shop_item_secondary; + : ride->GetRideEntry()->shop_item_secondary; if (shopItem != SHOP_ITEM_NONE) { set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural); diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 92386480ee..2c62047cc4 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2526,7 +2526,7 @@ void window_ride_construction_update_active_elements_impl() void window_ride_construction_update_enabled_track_pieces() { Ride* ride = get_ride(_currentRideIndex); - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); int32_t rideType = (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE) ? RideData4[ride->type].alternate_type : ride->type; diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index 79f834af15..4c5f5491f3 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -695,7 +695,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, } break; case INFORMATION_TYPE_QUEUE_LENGTH: - set_format_arg(2, uint16_t, ride_get_total_queue_length(ride)); + set_format_arg(2, uint16_t, ride->GetTotalQueueLength()); formatSecondary = STR_QUEUE_EMPTY; { uint16_t arg; @@ -708,7 +708,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, } break; case INFORMATION_TYPE_QUEUE_TIME: - set_format_arg(2, uint16_t, ride_get_max_queue_time(ride)); + set_format_arg(2, uint16_t, ride->GetMaxQueueTime()); formatSecondary = STR_QUEUE_TIME_LABEL; { uint16_t arg; @@ -906,7 +906,7 @@ void window_ride_list_refresh_list(rct_window* w) while (--current_list_position >= 0) { otherRide = get_ride(w->list_item_positions[current_list_position]); - if (ride_get_total_queue_length(ride) <= ride_get_total_queue_length(otherRide)) + if (ride->GetTotalQueueLength() <= otherRide->GetTotalQueueLength()) break; window_bubble_list_item(w, current_list_position); @@ -916,7 +916,7 @@ void window_ride_list_refresh_list(rct_window* w) while (--current_list_position >= 0) { otherRide = get_ride(w->list_item_positions[current_list_position]); - if (ride_get_max_queue_time(ride) <= ride_get_max_queue_time(otherRide)) + if (ride->GetMaxQueueTime() <= otherRide->GetMaxQueueTime()) break; window_bubble_list_item(w, current_list_position); diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index a48456911d..fc4544aa59 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -260,7 +260,7 @@ void GameState::UpdateLogic() map_restore_provisional_elements(); vehicle_update_all(); sprite_misc_update_all(); - ride_update_all(); + Ride::UpdateAll(); if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { diff --git a/src/openrct2/actions/LandSetHeightAction.hpp b/src/openrct2/actions/LandSetHeightAction.hpp index ab8eab6f79..e3fd2d4ceb 100644 --- a/src/openrct2/actions/LandSetHeightAction.hpp +++ b/src/openrct2/actions/LandSetHeightAction.hpp @@ -260,7 +260,7 @@ private: Ride* ride = get_ride(rideIndex); if (ride != nullptr) { - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); if (rideEntry != nullptr) { int32_t maxHeight = rideEntry->max_height; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 38d863bf43..6d19e463a0 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -3736,7 +3736,7 @@ static void peep_update_ride_no_free_vehicle_rejoin_queue(Peep* peep, Ride* ride peep->SetState(PEEP_STATE_QUEUING_FRONT); peep->sub_state = PEEP_RIDE_AT_ENTRANCE; - ride_queue_insert_guest_at_front(ride, peep->current_ride_station, peep); + ride->QueueInsertGuestAtFront(peep->current_ride_station, peep); } /** diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index b68ceb2c7d..d748958c1b 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -205,7 +205,6 @@ static void ride_breakdown_status_update(Ride* ride); static void ride_breakdown_update(Ride* ride); static void ride_call_closest_mechanic(Ride* ride); static void ride_call_mechanic(Ride* ride, Peep* mechanic, int32_t forInspection); -static void ride_chairlift_update(Ride* ride); static void ride_entrance_exit_connected(Ride* ride); static void ride_set_name_to_vehicle_default(Ride* ride, rct_ride_entry* rideEntry); static int32_t ride_get_new_breakdown_problem(Ride* ride); @@ -213,8 +212,6 @@ static void ride_inspection_update(Ride* ride); static void ride_mechanic_status_update(Ride* ride, int32_t mechanicStatus); static void ride_music_update(Ride* ride); static void ride_shop_connected(Ride* ride); -static void ride_spiral_slide_update(Ride* ride); -static void ride_update(Ride* ride); void loc_6DDF9C(Ride* ride, TileElement* tileElement); Ride* get_ride(int32_t index) @@ -263,16 +260,16 @@ rct_ride_measurement* get_ride_measurement(int32_t index) return &gRideMeasurements[index]; } -rct_ride_entry* get_ride_entry_by_ride(const Ride* ride) +rct_ride_entry* Ride::GetRideEntry() const { - rct_ride_entry* type = get_ride_entry(ride->subtype); - if (type == nullptr) + rct_ride_entry* rideEntry = get_ride_entry(subtype); + if (rideEntry == nullptr) { char oldname[128]; - format_string(oldname, 128, ride->name, &ride->name_arguments); + format_string(oldname, 128, name, &name_arguments); log_error("Invalid ride subtype for ride %s", oldname); } - return type; + return rideEntry; } /** @@ -344,29 +341,29 @@ int32_t ride_get_count() return count; } -int32_t ride_get_total_queue_length(Ride* ride) +int32_t Ride::GetTotalQueueLength() const { int32_t i, queueLength = 0; for (i = 0; i < MAX_STATIONS; i++) - if (!ride_get_entrance_location(ride, i).isNull()) - queueLength += ride->stations[i].QueueLength; + if (!ride_get_entrance_location(this, i).isNull()) + queueLength += stations[i].QueueLength; return queueLength; } -int32_t ride_get_max_queue_time(Ride* ride) +int32_t Ride::GetMaxQueueTime() const { uint8_t i, queueTime = 0; for (i = 0; i < MAX_STATIONS; i++) - if (!ride_get_entrance_location(ride, i).isNull()) - queueTime = std::max(queueTime, ride->stations[i].QueueTime); + if (!ride_get_entrance_location(this, i).isNull()) + queueTime = std::max(queueTime, stations[i].QueueTime); return (int32_t)queueTime; } -Peep* ride_get_queue_head_guest(Ride* ride, int32_t stationIndex) +Peep* Ride::GetQueueHeadGuest(int32_t stationIndex) const { Peep* peep; Peep* result = nullptr; - uint16_t spriteIndex = ride->stations[stationIndex].LastPeepInQueue; + uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; while ((peep = try_get_guest(spriteIndex)) != nullptr) { spriteIndex = peep->next_in_queue; @@ -375,36 +372,35 @@ Peep* ride_get_queue_head_guest(Ride* ride, int32_t stationIndex) return result; } -static void ride_update_queue_length(Ride* ride, int32_t stationIndex) +void Ride::UpdateQueueLength(int32_t stationIndex) { uint16_t count = 0; Peep* peep; - uint16_t spriteIndex = ride->stations[stationIndex].LastPeepInQueue; + uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; while ((peep = try_get_guest(spriteIndex)) != nullptr) { spriteIndex = peep->next_in_queue; count++; } - ride->stations[stationIndex].QueueLength = count; + stations[stationIndex].QueueLength = count; } -void ride_queue_insert_guest_at_front(Ride* ride, int32_t stationIndex, Peep* peep) +void Ride::QueueInsertGuestAtFront(int32_t stationIndex, Peep* peep) { - assert(ride != nullptr); assert(stationIndex < MAX_STATIONS); assert(peep != nullptr); peep->next_in_queue = SPRITE_INDEX_NULL; - Peep* queueHeadGuest = ride_get_queue_head_guest(ride, peep->current_ride_station); + Peep* queueHeadGuest = GetQueueHeadGuest(peep->current_ride_station); if (queueHeadGuest == nullptr) { - ride->stations[peep->current_ride_station].LastPeepInQueue = peep->sprite_index; + stations[peep->current_ride_station].LastPeepInQueue = peep->sprite_index; } else { queueHeadGuest->next_in_queue = peep->sprite_index; } - ride_update_queue_length(ride, peep->current_ride_station); + UpdateQueueLength(peep->current_ride_station); } /** @@ -440,16 +436,16 @@ void ride_update_favourited_stat() * * rct2: 0x006AC3AB */ -static money32 ride_calculate_income_per_hour(Ride* ride) +money32 Ride::CalculateIncomePerHour() const { // Get entry by ride to provide better reporting - rct_ride_entry* entry = get_ride_entry_by_ride(ride); + rct_ride_entry* entry = GetRideEntry(); if (entry == nullptr) { return 0; } - money32 customersPerHour = ride_customers_per_hour(ride); - money32 priceMinusCost = ride_get_price(ride); + money32 customersPerHour = ride_customers_per_hour(this); + money32 priceMinusCost = ride_get_price(this); int32_t currentShopItem = entry->shop_item; if (currentShopItem != SHOP_ITEM_NONE) @@ -457,12 +453,11 @@ static money32 ride_calculate_income_per_hour(Ride* ride) priceMinusCost -= get_shop_item_cost(currentShopItem); } - currentShopItem = (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) ? RidePhotoItems[ride->type] - : entry->shop_item_secondary; + currentShopItem = (lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) ? RidePhotoItems[type] : entry->shop_item_secondary; if (currentShopItem != SHOP_ITEM_NONE) { - priceMinusCost += ride->price_secondary; + priceMinusCost += price_secondary; priceMinusCost -= get_shop_item_cost(currentShopItem); if (entry->shop_item != SHOP_ITEM_NONE) @@ -953,23 +948,23 @@ int32_t ride_get_total_time(Ride* ride) return totalTime; } -int32_t ride_can_have_multiple_circuits(Ride* ride) +bool Ride::CanHaveMultipleCircuits() const { - if (!(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_MULTIPLE_CIRCUITS)) - return 0; + if (!(RideData4[type].flags & RIDE_TYPE_FLAG4_ALLOW_MULTIPLE_CIRCUITS)) + return false; // Only allow circuit or launch modes - if (ride->mode != RIDE_MODE_CONTINUOUS_CIRCUIT && ride->mode != RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE - && ride->mode != RIDE_MODE_POWERED_LAUNCH_PASSTROUGH) + if (mode != RIDE_MODE_CONTINUOUS_CIRCUIT && mode != RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE + && mode != RIDE_MODE_POWERED_LAUNCH_PASSTROUGH) { - return 0; + return false; } // Must have no more than one vehicle and one station - if (ride->num_vehicles > 1 || ride->num_stations > 1) - return 0; + if (num_vehicles > 1 || num_stations > 1) + return false; - return 1; + return true; } #pragma region Initialisation functions @@ -1014,7 +1009,7 @@ void reset_all_ride_build_dates() static int32_t ride_check_if_construction_allowed(Ride* ride) { - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); if (rideEntry == nullptr) { context_show_error(STR_INVALID_RIDE_TYPE, STR_CANT_EDIT_INVALID_RIDE_TYPE); @@ -1974,7 +1969,7 @@ int32_t ride_modify(CoordsXYE* input) { return 0; } - rideEntry = get_ride_entry_by_ride(ride); + rideEntry = ride->GetRideEntry(); if ((rideEntry == nullptr) || !ride_check_if_construction_allowed(ride)) return 0; @@ -2117,7 +2112,7 @@ int32_t ride_initialise_construction_window(Ride* ride) * * rct2: 0x006ABE4C */ -void ride_update_all() +void Ride::UpdateAll() { Ride* ride; int32_t i; @@ -2135,7 +2130,7 @@ void ride_update_all() // Update rides FOR_ALL_RIDES (i, ride) - ride_update(ride); + ride->Update(); ride_music_update_final(); } @@ -2144,63 +2139,63 @@ void ride_update_all() * * rct2: 0x006ABE73 */ -static void ride_update(Ride* ride) +void Ride::Update() { - if (ride->vehicle_change_timeout != 0) - ride->vehicle_change_timeout--; + if (vehicle_change_timeout != 0) + vehicle_change_timeout--; - ride_music_update(ride); + ride_music_update(this); // Update stations - if (ride->type != RIDE_TYPE_MAZE) + if (type != RIDE_TYPE_MAZE) for (int32_t i = 0; i < MAX_STATIONS; i++) - ride_update_station(ride, i); + ride_update_station(this, i); // Update financial statistics - ride->num_customers_timeout++; + num_customers_timeout++; - if (ride->num_customers_timeout >= 960) + if (num_customers_timeout >= 960) { // This is meant to update about every 30 seconds - ride->num_customers_timeout = 0; + num_customers_timeout = 0; // Shift number of customers history, start of the array is the most recent one for (int32_t i = CUSTOMER_HISTORY_SIZE - 1; i > 0; i--) { - ride->num_customers[i] = ride->num_customers[i - 1]; + num_customers[i] = num_customers[i - 1]; } - ride->num_customers[0] = ride->cur_num_customers; + num_customers[0] = cur_num_customers; - ride->cur_num_customers = 0; - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_CUSTOMER; + cur_num_customers = 0; + window_invalidate_flags |= RIDE_INVALIDATE_RIDE_CUSTOMER; - ride->income_per_hour = ride_calculate_income_per_hour(ride); - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; + income_per_hour = CalculateIncomePerHour(); + window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; - if (ride->upkeep_cost != MONEY16_UNDEFINED) - ride->profit = (ride->income_per_hour - ((money32)ride->upkeep_cost * 16)); + if (upkeep_cost != MONEY16_UNDEFINED) + profit = (income_per_hour - ((money32)upkeep_cost * 16)); } // Ride specific updates - if (ride->type == RIDE_TYPE_CHAIRLIFT) - ride_chairlift_update(ride); - else if (ride->type == RIDE_TYPE_SPIRAL_SLIDE) - ride_spiral_slide_update(ride); + if (type == RIDE_TYPE_CHAIRLIFT) + UpdateChairlift(); + else if (type == RIDE_TYPE_SPIRAL_SLIDE) + UpdateSpiralSlide(); - ride_breakdown_update(ride); + ride_breakdown_update(this); // Various things include news messages - if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_DUE_INSPECTION)) - if (((gCurrentTicks >> 1) & 255) == (uint32_t)ride->id) - ride_breakdown_status_update(ride); + if (lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_DUE_INSPECTION)) + if (((gCurrentTicks >> 1) & 255) == (uint32_t)id) + ride_breakdown_status_update(this); - ride_inspection_update(ride); + ride_inspection_update(this); - if (ride->status == RIDE_STATUS_TESTING && gConfigGeneral.no_test_crashes) + if (status == RIDE_STATUS_TESTING && gConfigGeneral.no_test_crashes) { - for (int32_t i = 0; i < ride->num_vehicles; i++) + for (int32_t i = 0; i < num_vehicles; i++) { - uint16_t spriteIndex = ride->vehicles[i]; + uint16_t spriteIndex = vehicles[i]; if (spriteIndex == SPRITE_INDEX_NULL) continue; @@ -2208,9 +2203,9 @@ static void ride_update(Ride* ride) if (vehicle->status == VEHICLE_STATUS_CRASHED || vehicle->status == VEHICLE_STATUS_CRASHING) { - ride_set_status(ride, RIDE_STATUS_CLOSED); - ride_set_status(ride, RIDE_STATUS_CLOSED); - ride_set_status(ride, RIDE_STATUS_TESTING); + ride_set_status(this, RIDE_STATUS_CLOSED); + ride_set_status(this, RIDE_STATUS_CLOSED); + ride_set_status(this, RIDE_STATUS_TESTING); break; } } @@ -2221,29 +2216,29 @@ static void ride_update(Ride* ride) * * rct2: 0x006AC489 */ -static void ride_chairlift_update(Ride* ride) +void Ride::UpdateChairlift() { int32_t x, y, z; - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) + if (!(lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) return; - if ((ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) - && ride->breakdown_reason_pending == 0) + if ((lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) + && breakdown_reason_pending == 0) return; - uint16_t old_chairlift_bullwheel_rotation = ride->chairlift_bullwheel_rotation >> 14; - ride->chairlift_bullwheel_rotation += ride->speed * 2048; - if (old_chairlift_bullwheel_rotation == ride->speed / 8) + uint16_t old_chairlift_bullwheel_rotation = chairlift_bullwheel_rotation >> 14; + chairlift_bullwheel_rotation += speed * 2048; + if (old_chairlift_bullwheel_rotation == speed / 8) return; - x = ride->chairlift_bullwheel_location[0].x * 32; - y = ride->chairlift_bullwheel_location[0].y * 32; - z = ride->chairlift_bullwheel_z[0] * 8; + x = chairlift_bullwheel_location[0].x * 32; + y = chairlift_bullwheel_location[0].y * 32; + z = chairlift_bullwheel_z[0] * 8; map_invalidate_tile_zoom1(x, y, z, z + (4 * 8)); - x = ride->chairlift_bullwheel_location[1].x * 32; - y = ride->chairlift_bullwheel_location[1].y * 32; - z = ride->chairlift_bullwheel_z[1] * 8; + x = chairlift_bullwheel_location[1].x * 32; + y = chairlift_bullwheel_location[1].y * 32; + z = chairlift_bullwheel_z[1] * 8; map_invalidate_tile_zoom1(x, y, z, z + (4 * 8)); } @@ -2319,19 +2314,19 @@ static constexpr const LocationXY16 ride_spiral_slide_main_tile_offset[][4] = { * * rct2: 0x006AC545 */ -static void ride_spiral_slide_update(Ride* ride) +void Ride::UpdateSpiralSlide() { if (gCurrentTicks & 3) return; - if (ride->slide_in_use == 0) + if (slide_in_use == 0) return; - ride->spiral_slide_progress++; - if (ride->spiral_slide_progress >= 48) + spiral_slide_progress++; + if (spiral_slide_progress >= 48) { - ride->slide_in_use--; + slide_in_use--; - Peep* peep = GET_PEEP(ride->slide_peep); + Peep* peep = GET_PEEP(slide_peep); peep->destination_x++; } @@ -2339,13 +2334,13 @@ static void ride_spiral_slide_update(Ride* ride) // Invalidate something related to station start for (int32_t i = 0; i < MAX_STATIONS; i++) { - if (ride->stations[i].Start.xy == RCT_XY8_UNDEFINED) + if (stations[i].Start.xy == RCT_XY8_UNDEFINED) continue; - int32_t x = ride->stations[i].Start.x; - int32_t y = ride->stations[i].Start.y; + int32_t x = stations[i].Start.x; + int32_t y = stations[i].Start.y; - TileElement* tileElement = ride_get_station_start_track_element(ride, i); + TileElement* tileElement = ride_get_station_start_track_element(this, i); if (tileElement == nullptr) continue; @@ -2573,7 +2568,7 @@ bool Ride::CanBreakDown() const return false; } - rct_ride_entry* entry = get_ride_entry_by_ride(this); + rct_ride_entry* entry = GetRideEntry(); if (entry == nullptr || entry->flags & RIDE_ENTRY_FLAG_CANNOT_BREAK_DOWN) { return false; @@ -7540,7 +7535,7 @@ bool Ride::IsRide() const } } -money16 ride_get_price(Ride* ride) +money16 ride_get_price(const Ride* ride) { if (gParkFlags & PARK_FLAGS_NO_MONEY) return 0; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index e09a0021ea..b82c0cf180 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -352,6 +352,14 @@ struct Ride uint16_t holes; uint8_t sheltered_eighths; +private: + void Update(); + void UpdateChairlift(); + void UpdateSpiralSlide(); + void UpdateQueueLength(int32_t stationIndex); + money32 CalculateIncomePerHour() const; + +public: bool CanBreakDown() const; bool IsRide() const; void Renew(); @@ -373,12 +381,23 @@ struct Ride bool IsPoweredLaunched() const; bool IsBlockSectioned() const; + bool CanHaveMultipleCircuits() const; void StopGuestsQueuing(); uint8_t GetDefaultMode() const; void SetColourPreset(uint8_t index); + + rct_ride_entry* GetRideEntry() const; + + int32_t GetTotalQueueLength() const; + int32_t GetMaxQueueTime() const; + + void QueueInsertGuestAtFront(int32_t stationIndex, Peep* peep); + Peep* GetQueueHeadGuest(int32_t stationIndex) const; + + static void UpdateAll(); }; #pragma pack(push, 1) @@ -1024,14 +1043,9 @@ extern uint8_t gLastEntranceStyle; ride_id_t ride_get_empty_slot(); int32_t ride_get_count(); -int32_t ride_get_total_queue_length(Ride* ride); -int32_t ride_get_max_queue_time(Ride* ride); -Peep* ride_get_queue_head_guest(Ride* ride, int32_t stationIndex); -void ride_queue_insert_guest_at_front(Ride* ride, int32_t stationIndex, Peep* peep); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); -void ride_update_all(); void ride_check_all_reachable(); void ride_update_satisfaction(Ride* ride, uint8_t happiness); void ride_update_popularity(Ride* ride, uint8_t pop_amount); @@ -1047,12 +1061,10 @@ Staff* ride_get_mechanic(Ride* ride); Staff* ride_get_assigned_mechanic(Ride* ride); int32_t ride_get_total_length(Ride* ride); int32_t ride_get_total_time(Ride* ride); -int32_t ride_can_have_multiple_circuits(Ride* ride); TrackColour ride_get_track_colour(Ride* ride, int32_t colourScheme); vehicle_colour ride_get_vehicle_colour(Ride* ride, int32_t vehicleIndex); int32_t ride_get_unused_preset_vehicle_colour(uint8_t ride_sub_type); void ride_set_vehicle_colours_to_random_preset(Ride* ride, uint8_t preset_index); -rct_ride_entry* get_ride_entry_by_ride(const Ride* ride); uint8_t* get_ride_entry_indices_for_ride_type(uint8_t rideType); void reset_type_to_ride_entry_index_map(IObjectManager& objectManager); void ride_measurement_clear(Ride* ride); @@ -1177,7 +1189,7 @@ rct_vehicle* ride_get_broken_vehicle(Ride* ride); void window_ride_construction_do_station_check(); void window_ride_construction_do_entrance_exit_check(); -money16 ride_get_price(Ride* ride); +money16 ride_get_price(const Ride* ride); TileElement* get_station_platform(int32_t x, int32_t y, int32_t z, int32_t z_tolerance); bool ride_has_adjacent_station(Ride* ride); diff --git a/src/openrct2/ride/thrill/MagicCarpet.cpp b/src/openrct2/ride/thrill/MagicCarpet.cpp index 390ebdfdf2..f799350792 100644 --- a/src/openrct2/ride/thrill/MagicCarpet.cpp +++ b/src/openrct2/ride/thrill/MagicCarpet.cpp @@ -122,7 +122,7 @@ static void paint_magic_carpet_vehicle( paint_session* session, Ride* ride, uint8_t direction, uint32_t swingImageId, LocationXYZ16 offset, LocationXYZ16 bbOffset, LocationXYZ16 bbSize) { - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); uint32_t vehicleImageId = rideEntry->vehicles[0].base_image_id + direction; // Vehicle diff --git a/src/openrct2/ride/thrill/MotionSimulator.cpp b/src/openrct2/ride/thrill/MotionSimulator.cpp index b7db9bf9f9..fd0cc6adf3 100644 --- a/src/openrct2/ride/thrill/MotionSimulator.cpp +++ b/src/openrct2/ride/thrill/MotionSimulator.cpp @@ -34,7 +34,7 @@ static void paint_motionsimulator_vehicle( paint_session* session, int8_t offsetX, int8_t offsetY, uint8_t direction, int32_t height, const TileElement* tileElement) { Ride* ride = get_ride(tileElement->AsTrack()->GetRideIndex()); - rct_ride_entry* rideEntry = get_ride_entry_by_ride(ride); + rct_ride_entry* rideEntry = ride->GetRideEntry(); const TileElement* savedTileElement = static_cast(session->CurrentlyDrawnItem); diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index 829aa80eb8..393c02db0a 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -139,14 +139,14 @@ rct_ride_entry* get_ride_entry(int index) return gRideEntries[index]; } -rct_ride_entry* get_ride_entry_by_ride(const Ride* ride) +rct_ride_entry* Ride::GetRideEntry() const { - rct_ride_entry* type = get_ride_entry(ride->subtype); - if (type == nullptr) + rct_ride_entry* rideEntry = get_ride_entry(subtype); + if (rideEntry == nullptr) { log_error("Invalid ride subtype for ride"); } - return type; + return rideEntry; } rct_sprite* get_sprite(size_t sprite_idx) From ec6b73831764ad9f26f28cd9c1b9a84e281da153 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 20 Apr 2019 22:43:28 +0200 Subject: [PATCH 231/506] Fix #8079: Crash when unloading buggy custom rides --- distribution/changelog.txt | 1 + src/openrct2/peep/Guest.cpp | 34 +++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b41c9335e9..bd469e201b 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -13,6 +13,7 @@ - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. +- Fix: [#8079, #8969] Crash when unloading buggy custom rides. - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8649] Setting date does not work in multiplayer. diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 6d19e463a0..9fa5bf938e 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4028,22 +4028,26 @@ void Guest::UpdateRideLeaveVehicle() platformLocation.x = vehicle->x + word_981D6C[platformLocation.direction].x * 12; platformLocation.y = vehicle->y + word_981D6C[platformLocation.direction].y * 12; - int8_t loadPosition = vehicle_entry->peep_loading_positions[current_seat]; - - switch (vehicle->sprite_direction / 8) + // This can evaluate to false with buggy custom rides. + if (current_seat < vehicle_entry->peep_loading_positions.size()) { - case 0: - platformLocation.x -= loadPosition; - break; - case 1: - platformLocation.y += loadPosition; - break; - case 2: - platformLocation.x += loadPosition; - break; - case 3: - platformLocation.y -= loadPosition; - break; + int8_t loadPosition = vehicle_entry->peep_loading_positions[current_seat]; + + switch (vehicle->sprite_direction / 8) + { + case 0: + platformLocation.x -= loadPosition; + break; + case 1: + platformLocation.y += loadPosition; + break; + case 2: + platformLocation.x += loadPosition; + break; + case 3: + platformLocation.y -= loadPosition; + break; + } } platformLocation.z = ride->stations[current_ride_station].Height * 8; From 89f591ffcb45defc9ea9e3a0e62d807362963a41 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 21 Apr 2019 12:21:24 +0200 Subject: [PATCH 232/506] Also add #7700 to changelog [ci skip] --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index bd469e201b..f06f8da6dd 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -13,7 +13,7 @@ - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. -- Fix: [#8079, #8969] Crash when unloading buggy custom rides. +- Fix: [#7700, #8079, #8969] Crash when unloading buggy custom rides. - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8649] Setting date does not work in multiplayer. From 90a04e2758998caeb7779c997f051dcb4c7baf3c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 21 Apr 2019 19:56:18 +0100 Subject: [PATCH 233/506] Undo mistake. Remove pointless parameter --- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 10 ++++------ src/openrct2/peep/Guest.cpp | 6 ++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index bcd8ee892c..8dce64eed9 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -94,7 +94,6 @@ public: res->Position.z = surfaceHeight; res->GroundFlags = 0; - BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; if (_primaryColour > TILE_ELEMENT_COLOUR_MASK || _secondaryColour > TILE_ELEMENT_COLOUR_MASK) @@ -219,7 +218,6 @@ public: res->Position.z = surfaceHeight; res->GroundFlags = 0; - BannerIndex bannerId = BANNER_INDEX_NULL; money32 supportsCost = 0; rct_scenery_entry* sceneryEntry = get_large_scenery_entry(_sceneryType); @@ -324,7 +322,7 @@ public: newTileElement->clearance_height = zHigh; auto newSceneryElement = newTileElement->AsLargeScenery(); - SetNewLargeSceneryElement(*newSceneryElement, tileNum, _bannerId); + SetNewLargeSceneryElement(*newSceneryElement, tileNum); if (tileNum == 0) { @@ -394,7 +392,7 @@ private: return maxHeight; } - void SetNewLargeSceneryElement(LargeSceneryElement & sceneryElement, uint8_t tileNum, BannerIndex bannerId) const + void SetNewLargeSceneryElement(LargeSceneryElement & sceneryElement, uint8_t tileNum) const { sceneryElement.SetDirection(_loc.direction); sceneryElement.SetEntryIndex(_sceneryType); @@ -402,9 +400,9 @@ private: sceneryElement.SetPrimaryColour(_primaryColour); sceneryElement.SetSecondaryColour(_secondaryColour); - if (bannerId != BANNER_INDEX_NULL) + if (_bannerId != BANNER_INDEX_NULL) { - sceneryElement.SetBannerIndex(bannerId); + sceneryElement.SetBannerIndex(_bannerId); } if (GetFlags() & GAME_COMMAND_FLAG_GHOST) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 6d19e463a0..6de0a9e2ab 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4028,6 +4028,12 @@ void Guest::UpdateRideLeaveVehicle() platformLocation.x = vehicle->x + word_981D6C[platformLocation.direction].x * 12; platformLocation.y = vehicle->y + word_981D6C[platformLocation.direction].y * 12; + if (vehicle_entry->peep_loading_positions.empty()) + { + + log_error("Failed seating. %s", language_get_string(rideEntry->naming.name)); + } + int8_t loadPosition = vehicle_entry->peep_loading_positions[current_seat]; switch (vehicle->sprite_direction / 8) From 228628b702ac3dddbbb62ddab41cdf69e3219757 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 21 Apr 2019 19:59:37 +0100 Subject: [PATCH 234/506] Undo 2nd mistake --- src/openrct2/peep/Guest.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 6de0a9e2ab..6d19e463a0 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4028,12 +4028,6 @@ void Guest::UpdateRideLeaveVehicle() platformLocation.x = vehicle->x + word_981D6C[platformLocation.direction].x * 12; platformLocation.y = vehicle->y + word_981D6C[platformLocation.direction].y * 12; - if (vehicle_entry->peep_loading_positions.empty()) - { - - log_error("Failed seating. %s", language_get_string(rideEntry->naming.name)); - } - int8_t loadPosition = vehicle_entry->peep_loading_positions[current_seat]; switch (vehicle->sprite_direction / 8) From cc2da472715cbd517021568a70874dbd6582f89b Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 21 Apr 2019 20:06:55 +0100 Subject: [PATCH 235/506] Fix parameters --- src/openrct2/actions/LargeSceneryPlaceAction.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 8dce64eed9..9baf393df3 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -132,7 +132,7 @@ public: if (_bannerId == BANNER_INDEX_NULL) { log_error("Banner Index not specified."); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_POSITION_THIS_HERE); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME); } if (gBanners[_bannerId].type != BANNER_NULL) @@ -248,7 +248,7 @@ public: if (_bannerId == BANNER_INDEX_NULL) { log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_POSITION_THIS_HERE); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_BANNERS_IN_GAME); } if (gBanners[_bannerId].type != BANNER_NULL) From 700ebe646f738cf7ffff4e913685e4ed5fe9f73a Mon Sep 17 00:00:00 2001 From: Trevor Harkness Date: Mon, 22 Apr 2019 02:33:46 -0400 Subject: [PATCH 236/506] Add new class in SmallSceneryPlaceAction def Change to definition to refer to created SmallSceneryPlaceAction subclass instead of GameActionResult --- src/openrct2/actions/SmallSceneryPlaceAction.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index da3e4b501e..131cce2bbd 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -50,7 +50,7 @@ public: uint8_t GroundFlags{ 0 }; }; -DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GAME_COMMAND_PLACE_SCENERY, GameActionResult) +DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GAME_COMMAND_PLACE_SCENERY, SmallSceneryPlaceActionResult) { private: CoordsXYZD _loc; From d8f1933a5b81d3cf13ae05432ac22eea450bef2d Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Mon, 22 Apr 2019 15:16:48 +0200 Subject: [PATCH 237/506] Show dash for station index for non-station elements --- data/language/en-GB.txt | 2 +- src/openrct2-ui/windows/TileInspector.cpp | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 9e57c493b8..02c61a2feb 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3724,7 +3724,7 @@ STR_6273 :Music STR_6274 :Can't set colour scheme... STR_6275 :{WINDOW_COLOUR_2}Station style: STR_6276 :{RED}{STRINGID} has guests getting stuck, possibly due to invalid ride type or operating mode. -STR_6277 :{WINDOW_COLOUR_2}Station index: {BLACK}{COMMA16} +STR_6277 :{WINDOW_COLOUR_2}Station index: {BLACK}{STRINGID} STR_6278 :Autosave amount STR_6279 :{SMALLFONT}{BLACK}Number of autosaves that should be kept STR_6280 :{SMALLFONT}{BLACK}Chat diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 10af49f1ca..08a56b03f4 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -1858,7 +1858,18 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) if (track_element_is_station(tileElement)) { int16_t stationIndex = trackElement->GetStationIndex(); - gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_STATION_INDEX, &stationIndex, COLOUR_DARK_GREEN, x, y + 55); + set_format_arg(0, rct_string_id, STR_COMMA16); + set_format_arg(2, int16_t, stationIndex); + gfx_draw_string_left( + dpi, STR_TILE_INSPECTOR_STATION_INDEX, gCommonFormatArgs, COLOUR_DARK_GREEN, x, y + 55); + } + else + { + const char* stationNone = "-"; + set_format_arg(0, rct_string_id, STR_STRING); + set_format_arg(2, char*, stationNone); + gfx_draw_string_left( + dpi, STR_TILE_INSPECTOR_STATION_INDEX, gCommonFormatArgs, COLOUR_DARK_GREEN, x, y + 55); } // Properties From ac7bc977367be8839f2a4647dd87f2155d704ff6 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Mon, 22 Apr 2019 15:49:09 +0200 Subject: [PATCH 238/506] Expose colour scheme in the tile inspector (#6116) --- data/language/en-GB.txt | 1 + distribution/changelog.txt | 1 + src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/TileInspector.cpp | 5 ++++- src/openrct2/localisation/StringIds.h | 2 ++ src/openrct2/ride/Ride.h | 1 + 6 files changed, 10 insertions(+), 2 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 02c61a2feb..172ac686ad 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3754,6 +3754,7 @@ STR_6303 :Downloading object ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Open scenery picker STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to render, may cause instability. +STR_6307 :Colour scheme: {BLACK}{STRINGID} ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b41c9335e9..25e03fde77 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -23,6 +23,7 @@ - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. +- Improved: [#6116] Expose colour scheme for track elements in the tile inspector. - Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index cb9f553c71..ddcc299279 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -978,7 +978,7 @@ static constexpr const rct_string_id RideBreakdownReasonNames[] = { STR_RIDE_BREAKDOWN_CONTROL_FAILURE }; -static constexpr const rct_string_id ColourSchemeNames[] = { +const rct_string_id ColourSchemeNames[4] = { STR_MAIN_COLOUR_SCHEME, STR_ALTERNATIVE_COLOUR_SCHEME_1, STR_ALTERNATIVE_COLOUR_SCHEME_2, diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 08a56b03f4..1b1ebbbc09 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -314,7 +314,7 @@ static rct_widget PathWidgets[] = { #define TRA_GBPB PADDING_BOTTOM // Track group box properties bottom #define TRA_GBPT (TRA_GBPB + 16 + 3 * 21) // Track group box properties top #define TRA_GBDB (TRA_GBPT + GROUPBOX_PADDING) // Track group box info bottom -#define TRA_GBDT (TRA_GBDB + 20 + 6 * 11) // Track group box info top +#define TRA_GBDT (TRA_GBDB + 20 + 7 * 11) // Track group box info top static rct_widget TrackWidgets[] = { MAIN_TILE_INSPECTOR_WIDGETS, { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 0), STR_TILE_INSPECTOR_TRACK_ENTIRE_TRACK_PIECE, STR_NONE }, // WIDX_TRACK_CHECK_APPLY_TO_ALL @@ -1872,6 +1872,9 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) dpi, STR_TILE_INSPECTOR_STATION_INDEX, gCommonFormatArgs, COLOUR_DARK_GREEN, x, y + 55); } + rct_string_id colourScheme = ColourSchemeNames[trackElement->GetColourScheme()]; + gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_COLOUR_SCHEME, &colourScheme, COLOUR_DARK_GREEN, x, y + 66); + // Properties // Raise / lower label y = w->y + w->widgets[WIDX_TRACK_SPINNER_HEIGHT].top; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 7213d4d08c..0d77e03726 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3937,6 +3937,8 @@ enum STR_MULTITHREADING = 6305, STR_MULTITHREADING_TIP = 6306, + STR_TILE_INSPECTOR_COLOUR_SCHEME = 6307, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index b82c0cf180..e447717917 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -994,6 +994,7 @@ extern money16 gTotalRideValueForMoney; extern const uint8_t gRideClassifications[MAX_RIDES]; extern Ride gRideList[MAX_RIDES]; +extern const rct_string_id ColourSchemeNames[4]; extern rct_ride_measurement gRideMeasurements[MAX_RIDE_MEASUREMENTS]; extern uint16_t gRideCount; From 6d3eca31fd6ca8a2e475cae0d07cc8a587e10761 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 22 Apr 2019 23:27:25 +0200 Subject: [PATCH 239/506] Add log_verbose for vehicle entries with broken peep loading positions --- src/openrct2/peep/Guest.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 9fa5bf938e..d4437e38b6 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4049,6 +4049,12 @@ void Guest::UpdateRideLeaveVehicle() break; } } + else + { + log_verbose( + "current_seat %d is too large! (Vehicle entry has room for %d.)", current_seat, + vehicle_entry->peep_loading_positions.size()); + } platformLocation.z = ride->stations[current_ride_station].Height * 8; From d38fb6a7a2d754462f528a12c3a9614990c0cc8b Mon Sep 17 00:00:00 2001 From: Nicole <46659974+nicolewright@users.noreply.github.com> Date: Tue, 23 Apr 2019 13:26:48 -0400 Subject: [PATCH 240/506] Fix #8800: ensure tile_element_height is used correctly (#9087) * Changed calls to tile_element_height to tile_element_water_height * Changes to calls to tile_element_height * Removed tile element_height, map_get_highest_land_height, and map_get lowest_land_height 3 functions removed due to relocation. * Added function tile_element_height back to map.cpp Added tile_element height back to map.cpp. Was unnecessarily deleted. * Update Map.h * water_height changes * Update Scenario.cpp * Update Scenario.cpp * Fix 8800: applied clang format * Removed unnecessary ANDs --- src/openrct2/actions/BannerSetStyleAction.hpp | 4 +- src/openrct2/actions/LandLowerAction.hpp | 5 +- src/openrct2/actions/LandRaiseAction.hpp | 6 +-- src/openrct2/actions/LandSetHeightAction.hpp | 2 +- src/openrct2/actions/LandSmoothAction.hpp | 2 +- .../actions/LargeSceneryPlaceAction.hpp | 4 +- .../actions/SmallSceneryPlaceAction.hpp | 52 ++++++++++++------- .../actions/SurfaceSetStyleAction.hpp | 4 +- src/openrct2/actions/WallPlaceAction.hpp | 4 +- src/openrct2/actions/WaterLowerAction.hpp | 6 +-- src/openrct2/actions/WaterRaiseAction.hpp | 3 +- src/openrct2/actions/WaterSetHeightAction.hpp | 2 +- src/openrct2/cmdline/BenchSpriteSort.cpp | 2 +- src/openrct2/interface/Screenshot.cpp | 6 +-- src/openrct2/interface/Viewport.cpp | 2 +- .../paint/tile_element/Paint.Surface.cpp | 6 +-- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/peep/Peep.cpp | 4 +- src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/ride/RideRatings.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 4 +- src/openrct2/ride/Vehicle.cpp | 5 +- src/openrct2/scenario/Scenario.cpp | 4 +- src/openrct2/world/Duck.cpp | 8 ++- src/openrct2/world/Map.cpp | 31 +++++++++-- src/openrct2/world/Map.h | 3 +- src/openrct2/world/MoneyEffect.cpp | 2 +- src/openrct2/world/Particle.cpp | 5 +- 28 files changed, 106 insertions(+), 76 deletions(-) diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp index 50254ab9d0..038a0265b4 100644 --- a/src/openrct2/actions/BannerSetStyleAction.hpp +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -68,7 +68,7 @@ public: res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; res->Position.x = banner->x * 32 + 16; res->Position.y = banner->y * 32 + 16; - res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + res->Position.z = tile_element_height(banner->x, banner->y); TileElement* tileElement = banner_get_tile_element(_bannerIndex); @@ -118,7 +118,7 @@ public: res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; res->Position.x = banner->x * 32 + 16; res->Position.y = banner->y * 32 + 16; - res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + res->Position.z = tile_element_height(banner->x, banner->y); TileElement* tileElement = banner_get_tile_element(_bannerIndex); diff --git a/src/openrct2/actions/LandLowerAction.hpp b/src/openrct2/actions/LandLowerAction.hpp index 0ef06089ca..e6d4e4e9ec 100644 --- a/src/openrct2/actions/LandLowerAction.hpp +++ b/src/openrct2/actions/LandLowerAction.hpp @@ -83,13 +83,12 @@ private: MapRange validRange = MapRange{ aX, aY, bX, bY }; - res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF }; + res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) }; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; if (isExecuting) { - audio_play_sound_at_location( - SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF); + audio_play_sound_at_location(SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y)); } uint8_t maxHeight = map_get_highest_land_height( diff --git a/src/openrct2/actions/LandRaiseAction.hpp b/src/openrct2/actions/LandRaiseAction.hpp index fb2ddd40a2..b5d2f36090 100644 --- a/src/openrct2/actions/LandRaiseAction.hpp +++ b/src/openrct2/actions/LandRaiseAction.hpp @@ -4,6 +4,7 @@ * 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. *****************************************************************************/ @@ -83,13 +84,12 @@ private: MapRange validRange = MapRange{ aX, aY, bX, bY }; - res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF }; + res->Position = { _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) }; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; if (isExecuting) { - audio_play_sound_at_location( - SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y) & 0xFFFF); + audio_play_sound_at_location(SOUND_PLACE_ITEM, _coords.x, _coords.y, tile_element_height(_coords.x, _coords.y)); } uint8_t minHeight = map_get_lowest_land_height( diff --git a/src/openrct2/actions/LandSetHeightAction.hpp b/src/openrct2/actions/LandSetHeightAction.hpp index e3fd2d4ceb..47bd9b8b51 100644 --- a/src/openrct2/actions/LandSetHeightAction.hpp +++ b/src/openrct2/actions/LandSetHeightAction.hpp @@ -144,7 +144,7 @@ public: GameActionResult::Ptr Execute() const override { money32 cost = MONEY(0, 0); - auto surfaceHeight = tile_element_height(_coords.x, _coords.y) & 0xFFFF; + auto surfaceHeight = tile_element_height(_coords.x, _coords.y); footpath_remove_litter(_coords.x, _coords.y, surfaceHeight); if (!gCheatsDisableClearanceChecks) diff --git a/src/openrct2/actions/LandSmoothAction.hpp b/src/openrct2/actions/LandSmoothAction.hpp index 289e0a13c0..779a7d6ab5 100644 --- a/src/openrct2/actions/LandSmoothAction.hpp +++ b/src/openrct2/actions/LandSmoothAction.hpp @@ -350,7 +350,7 @@ private: auto b = std::clamp(normRange.GetBottom(), 0, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); auto validRange = MapRange{ l, t, r, b }; - int32_t centreZ = tile_element_height(_coords.x, _coords.y) & 0xFFFF; + int32_t centreZ = tile_element_height(_coords.x, _coords.y); auto res = MakeResult(); res->ErrorTitle = _ErrorTitles[_isLowering ? 0 : 1]; diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 9baf393df3..11a224e28b 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -88,7 +88,7 @@ public: auto res = std::make_unique(); res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; + int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; res->Position.z = surfaceHeight; @@ -212,7 +212,7 @@ public: auto res = std::make_unique(); res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; - int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y) & 0xFFFF; + int16_t surfaceHeight = tile_element_height(_loc.x, _loc.y); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; res->Position.z = surfaceHeight; diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index 131cce2bbd..4503b82b00 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -98,20 +98,23 @@ public: { supportsRequired = true; } - int32_t baseHeight = tile_element_height(_loc.x, _loc.y); + int32_t landHeight = tile_element_height(_loc.x, _loc.y); + int16_t waterHeight = tile_element_water_height(_loc.x, _loc.y); + + int32_t surfaceHeight = landHeight; // If on water - if (baseHeight & 0xFFFF0000) + if (waterHeight > 0) { - baseHeight >>= 16; + surfaceHeight = waterHeight; } auto res = std::make_unique(); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; - res->Position.z = baseHeight; + res->Position.z = surfaceHeight; if (_loc.z != 0) { - baseHeight = _loc.z; - res->Position.z = baseHeight; + surfaceHeight = _loc.z; + res->Position.z = surfaceHeight; } if (!map_check_free_elements_and_reorganise(1)) @@ -155,12 +158,15 @@ public: x2 += ScenerySubTileOffsets[quadrant & 3].x - 1; y2 += ScenerySubTileOffsets[quadrant & 3].y - 1; } - baseHeight = tile_element_height(x2, y2); + landHeight = tile_element_height(x2, y2); + waterHeight = tile_element_water_height(x2, y2); + + surfaceHeight = landHeight; // If on water - if (baseHeight & 0xFFFF0000) + if (waterHeight > 0) { // base_height2 is now the water height - baseHeight >>= 16; + surfaceHeight = waterHeight; if (_loc.z == 0) { isOnWater = true; @@ -169,7 +175,7 @@ public: auto targetHeight = _loc.z; if (_loc.z == 0) { - targetHeight = baseHeight; + targetHeight = surfaceHeight; } if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode @@ -295,20 +301,23 @@ public: { supportsRequired = true; } - int32_t baseHeight = tile_element_height(_loc.x, _loc.y); + int32_t landHeight = tile_element_height(_loc.x, _loc.y); + int16_t waterHeight = tile_element_water_height(_loc.x, _loc.y); + + int32_t surfaceHeight = landHeight; // If on water - if (baseHeight & 0xFFFF0000) + if (waterHeight > 0) { - baseHeight >>= 16; + surfaceHeight = waterHeight; } auto res = std::make_unique(); res->Position.x = _loc.x + 16; res->Position.y = _loc.y + 16; - res->Position.z = baseHeight; + res->Position.z = surfaceHeight; if (_loc.z != 0) { - baseHeight = _loc.z; - res->Position.z = baseHeight; + surfaceHeight = _loc.z; + res->Position.z = surfaceHeight; } rct_scenery_entry* sceneryEntry = get_small_scenery_entry(_sceneryType); @@ -342,17 +351,20 @@ public: x2 += ScenerySubTileOffsets[quadrant & 3].x - 1; y2 += ScenerySubTileOffsets[quadrant & 3].y - 1; } - baseHeight = tile_element_height(x2, y2); + landHeight = tile_element_height(x2, y2); + waterHeight = tile_element_water_height(x2, y2); + + surfaceHeight = landHeight; // If on water - if (baseHeight & 0xFFFF0000) + if (waterHeight > 0) { // base_height2 is now the water height - baseHeight >>= 16; + surfaceHeight = waterHeight; } auto targetHeight = _loc.z; if (_loc.z == 0) { - targetHeight = baseHeight; + targetHeight = surfaceHeight; } if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) diff --git a/src/openrct2/actions/SurfaceSetStyleAction.hpp b/src/openrct2/actions/SurfaceSetStyleAction.hpp index cf281f1f7b..22ec7a0149 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.hpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.hpp @@ -99,7 +99,7 @@ public: auto xMid = (validRange.GetLeft() + validRange.GetRight()) / 2 + 16; auto yMid = (validRange.GetTop() + validRange.GetBottom()) / 2 + 16; - auto heightMid = tile_element_height(xMid, yMid) & 0xFFFF; + auto heightMid = tile_element_height(xMid, yMid); res->Position.x = xMid; res->Position.y = yMid; @@ -178,7 +178,7 @@ public: auto xMid = (validRange.GetLeft() + validRange.GetRight()) / 2 + 16; auto yMid = (validRange.GetTop() + validRange.GetBottom()) / 2 + 16; - auto heightMid = tile_element_height(xMid, yMid) & 0xFFFF; + auto heightMid = tile_element_height(xMid, yMid); res->Position.x = xMid; res->Position.y = yMid; diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 12fd45d70d..1fb0d789da 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -83,7 +83,7 @@ public: if (_loc.z == 0) { - res->Position.z = tile_element_height(res->Position.x, res->Position.y) & 0xFFFF; + res->Position.z = tile_element_height(res->Position.x, res->Position.y); } if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(GetFlags() & GAME_COMMAND_FLAG_PATH_SCENERY) @@ -288,7 +288,7 @@ public: if (res->Position.z == 0) { - res->Position.z = tile_element_height(res->Position.x, res->Position.y) & 0xFFFF; + res->Position.z = tile_element_height(res->Position.x, res->Position.y); } uint8_t edgeSlope = 0; diff --git a/src/openrct2/actions/WaterLowerAction.hpp b/src/openrct2/actions/WaterLowerAction.hpp index 5671f49938..6b7e984f64 100644 --- a/src/openrct2/actions/WaterLowerAction.hpp +++ b/src/openrct2/actions/WaterLowerAction.hpp @@ -8,7 +8,6 @@ *****************************************************************************/ #pragma once - #include "../audio/audio.h" #include "GameAction.h" #include "WaterSetHeightAction.hpp" @@ -64,9 +63,8 @@ private: res->Position.x = ((validRange.GetLeft() + validRange.GetRight()) / 2) + 16; res->Position.y = ((validRange.GetTop() + validRange.GetBottom()) / 2) + 16; - int32_t z = tile_element_height(res->Position.x, res->Position.y); - int16_t waterHeight = z >> 16; - z &= 0xFFFF; + int16_t z = tile_element_height(res->Position.x, res->Position.y); + int16_t waterHeight = tile_element_water_height(res->Position.x, res->Position.y); if (waterHeight != 0) { z = waterHeight; diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index 7ee71f7796..28304d1732 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -65,8 +65,7 @@ private: res->Position.x = ((validRange.GetLeft() + validRange.GetRight()) / 2) + 16; res->Position.y = ((validRange.GetTop() + validRange.GetBottom()) / 2) + 16; int32_t z = tile_element_height(res->Position.x, res->Position.y); - int16_t waterHeight = z >> 16; - z &= 0xFFFF; + int16_t waterHeight = tile_element_water_height(res->Position.x, res->Position.y); if (waterHeight != 0) { z = waterHeight; diff --git a/src/openrct2/actions/WaterSetHeightAction.hpp b/src/openrct2/actions/WaterSetHeightAction.hpp index e7b76ae133..b20747adc3 100644 --- a/src/openrct2/actions/WaterSetHeightAction.hpp +++ b/src/openrct2/actions/WaterSetHeightAction.hpp @@ -113,7 +113,7 @@ public: res->Position.y = _coords.y + 16; res->Position.z = _height * 8; - int32_t surfaceHeight = tile_element_height(_coords.x, _coords.y) & 0xFFFF; + int32_t surfaceHeight = tile_element_height(_coords.x, _coords.y); footpath_remove_litter(_coords.x, _coords.y, surfaceHeight); if (!gCheatsDisableClearanceChecks) wall_remove_at_z(_coords.x, _coords.y, surfaceHeight); diff --git a/src/openrct2/cmdline/BenchSpriteSort.cpp b/src/openrct2/cmdline/BenchSpriteSort.cpp index 0c9776ece8..aa38244595 100644 --- a/src/openrct2/cmdline/BenchSpriteSort.cpp +++ b/src/openrct2/cmdline/BenchSpriteSort.cpp @@ -105,7 +105,7 @@ static std::vector extract_paint_session(const std::string parkFi int32_t customY = (gMapSize / 2) * 32 + 16; int32_t x = 0, y = 0; - int32_t z = tile_element_height(customX, customY) & 0xFFFF; + int32_t z = tile_element_height(customX, customY); x = customY - customX; y = ((customX + customY) / 2) - z; diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 2323c1b2d0..763fd2a89a 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -255,7 +255,7 @@ void screenshot_giant() int32_t centreY = (mapSize / 2) * 32 + 16; int32_t x = 0, y = 0; - int32_t z = tile_element_height(centreX, centreY) & 0xFFFF; + int32_t z = tile_element_height(centreX, centreY); switch (rotation) { case 0: @@ -348,7 +348,7 @@ static void benchgfx_render_screenshots(const char* inputPath, std::unique_ptrviewport_target_sprite); - int32_t height = (tile_element_height(0xFFFF & sprite->generic.x, 0xFFFF & sprite->generic.y) & 0xFFFF) - 16; + int32_t height = (tile_element_height(0xFFFF & sprite->generic.x, 0xFFFF & sprite->generic.y)) - 16; int32_t underground = sprite->generic.z < height; viewport_set_underground_flag(underground, window, window->viewport); diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index e6d6a3b4a6..b95667f9d9 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -976,7 +976,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c const int16_t x = session->MapPosition.x; const int16_t y = session->MapPosition.y; - int32_t dx = tile_element_height(x + 16, y + 16) & 0xFFFF; + int32_t dx = tile_element_height(x + 16, y + 16); dx += 3; int32_t image_id = (SPR_HEIGHT_MARKER_BASE + dx / 16) | 0x20780000; @@ -1087,7 +1087,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_AVAILABLE) { const LocationXY16& pos = session->MapPosition; - const int32_t height2 = (tile_element_height(pos.x + 16, pos.y + 16) & 0xFFFF) + 3; + const int32_t height2 = (tile_element_height(pos.x + 16, pos.y + 16)) + 3; paint_struct* backup = session->LastRootPS; sub_98196C(session, SPR_LAND_OWNERSHIP_AVAILABLE, 16, 16, 1, 1, 0, height2); session->LastRootPS = backup; @@ -1104,7 +1104,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) { const LocationXY16& pos = session->MapPosition; - const int32_t height2 = tile_element_height(pos.x + 16, pos.y + 16) & 0xFFFF; + const int32_t height2 = tile_element_height(pos.x + 16, pos.y + 16); paint_struct* backup = session->LastRootPS; sub_98196C(session, SPR_LAND_CONSTRUCTION_RIGHTS_AVAILABLE, 16, 16, 1, 1, 0, height2 + 3); session->LastRootPS = backup; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 6d19e463a0..197a4cec26 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -2616,7 +2616,7 @@ static bool peep_really_liked_ride(Peep* peep, Ride* ride) */ static PeepThoughtType peep_assess_surroundings(int16_t centre_x, int16_t centre_y, int16_t centre_z) { - if ((tile_element_height(centre_x, centre_y) & 0xFFFF) > centre_z) + if ((tile_element_height(centre_x, centre_y)) > centre_z) return PEEP_THOUGHT_TYPE_NONE; uint16_t num_scenery = 0; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index e771e9ab2e..dda01a2219 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1086,7 +1086,7 @@ void Peep::UpdateFalling() return; } } - int32_t map_height = tile_element_height(0xFFFF & x, 0xFFFF & y) & 0xFFFF; + int32_t map_height = tile_element_height(0xFFFF & x, 0xFFFF & y); if (map_height < z || map_height - 4 > z) continue; saved_height = map_height; @@ -3444,7 +3444,7 @@ int32_t Peep::GetZOnSlope(int32_t tile_x, int32_t tile_y) if (GetNextIsSurface()) { - return tile_element_height(tile_x, tile_y) & 0xFFFF; + return tile_element_height(tile_x, tile_y); } int32_t height = next_z * 8; diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index e4e19caaba..362782a553 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1202,7 +1202,7 @@ void Staff::UpdateMowing() int16_t xy_distance; if (UpdateAction(&actionX, &actionY, &xy_distance)) { - int16_t checkZ = tile_element_height(actionX, actionY) & 0xFFFF; + int16_t checkZ = tile_element_height(actionX, actionY); MoveTo(actionX, actionY, checkZ); Invalidate(); return; diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 2ba78a0053..a0790e7bd6 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1414,7 +1414,7 @@ static int32_t ride_ratings_get_scenery_score(Ride* ride) y = location.y; } - int32_t z = tile_element_height(x * 32, y * 32) & 0xFFFF; + int32_t z = tile_element_height(x * 32, y * 32); // Check if station is underground, returns a fixed mediocre score since you can't have scenery underground if (z > ride->stations[i].Height * 8) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 559c3795c2..83ba5a32cb 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1137,7 +1137,7 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y, gMapSelectionTiles.clear(); gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; - gMapSelectArrowPosition.z = tile_element_height(x, y) & 0xFFFF; + gMapSelectArrowPosition.z = tile_element_height(x, y); gMapSelectArrowDirection = _currentTrackPieceDirection; } @@ -1354,7 +1354,7 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in gMapSelectionTiles.clear(); gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; - gMapSelectArrowPosition.z = tile_element_height(x, y) & 0xFFFF; + gMapSelectArrowPosition.z = tile_element_height(x, y); gMapSelectArrowDirection = _currentTrackPieceDirection; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index e8a5667533..40665151c7 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -5418,9 +5418,8 @@ static void vehicle_update_crash(rct_vehicle* vehicle) continue; } - int32_t z = tile_element_height(curVehicle->x, curVehicle->y); - int16_t waterHeight = (z >> 16) & 0xFFFF; - z = (int16_t)(z & 0xFFFF); + int16_t z = tile_element_height(curVehicle->x, curVehicle->y); + int16_t waterHeight = tile_element_water_height(curVehicle->x, curVehicle->y); int16_t zDiff; if (waterHeight != 0) { diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 83b84aca80..6c1efad7cf 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -435,7 +435,7 @@ static int32_t scenario_create_ducks() if (!map_is_location_in_park({ x, y })) return 0; - centreWaterZ = (tile_element_height(x, y) >> 16) & 0xFFFF; + centreWaterZ = (tile_element_water_height(x, y)); if (centreWaterZ == 0) return 0; @@ -447,7 +447,7 @@ static int32_t scenario_create_ducks() { for (j = 0; j < 7; j++) { - waterZ = (tile_element_height(x2, y2) >> 16) & 0xFFFF; + waterZ = (tile_element_water_height(x2, y2)); if (waterZ == centreWaterZ) c++; diff --git a/src/openrct2/world/Duck.cpp b/src/openrct2/world/Duck.cpp index ce96c672f3..e9d9c69353 100644 --- a/src/openrct2/world/Duck.cpp +++ b/src/openrct2/world/Duck.cpp @@ -201,9 +201,8 @@ void rct_duck::UpdateSwim() else { Invalidate(); - int32_t landZ = tile_element_height(x, y); - int32_t waterZ = (landZ >> 16) & 0xFFFF; - landZ &= 0xFFFF; + int16_t landZ = tile_element_height(x, y); + int16_t waterZ = tile_element_water_height(x, y); if (z < landZ || waterZ == 0) { @@ -224,8 +223,7 @@ void rct_duck::UpdateSwim() int32_t newX = x + DuckMoveOffset[direction].x; int32_t newY = y + DuckMoveOffset[direction].y; landZ = tile_element_height(newX, newY); - waterZ = (landZ >> 16) & 0xFFFF; - landZ &= 0xFFFF; + waterZ = tile_element_water_height(newX, newY); if (z >= landZ && z == waterZ) { diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 1317a5831f..900c88b292 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -457,7 +457,7 @@ void map_update_tile_pointers() * dx: return remember to & with 0xFFFF if you don't want water affecting results * rct2: 0x00662783 */ -int32_t tile_element_height(int32_t x, int32_t y) +int16_t tile_element_height(int32_t x, int32_t y) { TileElement* tileElement; @@ -477,7 +477,7 @@ int32_t tile_element_height(int32_t x, int32_t y) return 16; } - uint32_t height = (tileElement->AsSurface()->GetWaterHeight() << 20) | (tileElement->base_height << 3); + uint16_t height = (tileElement->base_height << 3); uint32_t slope = tileElement->AsSurface()->GetSlope(); uint8_t extra_height = (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) >> 4; // 0x10 is the 5th bit - sets slope to double height @@ -609,6 +609,31 @@ int32_t tile_element_height(int32_t x, int32_t y) return height; } +int16_t tile_element_water_height(int32_t x, int32_t y) +{ + TileElement* tileElement; + + // Off the map + if ((unsigned)x >= 8192 || (unsigned)y >= 8192) + return 0; + + // Truncate subtile coordinates + int32_t x_tile = x & 0xFFFFFFE0; + int32_t y_tile = y & 0xFFFFFFE0; + + // Get the surface element for the tile + tileElement = map_get_surface_element_at({ x_tile, y_tile }); + + if (tileElement == nullptr) + { + return 0; + } + + uint16_t height = (tileElement->AsSurface()->GetWaterHeight() << 4); + + return height; +} + /** * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwise @@ -925,7 +950,7 @@ static money32 map_set_land_ownership(uint8_t flags, int16_t x1, int16_t y1, int x += 16; y += 16; - int16_t z = tile_element_height(x, y) & 0xFFFF; + int16_t z = tile_element_height(x, y); audio_play_sound_at_location(SOUND_PLACE_ITEM, x, y, z); return 0; } diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 9bc2335d82..3ff6251ed6 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -151,7 +151,8 @@ SmallSceneryElement* map_get_small_scenery_element_at(int32_t x, int32_t y, int3 EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t z, bool ghost); EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, bool ghost); -int32_t tile_element_height(int32_t x, int32_t y); +int16_t tile_element_height(int32_t x, int32_t y); +int16_t tile_element_water_height(int32_t x, int32_t y); uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax); uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax); bool map_coord_is_connected(int32_t x, int32_t y, int32_t z, uint8_t faceDirection); diff --git a/src/openrct2/world/MoneyEffect.cpp b/src/openrct2/world/MoneyEffect.cpp index 6388fa22a6..e5a7a2b765 100644 --- a/src/openrct2/world/MoneyEffect.cpp +++ b/src/openrct2/world/MoneyEffect.cpp @@ -76,7 +76,7 @@ void money_effect_create(money32 value) if (mapPosition.x == LOCATION_NULL) return; - mapPosition.z = tile_element_height(mapPosition.x, mapPosition.y) & 0xFFFF; + mapPosition.z = tile_element_height(mapPosition.x, mapPosition.y); } mapPosition.z += 10; money_effect_create_at(-value, mapPosition.x, mapPosition.y, mapPosition.z, false); diff --git a/src/openrct2/world/Particle.cpp b/src/openrct2/world/Particle.cpp index e2b40a64f1..2639c78695 100644 --- a/src/openrct2/world/Particle.cpp +++ b/src/openrct2/world/Particle.cpp @@ -80,9 +80,8 @@ void crashed_vehicle_particle_update(rct_crashed_vehicle_particle* particle) particle->velocity_z = vz & 0xFFFF; // Check collision with land / water - uint32_t waterLand = tile_element_height(x, y); - int16_t landZ = (waterLand & 0xFFFF); - int16_t waterZ = (waterLand >> 16); + int16_t landZ = tile_element_height(x, y); + int16_t waterZ = tile_element_water_height(x, y); if (waterZ != 0 && particle->z >= waterZ && z <= waterZ) { From b052c4ac616642d86c315891ed8743f92a600c81 Mon Sep 17 00:00:00 2001 From: boucks Date: Wed, 24 Apr 2019 04:42:00 -0400 Subject: [PATCH 241/506] =?UTF-8?q?Fix=20#9054:=20remove=20gSceneryTileEle?= =?UTF-8?q?ment=20by=20returning=20it=20within=20GameActi=E2=80=A6=20(#912?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #9054: remove gSceneryTileElement by returning it within GameActionResult * fixing Clang-format issues * fixing clang-format lets try this again... * fixing clang-format alright should be good this time * fixing clang-format issues using automatic clang-formatting * initializing tileElement --- src/openrct2-ui/windows/TopToolbar.cpp | 8 +- .../actions/LargeSceneryPlaceAction.hpp | 3 +- .../actions/SmallSceneryPlaceAction.hpp | 3 +- src/openrct2/actions/WallPlaceAction.hpp | 97 +++++++++++-------- src/openrct2/world/Scenery.cpp | 1 - src/openrct2/world/Scenery.h | 1 - 6 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 4faf5d81e5..ec173da5b3 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2484,7 +2484,7 @@ static money32 try_place_ghost_scenery( gSceneryPlaceRotation = (uint16_t)(parameter_3 & 0xFF); gSceneryPlaceObject = selected_tab; - tileElement = gSceneryTileElement; + tileElement = dynamic_cast(res.get())->tileElement; gSceneryGhostPosition.z = tileElement->base_height; gSceneryQuadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant(); if (dynamic_cast(res.get())->GroundFlags & ELEMENT_IS_UNDERGROUND) @@ -2539,14 +2539,14 @@ static money32 try_place_ghost_scenery( type, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour); wallPlaceAction.SetFlags( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); - wallPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { + wallPlaceAction.SetCallback([=](const GameAction* ga, const WallPlaceActionResult* result) { if (result->Error != GA_ERROR::OK) return; gSceneryGhostPosition.x = map_tile.x; gSceneryGhostPosition.y = map_tile.y; gSceneryGhostWallRotation = edges; - gSceneryGhostPosition.z = gSceneryTileElement->base_height; + gSceneryGhostPosition.z = result->tileElement->base_height; gSceneryGhostType |= SCENERY_GHOST_FLAG_2; }); @@ -2579,7 +2579,7 @@ static money32 try_place_ghost_scenery( gSceneryGhostPosition.y = map_tile.y; gSceneryPlaceRotation = loc.direction; - tileElement = gSceneryTileElement; + tileElement = dynamic_cast(res.get())->tileElement; gSceneryGhostPosition.z = tileElement->base_height; if (dynamic_cast(res.get())->GroundFlags & ELEMENT_IS_UNDERGROUND) diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index 11a224e28b..4cd296f0a9 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -40,6 +40,7 @@ public: } uint8_t GroundFlags{ 0 }; + TileElement* tileElement = nullptr; }; DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GAME_COMMAND_PLACE_LARGE_SCENERY, LargeSceneryPlaceActionResult) @@ -326,7 +327,7 @@ public: if (tileNum == 0) { - gSceneryTileElement = newTileElement; + res->tileElement = newTileElement; } map_invalidate_tile_full(curTile.x, curTile.y); } diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.hpp b/src/openrct2/actions/SmallSceneryPlaceAction.hpp index 4503b82b00..c616dd80e3 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.hpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.hpp @@ -48,6 +48,7 @@ public: } uint8_t GroundFlags{ 0 }; + TileElement* tileElement = nullptr; }; DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GAME_COMMAND_PLACE_SCENERY, SmallSceneryPlaceActionResult) @@ -431,7 +432,7 @@ public: TileElement* newElement = tile_element_insert(_loc.x / 32, _loc.y / 32, zLow, quarterTile.GetBaseQuarterOccupied()); assert(newElement != nullptr); - gSceneryTileElement = newElement; + res->tileElement = newElement; newElement->SetType(TILE_ELEMENT_TYPE_SMALL_SCENERY); newElement->SetDirection(_loc.direction); SmallSceneryElement* sceneryElement = newElement->AsSmallScenery(); diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index 1fb0d789da..f8bb95666b 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -23,7 +23,33 @@ #include "../world/Surface.h" #include "GameAction.h" -DEFINE_GAME_ACTION(WallPlaceAction, GAME_COMMAND_PLACE_WALL, GameActionResult) +class WallPlaceActionResult final : public GameActionResult +{ +public: + WallPlaceActionResult() + : GameActionResult(GA_ERROR::OK, STR_CANT_BUILD_PARK_ENTRANCE_HERE) + { + } + + WallPlaceActionResult(GA_ERROR err) + : GameActionResult(err, STR_CANT_BUILD_PARK_ENTRANCE_HERE) + { + } + + WallPlaceActionResult(GA_ERROR err, rct_string_id msg) + : GameActionResult(err, STR_CANT_BUILD_PARK_ENTRANCE_HERE, msg) + { + } + + WallPlaceActionResult(GA_ERROR error, rct_string_id msg, uint8_t* args) + : GameActionResult(error, STR_CANT_BUILD_PARK_ENTRANCE_HERE, msg, args) + { + } + + TileElement* tileElement = nullptr; +}; + +DEFINE_GAME_ACTION(WallPlaceAction, GAME_COMMAND_PLACE_WALL, WallPlaceActionResult) { private: int32_t _wallType{ -1 }; @@ -73,7 +99,7 @@ public: GameActionResult::Ptr Query() const override { - auto res = MakeResult(); + auto res = std::make_unique(); res->ErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; res->Position = _loc; @@ -93,23 +119,23 @@ public: { if (!map_is_location_in_park({ _loc.x, _loc.y })) { - return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::NOT_OWNED); } } else if (!map_is_location_owned(_loc.x, _loc.y, _loc.z)) { - return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::NOT_OWNED); } } else if (!byte_9D8150 && (_loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)) { log_error("Invalid x/y coordinates. x = %d y = %d", _loc.x, _loc.y); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } if (_edge > 3) { - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } uint8_t edgeSlope = 0; @@ -120,7 +146,7 @@ public: if (surfaceElement == nullptr) { log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } targetHeight = surfaceElement->base_height * 8; @@ -137,7 +163,7 @@ public: if (surfaceElement == nullptr) { log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } if (surfaceElement->AsSurface()->GetWaterHeight() > 0) @@ -146,13 +172,13 @@ public: if (targetHeight < waterHeight && !gCheatsDisableClearanceChecks) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CANT_BUILD_THIS_UNDERWATER); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_BUILD_THIS_UNDERWATER); } } if (targetHeight / 8 < surfaceElement->base_height && !gCheatsDisableClearanceChecks) { - return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } if (!(edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS))) @@ -164,8 +190,7 @@ public: { if (targetHeight / 8 < newBaseHeight) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) @@ -180,9 +205,8 @@ public: newBaseHeight += 2; if (targetHeight / 8 < newBaseHeight) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, - STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } newBaseHeight -= 2; } @@ -195,8 +219,7 @@ public: { if (targetHeight / 8 < newBaseHeight) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique(GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) @@ -211,9 +234,8 @@ public: newBaseHeight += 2; if (targetHeight / 8 < newBaseHeight) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, - STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); } } } @@ -226,7 +248,7 @@ public: if (wallEntry == nullptr) { log_error("Wall Type not found %d", _wallType); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) @@ -234,14 +256,13 @@ public: if (_bannerId == BANNER_INDEX_NULL) { log_error("Banner Index not specified."); - return MakeResult( - GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME); } if (gBanners[_bannerId].type != BANNER_NULL) { log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } } @@ -250,8 +271,7 @@ public: { if (wallEntry->wall.flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE) { - return MakeResult( - GA_ERROR::DISALLOWED, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE); + return std::make_unique(GA_ERROR::DISALLOWED, STR_ERR_UNABLE_TO_BUILD_THIS_ON_SLOPE); } clearanceHeight += 2; } @@ -262,14 +282,14 @@ public: { if (!WallCheckObstruction(wallEntry, targetHeight / 8, clearanceHeight, &wallAcrossTrack)) { - return MakeResult( - GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } } if (!map_check_free_elements_and_reorganise(1)) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, gGameCommandErrorText); } res->Cost = wallEntry->wall.price; @@ -278,7 +298,7 @@ public: GameActionResult::Ptr Execute() const override { - auto res = MakeResult(); + auto res = std::make_unique(); res->ErrorTitle = STR_CANT_BUILD_PARK_ENTRANCE_HERE; res->Position = _loc; @@ -299,7 +319,7 @@ public: if (surfaceElement == nullptr) { log_error("Surface element not found at %d, %d.", _loc.x, _loc.y); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } targetHeight = surfaceElement->base_height * 8; @@ -317,7 +337,7 @@ public: if (wallEntry == nullptr) { log_error("Wall Type not found %d", _wallType); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) @@ -325,14 +345,13 @@ public: if (_bannerId == BANNER_INDEX_NULL) { log_error("Banner Index not specified."); - return MakeResult( - GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME); } if (gBanners[_bannerId].type != BANNER_NULL) { log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); } rct_banner* banner = &gBanners[_bannerId]; @@ -364,14 +383,14 @@ public: { if (!WallCheckObstruction(wallEntry, targetHeight / 8, clearanceHeight, &wallAcrossTrack)) { - return MakeResult( - GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText, gCommonFormatArgs); + return std::make_unique( + GA_ERROR::NO_CLEARANCE, gGameCommandErrorText, gCommonFormatArgs); } } if (!map_check_free_elements_and_reorganise(1)) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_BUILD_PARK_ENTRANCE_HERE, gGameCommandErrorText); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, gGameCommandErrorText); } TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, targetHeight / 8, 0); @@ -410,7 +429,7 @@ public: wallElement->SetGhost(true); } - gSceneryTileElement = tileElement; + res->tileElement = tileElement; map_invalidate_tile_zoom1(_loc.x, _loc.y, wallElement->base_height * 8, wallElement->base_height * 8 + 72); res->Cost = wallEntry->wall.price; diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 77eb443ad6..5d2b0d01b1 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -40,7 +40,6 @@ colour_t gWindowScenerySecondaryColour; colour_t gWindowSceneryTertiaryColour; bool gWindowSceneryEyedropperEnabled; -TileElement* gSceneryTileElement; uint8_t gSceneryQuadrant; money32 gSceneryPlaceCost; diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h index 9fd3c62581..19b993d94a 100644 --- a/src/openrct2/world/Scenery.h +++ b/src/openrct2/world/Scenery.h @@ -256,7 +256,6 @@ extern colour_t gWindowScenerySecondaryColour; extern colour_t gWindowSceneryTertiaryColour; extern bool gWindowSceneryEyedropperEnabled; -extern TileElement* gSceneryTileElement; extern uint8_t gSceneryQuadrant; extern money32 gSceneryPlaceCost; From 0183fc76db57b361139ed76298c5ff2dc8cf8307 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 25 Apr 2019 04:00:23 +0000 Subject: [PATCH 242/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/hu-HU.txt | 130 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 13 deletions(-) diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index 3dbe5dfe33..20d3fabde9 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -40,7 +40,7 @@ STR_0035 :Körhinta STR_0036 :Ismeretlen bódé (22) STR_0037 :Információs bódé STR_0038 :WC -STR_0039 :Óriáskerék +STR_0039 :Óriáskerék STR_0040 :Mozgásszimulátor STR_0041 :3D mozi STR_0042 :Top Spin @@ -143,7 +143,7 @@ STR_0560 :Egy hely, ahol a rosszul lett vendégek gyorsabban összeszedhetik STR_0561 :Cirkuszi állatprodukció egy nagy sátorban STR_0562 :Motoros autók utaznak egy többszintes pálya mentén, miközben kísérteties díszletek és speciális effektusok mellett haladnak el STR_0563 :Kényelmes, egyszerű biztonsági rudas vonatokban ülve élvezhetik az utasok a hatalmas, sima eséseket és csavaros pályákat, valamint a bőséges „légi időt” az emelkedők után -STR_0564 :Ez a fa pályán futó hullámvasút gyors, durva, hangos és „kontroll nélküli” utazási élményt nyújt, bőséges „légi idővel” +STR_0564 :Ez a fa pályán futó hullámvasút gyors, durva, hangos és „kontrollvesztett” utazási élményt nyújt, bőséges „légi idővel” STR_0578 :A kocsik egy abroncsokkal körbefogott, meredek esésekkel és palástorsókkal teli pálya mentén haladnak STR_0579 :Egy enyhe minigolf-játék STR_0582 :Önvezető légpárnás járművek @@ -524,6 +524,9 @@ STR_1154 :Magasságjelek a talajon STR_1155 :Magasságjelek az utakon STR_1156 :{MOVE_X}{10}{STRINGID} STR_1157 :✓{MOVE_X}{10}{STRINGID} +STR_1159 :{SMALLFONT}{BLACK}Díszletek, kertek és egyéb kiegészítők lerakása +STR_1160 :{SMALLFONT}{BLACK}Tavak és vizek létrehozása/módosítása +STR_1173 :{SMALLFONT}{BLACK}Utak és várósorok építése STR_1158 :Nem távolítható el... STR_1161 :Nem rakhatod ide... STR_1162 :{OUTLINE}{TOPAZ}{STRINGID} @@ -539,6 +542,7 @@ STR_1174 :Egy hirdetőtábla útban van STR_1175 :Nem építhető lejtős úton STR_1176 :Nem építhető ide út... STR_1177 :Nem távolítható el az út... +STR_1179 :Az út akadályozza STR_1180 :Nem építhető víz alá! STR_1181 :Utak STR_1182 :Típus @@ -799,6 +803,9 @@ STR_1455 :Érvénytelen vendégnév STR_1456 :{WINDOW_COLOUR_2}Elköltött pénz: {BLACK}{CURRENCY2DP} STR_1457 :{WINDOW_COLOUR_2}Pénz a zsebében: {BLACK}{CURRENCY2DP} STR_1458 :{WINDOW_COLOUR_2}Parkban töltött idő: {BLACK}{REALTIME} +STR_1459 :Pálya stílusa +STR_1460 :{SMALLFONT}{BLACK}’U’ alakú nyílt pálya +STR_1461 :{SMALLFONT}{BLACK}’O’ alakú zárt pálya STR_1462 :Túl meredek a felvonószakaszhoz STR_1463 :Vendégek STR_1464 :Spirálpálya felfelé (kicsi) @@ -1213,17 +1220,17 @@ STR_1906 :{WINDOW_COLOUR_2}Étel/ital készletek STR_1907 :{WINDOW_COLOUR_2}Alkalmazottak bére STR_1908 :{WINDOW_COLOUR_2}Marketing STR_1909 :{WINDOW_COLOUR_2}Kutatás -STR_1910 :{WINDOW_COLOUR_2}Hitelkamat +STR_1910 :{WINDOW_COLOUR_2}Kölcsön kamat: STR_1911 :{BLACK} {COMMA16}%-os éves kamattal STR_1912 :{MONTH} STR_1913 :{BLACK}+{CURRENCY2DP} STR_1914 :{BLACK}{CURRENCY2DP} STR_1915 :{RED}{CURRENCY2DP} -STR_1916 :{WINDOW_COLOUR_2}Hitel: +STR_1916 :{WINDOW_COLOUR_2}Kölcsön: STR_1917 :{POP16}{POP16}{POP16}{CURRENCY} STR_1918 :Nem vehetsz fel több pénzt! STR_1919 :Nincs elég pénz! -STR_1920 :Nem tudod visszafizetni a hitelt! +STR_1920 :Nem tudod visszafizetni a kölcsönt! STR_1921 :{SMALLFONT}{BLACK}Új játék indítása STR_1922 :{SMALLFONT}{BLACK}Mentett játék folytatása STR_1924 :{SMALLFONT}{BLACK}Kilépés @@ -1709,8 +1716,8 @@ STR_2449 :{YELLOW}Az ingyen {STRINGID} marketingkampánya befejeződött STR_2450 :{YELLOW}A park reklámkampánya befejeződött STR_2451 :{YELLOW}{STRINGID} reklámkampánya befejeződött STR_2454 :{SMALLFONT}{BLACK}{CURRENCY2DP} - -STR_2452 :{WINDOW_COLOUR_2}Pénz (hitel nélkül): {BLACK}{CURRENCY2DP} -STR_2453 :{WINDOW_COLOUR_2}Pénz (hitel nélkül): {RED}{CURRENCY2DP} +STR_2452 :{WINDOW_COLOUR_2}Pénz (kölcsön nélkül): {BLACK}{CURRENCY2DP} +STR_2453 :{WINDOW_COLOUR_2}Pénz (kölcsön nélkül): {RED}{CURRENCY2DP} STR_2457 :{SMALLFONT}{BLACK}A pénzügyi számlák adatai STR_2458 :{SMALLFONT}{BLACK}Grafikon a pénz (kölcsön nélküli) alakulásáról STR_2459 :{SMALLFONT}{BLACK}Grafikon a park értékének alakulásáról @@ -1736,6 +1743,7 @@ STR_2482 :{SMALLFONT}{BLACK}Nyereség: {CURRENCY} hetente, Park értéke: {C STR_2483 :{WINDOW_COLOUR_2}Heti nyereség: {BLACK}+{CURRENCY2DP} STR_2484 :{WINDOW_COLOUR_2}Heti nyereség: {RED}{CURRENCY2DP} STR_2487 :Vendégek „igazi” nevének mutatása +STR_2488 :{SMALLFONT}{BLACK}Váltás a vendégek „igazi” nevének és a vendégek számának mutatása között STR_2489 :Gyorsbillentyűk... STR_2490 :Gyorsbillentyűk STR_2491 :Alapértékek visszaállítása @@ -1770,7 +1778,7 @@ STR_2519 :Park információk STR_2520 :Vendéglista STR_2521 :Alkalmazottak listája STR_2522 :Legutóbbi üzenetek megjelenítése -STR_2523 :Térkép megjelenítése +STR_2523 :Térkép STR_2524 :Képmentés ### The following need to be reordered to match SDL_keycode layout. STR_2525 :??? @@ -1954,6 +1962,7 @@ STR_2704 :Minden 30. percben STR_2705 :Minden órában STR_2706 :Soha STR_2707 :Rendszer fájlkezelőjének használata +STR_2708 :{WINDOW_COLOUR_1}Biztos, hogy felül akarod írni ezt: {STRINGID}? STR_2709 :Felülírás STR_2710 :Írd be a fájl nevét. STR_2711 :; @@ -2097,7 +2106,49 @@ STR_2858 :Nem indítható marketingkampány... STR_2861 :{WINDOW_COLOUR_2}Az Infogrames Interactive Inc. számára licencelve STR_2862 :Zenei köszönetnyilvánítások... STR_2863 :Zenei köszönetnyilvánítások +STR_2864 :{WINDOW_COLOUR_2}Induló - Die Regimentskinder: (Fucik) copyright nélküli +STR_2865 :{WINDOW_COLOUR_2}Heyken's Serenade: (J.Heyken) British Standard Music Coy; GEMA, BRITICO +STR_2866 :{WINDOW_COLOUR_2}La Belle Espagnole: (Robert Vollstedt) copyright nélküli +STR_2867 :{WINDOW_COLOUR_2}Wedding Journey: (Tradicionális) +STR_2868 :{WINDOW_COLOUR_2}Mesél a bécsi erdő: (JohannSTRauss) copyright nélküli +STR_2869 :{WINDOW_COLOUR_2}Szláv tánc: (Tradicionális) +STR_2870 :{WINDOW_COLOUR_2}Das Alpenhorn: (Tradicionális) +STR_2871 :{WINDOW_COLOUR_2}The Blond Sailor: (Tradicionális) +STR_2872 :{WINDOW_COLOUR_2}Nyitány - Költő és paraszt: (Franz von Suppé) copyright nélküli +STR_2873 :{WINDOW_COLOUR_2}Keringő egyveleg: (JohannSTRauss) copyright nélküli +STR_2874 :{WINDOW_COLOUR_2}Bella Bella Bimba: (Tradicionális) +STR_2875 :{WINDOW_COLOUR_2}Eredeti felvételek (P) 1976 C.J.Mears Organization, engedéllyel használva +STR_2876 :{WINDOW_COLOUR_2}RollerCoaster Tycoon 2 főcímzene: (Allister Brimble) copyright © Chris Sawyer +STR_2877 :{WINDOW_COLOUR_2}Dodgems Beat: (Allister Brimble) copyright © Chris Sawyer +STR_2878 :{WINDOW_COLOUR_2}Mid Summer's Heat: (Allister Brimble) copyright © Chris Sawyer +STR_2879 :{WINDOW_COLOUR_2}Pharaoh's Tomb: (Allister Brimble) copyright © Chris Sawyer +STR_2880 :{WINDOW_COLOUR_2}Caesar's March: (Allister Brimble) copyright © Chris Sawyer +STR_2881 :{WINDOW_COLOUR_2}Drifting To Heaven: (Allister Brimble) copyright © Chris Sawyer +STR_2882 :{WINDOW_COLOUR_2}Invaders: (Allister Brimble) copyright © Chris Sawyer +STR_2883 :{WINDOW_COLOUR_2}Eternal Toybox: (Allister Brimble) copyright © Chris Sawyer +STR_2884 :{WINDOW_COLOUR_2}Jungle Juice: (Allister Brimble) copyright © Chris Sawyer +STR_2885 :{WINDOW_COLOUR_2}Ninja's Noodles: (Allister Brimble) copyright © Chris Sawyer +STR_2886 :{WINDOW_COLOUR_2}Voyage to Andromeda: (Allister Brimble) copyright © Chris Sawyer +STR_2887 :{WINDOW_COLOUR_2}Brimble's Beat: (Allister Brimble) copyright © Chris Sawyer +STR_2888 :{WINDOW_COLOUR_2}Atlantis: (Allister Brimble) copyright © Chris Sawyer +STR_2889 :{WINDOW_COLOUR_2}Wild West Kid: (Allister Brimble) copyright © Chris Sawyer +STR_2890 :{WINDOW_COLOUR_2}Vampire's Lair: (Allister Brimble) copyright © Chris Sawyer +STR_2891 :{WINDOW_COLOUR_2}Blockbuster: (Allister Brimble) copyright © Chris Sawyer +STR_2892 :{WINDOW_COLOUR_2}Airtime Rock: (Allister Brimble) copyright © Chris Sawyer +STR_2893 :{WINDOW_COLOUR_2}Searchlight Rag: (Scott Joplin/Allister Brimble) copyright © Chris Sawyer +STR_2894 :{WINDOW_COLOUR_2}Flight of Fantasy: (Steve Blenkinsopp) copyright © Chris Sawyer +STR_2895 :{WINDOW_COLOUR_2}Big Rock: (Allister Brimble) copyright © Chris Sawyer +STR_2896 :{WINDOW_COLOUR_2}Hypothermia: (Allister Brimble) copyright © Chris Sawyer +STR_2897 :{WINDOW_COLOUR_2}Last Sleigh Ride: (Allister Brimble) copyright © Chris Sawyer +STR_2898 :{WINDOW_COLOUR_2}Pipes of Glencairn: (Allister Brimble) copyright © Chris Sawyer +STR_2899 :{WINDOW_COLOUR_2}Traffic Jam: (Allister Brimble) copyright © Chris Sawyer STR_2901 :{WINDOW_COLOUR_2}(A minták a Spectrasonics „Liquid Grooves”-ának köszönhetőek) +STR_2902 :{WINDOW_COLOUR_2}Toccata: (C.M.Widor, Előadja: Peter James Adcock) felvétel © Chris Sawyer +STR_2903 :{WINDOW_COLOUR_2}Space Rock: (Allister Brimble) copyright © Chris Sawyer +STR_2904 :{WINDOW_COLOUR_2}Manic Mechanic: (Allister Brimble) copyright © Chris Sawyer +STR_2905 :{WINDOW_COLOUR_2}Techno Torture: (Allister Brimble) copyright © Chris Sawyer +STR_2906 :{WINDOW_COLOUR_2}Sweat Dreams: (Allister Brimble) copyright © Chris Sawyer +STR_2907 :{WINDOW_COLOUR_2}Baj van a részeg tengerésszel: (Névtelen/Allister Brimble) copyright © Chris Sawyer STR_2971 :Fő színséma STR_2972 :Alternatív színséma 1 STR_2973 :Alternatív színséma 2 @@ -2239,6 +2290,8 @@ STR_3133 :Nem építhető lejtőre STR_3142 :{WINDOW_COLOUR_2}Befogadóképesség: {BLACK}{STRINGID} STR_3143 :{SMALLFONT}{BLACK}Emberek megjelenítése a térképen STR_3144 :{SMALLFONT}{BLACK}Játékok és bódék megjelenítése a térképen +STR_3162 :Nem lehet elég memóriát lefoglalni +STR_3163 :Új adat telepítése: STR_3164 :{BLACK}{COMMA16} kiválasztva (maximum {COMMA16}) STR_3184 :Játékok és járműveik STR_3185 :Kis díszletek @@ -2280,9 +2333,12 @@ STR_3237 :{SMALLFONT}{BLACK}A park beállításai STR_3238 :Nem kell pénz STR_3239 :{SMALLFONT}{BLACK}Legyen ez a park egy pénzügyi korlátok nélküli, ’nem kell pénz’ park STR_3240 :{WINDOW_COLOUR_2}Kezdőtöke: -STR_3241 :{WINDOW_COLOUR_2}Kezdeti hitel: -STR_3242 :{WINDOW_COLOUR_2}Maximális hitelösszeg: +STR_3241 :{WINDOW_COLOUR_2}Kezdeti kölcsön: +STR_3242 :{WINDOW_COLOUR_2}Maximális kölcsönösszeg: STR_3243 :{WINDOW_COLOUR_2}Éves kamatláb: +STR_3264 :Nem növelhető jobban! +STR_3265 :Nem csökkenthető jobban! +STR_3266 :{SMALLFONT}{BLACK}Válaszd ki a park belépőjének és játékainak fizetési módját STR_3279 :Ingyenes parkbelépő / Fizetős játékok STR_3280 :Fizetős parkbelépő / Ingyenes játékok STR_3281 :{WINDOW_COLOUR_2}Belépési díj: @@ -2424,10 +2480,15 @@ STR_5164 :Twitch csatorna neve STR_5165 :Vendégek követők utáni elnevezése STR_5166 :{SMALLFONT}{BLACK}A vendégek a csatorna Twitch követői{NEWLINE}után kapják a nevüket STR_5167 :Követőkről elnevezett vendégek követése +STR_5168 :{SMALLFONT}{BLACK}A csatorna Twitch követőiről elnevezett vendégek követési információinak bekapcsolása STR_5169 :Vendégek Twitch chat résztvevők utáni elnevezése STR_5170 :{SMALLFONT}{BLACK}A vendégek Twitch chat résztvevők utáni elnevezése STR_5171 :Chat résztvevőkről elnevezett vendégek követése +STR_5172 :{SMALLFONT}{BLACK}A Twitch chat résztvevőiről elnevezett vendégek követési információinak bekapcsolása STR_5173 :Twitch chat hírként történő megjelenítése +STR_5174 :{SMALLFONT}{BLACK}A !news előtagú Twitch chat üzenetek játékbeli üzenetként történő használata +STR_5175 :Add meg a Twitch csatornád nevét +STR_5176 :Twitch integráció engedélyezése STR_5177 :Képernyőmód: STR_5178 :{SMALLFONT}{BLACK}Pénzügyi csalások STR_5179 :{SMALLFONT}{BLACK}Vendég-csalások @@ -2485,6 +2546,10 @@ STR_5276 :Add meg a keresendő objektum nevét STR_5277 :Törlés STR_5278 :Homokozó mód STR_5279 :Homokozó mód ki +STR_5281 :{SMALLFONT}{BLACK}Jellemzők +STR_5282 :RCT1 játék nyitva/zárva lámpák +STR_5283 :RCT1 park nyitva/zárva lámpák +STR_5284 :RCT1 pályaválasztó betütípus STR_5285 :ROBBANJANAK!!! STR_5286 :{SMALLFONT}{BLACK}Néhány vendéget felrobbant STR_5287 :A játék már meghibásodott @@ -2501,6 +2566,9 @@ STR_5297 :{SMALLFONT}{BLACK}A park megnyitása STR_5298 :{RED}{STRINGID} STR_5299 :{LIGHTPINK}{STRINGID} STR_5300 :{SMALLFONT}{BLACK}Az alkalmazottak gyors kirúgása +STR_5301 :{MEDIUMFONT}{BLACK}A kölcsönöd törlése +STR_5302 :Kölcsön törlése +STR_5303 :Szünet alatti építkezés engedélyezése STR_5304 :Főcím: STR_5305 :RollerCoaster Tycoon 1 STR_5306 :RollerCoaster Tycoon 1 (AA) @@ -2509,9 +2577,35 @@ STR_5308 :RollerCoaster Tycoon 2 STR_5309 :OpenRCT2 STR_5310 :Véletlenszerű STR_5311 :{SMALLFONT}{BLACK}Hibakereső eszközök -STR_5313 :Mezővizsgáló megjelenítése +STR_5312 :Konzol +STR_5313 :Mezővizsgáló STR_5314 :Mezővizsgáló +STR_5315 :Fű +STR_5316 :Homok +STR_5317 :Sár +STR_5318 :Kavics +STR_5319 :Marsi +STR_5320 :Sakktábla +STR_5321 :Fűcsomók +STR_5322 :Jég +STR_5323 :Rács (piros) +STR_5324 :Rács (sárga) +STR_5325 :Rács (kék) +STR_5326 :Rács (zöld) +STR_5327 :Homok (sötét) +STR_5328 :Homok (világos) +STR_5329 :Sakktábla (fordított) +STR_5330 :Földalatti nézet +STR_5331 :Kavics +STR_5332 :Fa (piros) +STR_5333 :Fa (fekete) STR_5334 :Jég +STR_5335 :Játék bejárata +STR_5336 :Játék kijárata +STR_5337 :Park bejárata +STR_5338 :Elem típusa +STR_5339 :{SMALLFONT}{BLACK}Alapmagsság +STR_5340 :{SMALLFONT}{BLACK}Felszín feletti magasság STR_5343 :Alkalmazottak automatikus lerakása STR_5344 :Változási napló STR_5345 :Pénzügyi csalások @@ -2529,14 +2623,18 @@ STR_5356 :{BLACK}Émelygés: STR_5357 :{BLACK}Émelygéstűrés: STR_5358 :{BLACK}WC: STR_5359 :Vendégek eltávolítása +STR_5360 :{SMALLFONT}{BLACK}Eltávolít minden vendéget a térképről STR_5361 :Minden vendég kapjon: +STR_5362 :{BLACK}A vendégek preferált játékintenzitása legyen: STR_5363 :Több mint 1 STR_5364 :Kevesebb mint 15 STR_5365 :{BLACK}Személyzet gyors.: STR_5366 :Normál STR_5367 :Gyors +STR_5368 :Visszaállítás ütközött állapotból STR_5369 :Park paraméterei... STR_5370 :{SMALLFONT}{BLACK}Kattints erre a gombra, hogy módosítsd{NEWLINE}a park olyan paramétereit, mint{NEWLINE}a vendégek generálása és a pénz. +STR_5371 :Objektum választás STR_5372 :Jobb egeres húzás invertálása STR_5373 :Név {STRINGID} STR_5374 :Dátum {STRINGID} @@ -2850,7 +2948,7 @@ STR_5816 :{SMALLFONT}{BLACK}A játék méretezési tényezőjének beállít STR_5820 :{SMALLFONT}{BLACK}A játék minimalizálása, ha elveszti a fókuszt{NEWLINE}teljes képernyős módban STR_5822 :{SMALLFONT}{BLACK}A nap és az éjszaka váltakozásának bekapcsolása.{NEWLINE}A teljes ciklus egy játékbeli hónapig tart STR_5823 :{SMALLFONT}{BLACK}Nagybetűs megjelenítés a hirdetőtáblákon (RCT1-beli viselkedés) -STR_5824 :{SMALLFONT}{BLACK}A villámhatás kikapcsolása{NEWLINE}a viharok alatt +STR_5824 :{SMALLFONT}{BLACK}A viharok alatti villámhatás{NEWLINE}kikapcsolása STR_5825 :{SMALLFONT}{BLACK}Az egérmutató maradjon az ablakon belül STR_5826 :{SMALLFONT}{BLACK}A látkép jobb egeres húzásának invertálása STR_5835 :{SMALLFONT}{BLACK}A játék némítása, ha az ablak elveszti a fókuszt @@ -2963,6 +3061,9 @@ STR_6035 :Kérlek válaszd ki az RCT1 mappádat STR_6036 :{SMALLFONT}{BLACK}Törlés STR_6037 :Kérlek válassz egy érvényes RCT1 mappát STR_6041 :{BLACK}Nem vettél fel gépészt! +STR_6052 :A magasságtérkép túl nagy és le lesz vágva +STR_6053 :A magasságtérkép nem normalizálható +STR_6054 :Csak a 24 bites bitmapek támogatottak STR_6055 :OpenRCT2 magasságtérkép fájl STR_6056 :{SMALLFONT}{BLACK}Némítás STR_6057 :{SMALLFONT}{BLACK}Külön gomb a némítási opció számára az eszköztáron @@ -2972,6 +3073,9 @@ STR_6060 :Vendégek vásárlásainak animálása STR_6061 :{SMALLFONT}{BLACK}Animált pénzhatás megjelenítése,{NEWLINE}mikor a vendégek vásárolnak valamit. STR_6062 :{OUTLINE}{GREEN}+ {CURRENCY2DP} STR_6063 :{OUTLINE}{RED}- {CURRENCY2DP} +STR_6064 :Minden föld birtoklása +STR_6065 :Felhasználói tevékenységek naplózása +STR_6066 :{SMALLFONT}{BLACK}Minden felhasználói tevékenységet naplóz a felhasználói mappádban lévő fájlokba STR_6067 :Szerver elindítva. STR_6068 :Szerver leállítva. STR_6099 :Kapcsolódtál a szerverhez. @@ -3136,7 +3240,7 @@ STR_6274 :Nem állítható be színséma... STR_6275 :{WINDOW_COLOUR_2}Állomás stílusa: STR_6276 :A vendégek beragadnak itt: {RED}{STRINGID}. Lehet, hogy érvénytelen játéktípus vagy működési mód okozza. STR_6277 :{WINDOW_COLOUR_2}Állomás index: {BLACK}{COMMA16} -STR_6278 :Automentések mennyisége +STR_6278 :Automentések száma STR_6279 :{SMALLFONT}{BLACK}A megőrzendő automentések száma STR_6280 :{SMALLFONT}{BLACK}Chat STR_6281 :{SMALLFONT}{BLACK}Külön gomb a chat ablak számára az eszköztáron From c8df801e6656bb05cbec54cb91d6667bf17ef4ea Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Fri, 26 Apr 2019 20:25:11 +0200 Subject: [PATCH 243/506] Create ShopItemDescriptor --- src/openrct2-ui/windows/Finances.cpp | 2 +- src/openrct2-ui/windows/Guest.cpp | 14 +- src/openrct2-ui/windows/NewCampaign.cpp | 4 +- src/openrct2-ui/windows/Ride.cpp | 14 +- src/openrct2/actions/RideCreateAction.hpp | 4 +- src/openrct2/management/Marketing.cpp | 2 +- src/openrct2/peep/Guest.cpp | 18 +- src/openrct2/peep/Peep.cpp | 4 +- src/openrct2/ride/Ride.cpp | 4 +- src/openrct2/ride/ShopItem.cpp | 308 ++++------------------ src/openrct2/ride/ShopItem.h | 34 ++- 11 files changed, 105 insertions(+), 303 deletions(-) diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index a5f7fb1323..1322bb54e0 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -1197,7 +1197,7 @@ static void window_finances_marketing_paint(rct_window* w, rct_drawpixelinfo* dp break; } case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: - set_format_arg(0, rct_string_id, ShopItemStringIds[campaign->ShopItemType].plural); + set_format_arg(0, rct_string_id, ShopItems[campaign->ShopItemType].Naming.Plural); break; } diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 35221ccd01..5db28abccf 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2059,8 +2059,8 @@ static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item Ride* ride; // Default arguments - set_format_arg(0, uint32_t, ShopItemImage[item]); - set_format_arg(4, rct_string_id, ShopItemStringIds[item].display); + set_format_arg(0, uint32_t, ShopItems[item].Image); + set_format_arg(4, rct_string_id, ShopItems[item].Naming.Display); set_format_arg(6, rct_string_id, gParkName); set_format_arg(8, uint32_t, gParkNameArgs); @@ -2068,7 +2068,7 @@ static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item switch (item) { case SHOP_ITEM_BALLOON: - set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->balloon_colour) | ShopItemImage[item]); + set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->balloon_colour) | ShopItems[item].Image); break; case SHOP_ITEM_PHOTO: ride = get_ride(peep->photo1_ride_ref); @@ -2076,7 +2076,7 @@ static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item set_format_arg(8, uint32_t, ride->name_arguments); break; case SHOP_ITEM_UMBRELLA: - set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->umbrella_colour) | ShopItemImage[item]); + set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->umbrella_colour) | ShopItems[item].Image); break; case SHOP_ITEM_VOUCHER: switch (peep->voucher_type) @@ -2099,15 +2099,15 @@ static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item break; case VOUCHER_TYPE_FOOD_OR_DRINK_FREE: set_format_arg(6, rct_string_id, STR_PEEP_INVENTORY_VOUCHER_FOOD_OR_DRINK_FREE); - set_format_arg(8, rct_string_id, ShopItemStringIds[peep->voucher_arguments].singular); + set_format_arg(8, rct_string_id, ShopItems[peep->voucher_arguments].Naming.Singular); break; } break; case SHOP_ITEM_HAT: - set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->hat_colour) | ShopItemImage[item]); + set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->hat_colour) | ShopItems[item].Image); break; case SHOP_ITEM_TSHIRT: - set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->tshirt_colour) | ShopItemImage[item]); + set_format_arg(0, uint32_t, SPRITE_ID_PALETTE_COLOUR_1(peep->tshirt_colour) | ShopItems[item].Image); break; case SHOP_ITEM_PHOTO2: ride = get_ride(peep->photo2_ride_ref); diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index 856a6e0776..97222862ab 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -271,7 +271,7 @@ static void window_new_campaign_mousedown(rct_window* w, rct_widgetindex widgetI break; gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[i] = ShopItemStringIds[window_new_campaign_shop_items[i]].plural; + gDropdownItemsArgs[i] = ShopItems[window_new_campaign_shop_items[i]].Naming.Plural; numItems++; } @@ -368,7 +368,7 @@ static void window_new_campaign_invalidate(rct_window* w) window_new_campaign_widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_ITEM; if (w->campaign.ride_id != SELECTED_RIDE_UNDEFINED) { - window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].text = ShopItemStringIds[w->campaign.ride_id].plural; + window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].text = ShopItems[w->campaign.ride_id].Naming.Plural; } break; } diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index ddcc299279..9cd7ccd341 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -4900,7 +4900,7 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi) uint8_t shopItem = rideEntry->shop_item_secondary == SHOP_ITEM_NONE ? rideEntry->shop_item : rideEntry->shop_item_secondary; - int32_t spriteIndex = ShopItemImage[shopItem]; + int32_t spriteIndex = ShopItems[shopItem].Image; spriteIndex |= SPRITE_ID_PALETTE_COLOUR_1(ride->track_colour[0].main); gfx_draw_sprite(dpi, spriteIndex, x, y, 0); @@ -6500,7 +6500,7 @@ static void window_ride_income_invalidate(rct_window* w) if (shop_item_has_common_price(primaryItem)) w->pressed_widgets |= (1 << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK); - window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].text = ShopItemStringIds[primaryItem].price_label; + window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].text = ShopItems[primaryItem].Naming.PriceLabel; } // Get secondary item @@ -6509,7 +6509,7 @@ static void window_ride_income_invalidate(rct_window* w) { if ((secondaryItem = rideEntry->shop_item_secondary) != SHOP_ITEM_NONE) { - window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].text = ShopItemStringIds[secondaryItem].price_label; + window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].text = ShopItems[secondaryItem].Naming.PriceLabel; } } @@ -6575,7 +6575,7 @@ static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi) profit = ride->price; stringId = STR_PROFIT_PER_ITEM_SOLD; - profit -= get_shop_item_cost(primaryItem); + profit -= ShopItems[primaryItem].Cost; if (profit < 0) { profit *= -1; @@ -6596,7 +6596,7 @@ static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi) profit = ride->price_secondary; stringId = STR_PROFIT_PER_ITEM_SOLD; - profit -= get_shop_item_cost(secondaryItem); + profit -= ShopItems[secondaryItem].Cost; if (profit < 0) { profit *= -1; @@ -6830,7 +6830,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) shopItem = ride->GetRideEntry()->shop_item; if (shopItem != SHOP_ITEM_NONE) { - set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural); + set_format_arg(0, rct_string_id, ShopItems[shopItem].Naming.Plural); set_format_arg(2, uint32_t, ride->no_primary_items_sold); gfx_draw_string_left(dpi, STR_ITEMS_SOLD, gCommonFormatArgs, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; @@ -6841,7 +6841,7 @@ static void window_ride_customer_paint(rct_window* w, rct_drawpixelinfo* dpi) : ride->GetRideEntry()->shop_item_secondary; if (shopItem != SHOP_ITEM_NONE) { - set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural); + set_format_arg(0, rct_string_id, ShopItems[shopItem].Naming.Plural); set_format_arg(2, uint32_t, ride->no_secondary_items_sold); gfx_draw_string_left(dpi, STR_ITEMS_SOLD, gCommonFormatArgs, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 1f676d3c63..05b3ee4cd6 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -206,11 +206,11 @@ public: } else { - ride->price = DefaultShopItemPrice[rideEntry->shop_item]; + ride->price = ShopItems[rideEntry->shop_item].DefaultPrice; } if (rideEntry->shop_item_secondary != SHOP_ITEM_NONE) { - ride->price_secondary = DefaultShopItemPrice[rideEntry->shop_item_secondary]; + ride->price_secondary = ShopItems[rideEntry->shop_item_secondary].DefaultPrice; } if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST) diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 91505a3cc5..23e342af3e 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -79,7 +79,7 @@ static void marketing_raise_finished_notification(const MarketingCampaign& campa } else if (campaign.Type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) { - set_format_arg(0, rct_string_id, ShopItemStringIds[campaign.ShopItemType].plural); + set_format_arg(0, rct_string_id, ShopItems[campaign.ShopItemType].Naming.Plural); } news_item_add_to_queue(NEWS_ITEM_MONEY, MarketingCampaignNames[campaign.Type][2], 0); diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index c3d40e78d9..4676ab878b 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1247,11 +1247,11 @@ loc_69B119: } if (gClimateCurrent.Temperature >= 21) - itemValue = get_shop_hot_value(shopItem); + itemValue = ShopItems[shopItem].HotValue; else if (gClimateCurrent.Temperature <= 11) - itemValue = get_shop_cold_value(shopItem); + itemValue = ShopItems[shopItem].ColdValue; else - itemValue = get_shop_base_value(shopItem); + itemValue = ShopItems[shopItem].BaseValue; if (itemValue < price) { @@ -1306,11 +1306,11 @@ loc_69B221: if (!hasVoucher) { if (gClimateCurrent.Temperature >= 21) - itemValue = get_shop_hot_value(shopItem); + itemValue = ShopItems[shopItem].HotValue; else if (gClimateCurrent.Temperature <= 11) - itemValue = get_shop_cold_value(shopItem); + itemValue = ShopItems[shopItem].ColdValue; else - itemValue = get_shop_base_value(shopItem); + itemValue = ShopItems[shopItem].BaseValue; itemValue -= price; uint8_t satisfaction = 0; @@ -1371,7 +1371,7 @@ loc_69B221: { set_format_arg(0, rct_string_id, name_string_idx); set_format_arg(2, uint32_t, id); - set_format_arg(6, rct_string_id, ShopItemStringIds[shopItem].indefinite); + set_format_arg(6, rct_string_id, ShopItems[shopItem].Naming.Indefinite); if (gConfigNotifications.guest_bought_item) { news_item_add_to_queue(2, STR_PEEP_TRACKING_NOTIFICATION_BOUGHT_X, sprite_index); @@ -1403,7 +1403,7 @@ loc_69B221: } if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) - finance_payment(get_shop_item_cost(shopItem), gCommandExpenditureType); + finance_payment(ShopItems[shopItem].Cost, gCommandExpenditureType); // Sets the expenditure type to *_FOODDRINK_SALES or *_SHOP_SALES appropriately. gCommandExpenditureType--; @@ -1416,7 +1416,7 @@ loc_69B221: { SpendMoney(*expend_type, price); } - ride->total_profit += (price - get_shop_item_cost(shopItem)); + ride->total_profit += (price - ShopItems[shopItem].Cost); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; ride->cur_num_customers++; ride->total_customers++; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index dda01a2219..dc1795b90b 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -2054,11 +2054,11 @@ void peep_thought_set_format_args(rct_peep_thought* thought) } else if (flags & 2) { - set_format_arg(2, rct_string_id, ShopItemStringIds[thought->item].singular); + set_format_arg(2, rct_string_id, ShopItems[thought->item].Naming.Singular); } else if (flags & 4) { - set_format_arg(2, rct_string_id, ShopItemStringIds[thought->item].indefinite); + set_format_arg(2, rct_string_id, ShopItems[thought->item].Naming.Indefinite); } } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index d748958c1b..730cadec6a 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -450,7 +450,7 @@ money32 Ride::CalculateIncomePerHour() const int32_t currentShopItem = entry->shop_item; if (currentShopItem != SHOP_ITEM_NONE) { - priceMinusCost -= get_shop_item_cost(currentShopItem); + priceMinusCost -= ShopItems[currentShopItem].Cost; } currentShopItem = (lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) ? RidePhotoItems[type] : entry->shop_item_secondary; @@ -458,7 +458,7 @@ money32 Ride::CalculateIncomePerHour() const if (currentShopItem != SHOP_ITEM_NONE) { priceMinusCost += price_secondary; - priceMinusCost -= get_shop_item_cost(currentShopItem); + priceMinusCost -= ShopItems[currentShopItem].Cost; if (entry->shop_item != SHOP_ITEM_NONE) priceMinusCost /= 2; diff --git a/src/openrct2/ride/ShopItem.cpp b/src/openrct2/ride/ShopItem.cpp index 57112d7a08..a8bb394d9e 100644 --- a/src/openrct2/ride/ShopItem.cpp +++ b/src/openrct2/ride/ShopItem.cpp @@ -15,261 +15,67 @@ uint64_t gSamePriceThroughoutPark; -/** rct2: 0x00982164 */ -static const rct_shop_item_stats ShopItemStats[SHOP_ITEM_COUNT] = { - { 3, 14, 14, 14 }, // SHOP_ITEM_BALLOON - { 15, 30, 30, 30 }, // SHOP_ITEM_TOY - { 1, 7, 7, 8 }, // SHOP_ITEM_MAP - { 2, 30, 30, 30 }, // SHOP_ITEM_PHOTO - { 20, 35, 25, 50 }, // SHOP_ITEM_UMBRELLA - { 3, 12, 20, 10 }, // SHOP_ITEM_DRINK - { 5, 19, 19, 22 }, // SHOP_ITEM_BURGER - { 4, 16, 16, 18 }, // SHOP_ITEM_CHIPS - { 4, 10, 15, 6 }, // SHOP_ITEM_ICE_CREAM - { 3, 9, 9, 6 }, // SHOP_ITEM_CANDYFLOSS - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_CAN - { 0, 0, 0, 0 }, // SHOP_ITEM_RUBBISH - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_BURGER_BOX - { 6, 21, 21, 25 }, // SHOP_ITEM_PIZZA - { 0, 0, 0, 0 }, // SHOP_ITEM_VOUCHER - { 5, 13, 13, 11 }, // SHOP_ITEM_POPCORN - { 5, 17, 17, 20 }, // SHOP_ITEM_HOT_DOG - { 11, 22, 20, 18 }, // SHOP_ITEM_TENTACLE - { 9, 27, 32, 24 }, // SHOP_ITEM_HAT - { 4, 10, 10, 10 }, // SHOP_ITEM_TOFFEE_APPLE - { 20, 37, 37, 37 }, // SHOP_ITEM_TSHIRT - { 4, 8, 7, 10 }, // SHOP_ITEM_DOUGHNUT - { 3, 11, 15, 20 }, // SHOP_ITEM_COFFEE - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_CUP - { 5, 19, 19, 22 }, // SHOP_ITEM_CHICKEN - { 4, 11, 21, 10 }, // SHOP_ITEM_LEMONADE - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_BOX - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_BOTTLE - { 0, 0, 0, 0 }, // 28 - { 0, 0, 0, 0 }, // 29 - { 0, 0, 0, 0 }, // 30 - { 0, 0, 0, 0 }, // SHOP_ITEM_ADMISSION - { 2, 30, 30, 30 }, // SHOP_ITEM_PHOTO2 - { 2, 30, 30, 30 }, // SHOP_ITEM_PHOTO3 - { 2, 30, 30, 30 }, // SHOP_ITEM_PHOTO4 - { 5, 11, 11, 11 }, // SHOP_ITEM_PRETZEL - { 4, 13, 13, 20 }, // SHOP_ITEM_CHOCOLATE - { 3, 10, 20, 10 }, // SHOP_ITEM_ICED_TEA - { 5, 13, 11, 14 }, // SHOP_ITEM_FUNNEL_CAKE - { 8, 15, 20, 12 }, // SHOP_ITEM_SUNGLASSES - { 7, 17, 17, 20 }, // SHOP_ITEM_BEEF_NOODLES - { 6, 17, 17, 20 }, // SHOP_ITEM_FRIED_RICE_NOODLES - { 4, 13, 13, 15 }, // SHOP_ITEM_WONTON_SOUP - { 5, 14, 14, 16 }, // SHOP_ITEM_MEATBALL_SOUP - { 4, 11, 19, 11 }, // SHOP_ITEM_FRUIT_JUICE - { 4, 10, 14, 10 }, // SHOP_ITEM_SOYBEAN_MILK - { 3, 11, 14, 11 }, // SHOP_ITEM_SUJEONGGWA - { 5, 19, 19, 17 }, // SHOP_ITEM_SUB_SANDWICH - { 4, 8, 8, 8 }, // SHOP_ITEM_COOKIE - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_BOWL_RED - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_DRINK_CARTON - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_JUICE_CUP - { 5, 16, 16, 20 }, // SHOP_ITEM_ROAST_SAUSAGE - { 0, 0, 0, 0 }, // SHOP_ITEM_EMPTY_BOWL_BLUE -}; - -// rct2: 0x00982358 -const money8 DefaultShopItemPrice[SHOP_ITEM_COUNT] = { - MONEY(0, 90), // SHOP_ITEM_BALLOON - MONEY(2, 50), // SHOP_ITEM_TOY - MONEY(0, 60), // SHOP_ITEM_MAP - MONEY(0, 00), // SHOP_ITEM_PHOTO - MONEY(2, 50), // SHOP_ITEM_UMBRELLA - MONEY(1, 20), // SHOP_ITEM_DRINK - MONEY(1, 50), // SHOP_ITEM_BURGER - MONEY(1, 50), // SHOP_ITEM_CHIPS - MONEY(0, 90), // SHOP_ITEM_ICE_CREAM - MONEY(0, 80), // SHOP_ITEM_CANDYFLOSS - MONEY(0, 00), // SHOP_ITEM_EMPTY_CAN - MONEY(0, 00), // SHOP_ITEM_RUBBISH - MONEY(0, 00), // SHOP_ITEM_EMPTY_BURGER_BOX - MONEY(1, 60), // SHOP_ITEM_PIZZA - MONEY(0, 00), // SHOP_ITEM_VOUCHER - MONEY(1, 20), // SHOP_ITEM_POPCORN - MONEY(1, 00), // SHOP_ITEM_HOT_DOG - MONEY(1, 50), // SHOP_ITEM_TENTACLE - MONEY(1, 50), // SHOP_ITEM_HAT - MONEY(0, 70), // SHOP_ITEM_TOFFEE_APPLE - MONEY(3, 00), // SHOP_ITEM_TSHIRT - MONEY(0, 70), // SHOP_ITEM_DOUGHNUT - MONEY(1, 20), // SHOP_ITEM_COFFEE - MONEY(0, 00), // SHOP_ITEM_EMPTY_CUP - MONEY(1, 50), // SHOP_ITEM_CHICKEN - MONEY(1, 20), // SHOP_ITEM_LEMONADE - MONEY(0, 00), // SHOP_ITEM_EMPTY_BOX - MONEY(0, 00), // SHOP_ITEM_EMPTY_BOTTLE - MONEY(0, 00), // 28 - MONEY(0, 00), // 29 - MONEY(0, 00), // 30 - MONEY(0, 00), // 31 - MONEY(0, 00), // SHOP_ITEM_PHOTO2 - MONEY(0, 00), // SHOP_ITEM_PHOTO3 - MONEY(0, 00), // SHOP_ITEM_PHOTO4 - MONEY(1, 10), // SHOP_ITEM_PRETZEL - MONEY(1, 20), // SHOP_ITEM_CHOCOLATE - MONEY(1, 10), // SHOP_ITEM_ICED_TEA - MONEY(1, 20), // SHOP_ITEM_FUNNEL_CAKE - MONEY(1, 50), // SHOP_ITEM_SUNGLASSES - MONEY(1, 50), // SHOP_ITEM_BEEF_NOODLES - MONEY(1, 50), // SHOP_ITEM_FRIED_RICE_NOODLES - MONEY(1, 50), // SHOP_ITEM_WONTON_SOUP - MONEY(1, 50), // SHOP_ITEM_MEATBALL_SOUP - MONEY(1, 20), // SHOP_ITEM_FRUIT_JUICE - MONEY(1, 20), // SHOP_ITEM_SOYBEAN_MILK - MONEY(1, 20), // SHOP_ITEM_SUJEONGGWA - MONEY(1, 50), // SHOP_ITEM_SUB_SANDWICH - MONEY(0, 70), // SHOP_ITEM_COOKIE - MONEY(0, 00), // SHOP_ITEM_EMPTY_BOWL_RED - MONEY(0, 00), // SHOP_ITEM_EMPTY_DRINK_CARTON - MONEY(0, 00), // SHOP_ITEM_EMPTY_JUICE_CUP - MONEY(1, 50), // SHOP_ITEM_ROAST_SAUSAGE - MONEY(0, 00), // SHOP_ITEM_EMPTY_BOWL_BLUE - MONEY(0, 00), // 54 - MONEY(0, 00), // 55 -}; - // clang-format off -const rct_shop_item_string_types ShopItemStringIds[SHOP_ITEM_COUNT] = -{ - { STR_SHOP_ITEM_PRICE_LABEL_BALLOON, STR_SHOP_ITEM_SINGULAR_BALLOON, STR_SHOP_ITEM_PLURAL_BALLOON, STR_SHOP_ITEM_INDEFINITE_BALLOON, STR_SHOP_ITEM_DISPLAY_BALLOON }, - { STR_SHOP_ITEM_PRICE_LABEL_CUDDLY_TOY, STR_SHOP_ITEM_SINGULAR_CUDDLY_TOY, STR_SHOP_ITEM_PLURAL_CUDDLY_TOY, STR_SHOP_ITEM_INDEFINITE_CUDDLY_TOY, STR_SHOP_ITEM_DISPLAY_CUDDLY_TOY }, - { STR_SHOP_ITEM_PRICE_LABEL_PARK_MAP, STR_SHOP_ITEM_SINGULAR_PARK_MAP, STR_SHOP_ITEM_PLURAL_PARK_MAP, STR_SHOP_ITEM_INDEFINITE_PARK_MAP, STR_SHOP_ITEM_DISPLAY_PARK_MAP }, - { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO }, - { STR_SHOP_ITEM_PRICE_LABEL_UMBRELLA, STR_SHOP_ITEM_SINGULAR_UMBRELLA, STR_SHOP_ITEM_PLURAL_UMBRELLA, STR_SHOP_ITEM_INDEFINITE_UMBRELLA, STR_SHOP_ITEM_DISPLAY_UMBRELLA }, - { STR_SHOP_ITEM_PRICE_LABEL_DRINK, STR_SHOP_ITEM_SINGULAR_DRINK, STR_SHOP_ITEM_PLURAL_DRINK, STR_SHOP_ITEM_INDEFINITE_DRINK, STR_SHOP_ITEM_DISPLAY_DRINK }, - { STR_SHOP_ITEM_PRICE_LABEL_BURGER, STR_SHOP_ITEM_SINGULAR_BURGER, STR_SHOP_ITEM_PLURAL_BURGER, STR_SHOP_ITEM_INDEFINITE_BURGER, STR_SHOP_ITEM_DISPLAY_BURGER }, - { STR_SHOP_ITEM_PRICE_LABEL_CHIPS, STR_SHOP_ITEM_SINGULAR_CHIPS, STR_SHOP_ITEM_PLURAL_CHIPS, STR_SHOP_ITEM_INDEFINITE_CHIPS, STR_SHOP_ITEM_DISPLAY_CHIPS }, - { STR_SHOP_ITEM_PRICE_LABEL_ICE_CREAM, STR_SHOP_ITEM_SINGULAR_ICE_CREAM, STR_SHOP_ITEM_PLURAL_ICE_CREAM, STR_SHOP_ITEM_INDEFINITE_ICE_CREAM, STR_SHOP_ITEM_DISPLAY_ICE_CREAM }, - { STR_SHOP_ITEM_PRICE_LABEL_CANDYFLOSS, STR_SHOP_ITEM_SINGULAR_CANDYFLOSS, STR_SHOP_ITEM_PLURAL_CANDYFLOSS, STR_SHOP_ITEM_INDEFINITE_CANDYFLOSS, STR_SHOP_ITEM_DISPLAY_CANDYFLOSS }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_CAN, STR_SHOP_ITEM_SINGULAR_EMPTY_CAN, STR_SHOP_ITEM_PLURAL_EMPTY_CAN, STR_SHOP_ITEM_INDEFINITE_EMPTY_CAN, STR_SHOP_ITEM_DISPLAY_EMPTY_CAN }, - { STR_SHOP_ITEM_PRICE_LABEL_RUBBISH, STR_SHOP_ITEM_SINGULAR_RUBBISH, STR_SHOP_ITEM_PLURAL_RUBBISH, STR_SHOP_ITEM_INDEFINITE_RUBBISH, STR_SHOP_ITEM_DISPLAY_RUBBISH }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BURGER_BOX, STR_SHOP_ITEM_SINGULAR_EMPTY_BURGER_BOX, STR_SHOP_ITEM_PLURAL_EMPTY_BURGER_BOX, STR_SHOP_ITEM_INDEFINITE_EMPTY_BURGER_BOX, STR_SHOP_ITEM_DISPLAY_EMPTY_BURGER_BOX }, - { STR_SHOP_ITEM_PRICE_LABEL_PIZZA, STR_SHOP_ITEM_SINGULAR_PIZZA, STR_SHOP_ITEM_PLURAL_PIZZA, STR_SHOP_ITEM_INDEFINITE_PIZZA, STR_SHOP_ITEM_DISPLAY_PIZZA }, - { STR_SHOP_ITEM_PRICE_LABEL_VOUCHER, STR_SHOP_ITEM_SINGULAR_VOUCHER, STR_SHOP_ITEM_PLURAL_VOUCHER, STR_SHOP_ITEM_INDEFINITE_VOUCHER, STR_SHOP_ITEM_DISPLAY_VOUCHER }, - { STR_SHOP_ITEM_PRICE_LABEL_POPCORN, STR_SHOP_ITEM_SINGULAR_POPCORN, STR_SHOP_ITEM_PLURAL_POPCORN, STR_SHOP_ITEM_INDEFINITE_POPCORN, STR_SHOP_ITEM_DISPLAY_POPCORN }, - { STR_SHOP_ITEM_PRICE_LABEL_HOT_DOG, STR_SHOP_ITEM_SINGULAR_HOT_DOG, STR_SHOP_ITEM_PLURAL_HOT_DOG, STR_SHOP_ITEM_INDEFINITE_HOT_DOG, STR_SHOP_ITEM_DISPLAY_HOT_DOG }, - { STR_SHOP_ITEM_PRICE_LABEL_TENTACLE, STR_SHOP_ITEM_SINGULAR_TENTACLE, STR_SHOP_ITEM_PLURAL_TENTACLE, STR_SHOP_ITEM_INDEFINITE_TENTACLE, STR_SHOP_ITEM_DISPLAY_TENTACLE }, - { STR_SHOP_ITEM_PRICE_LABEL_HAT, STR_SHOP_ITEM_SINGULAR_HAT, STR_SHOP_ITEM_PLURAL_HAT, STR_SHOP_ITEM_INDEFINITE_HAT, STR_SHOP_ITEM_DISPLAY_HAT }, - { STR_SHOP_ITEM_PRICE_LABEL_TOFFEE_APPLE, STR_SHOP_ITEM_SINGULAR_TOFFEE_APPLE, STR_SHOP_ITEM_PLURAL_TOFFEE_APPLE, STR_SHOP_ITEM_INDEFINITE_TOFFEE_APPLE, STR_SHOP_ITEM_DISPLAY_TOFFEE_APPLE }, - { STR_SHOP_ITEM_PRICE_LABEL_T_SHIRT, STR_SHOP_ITEM_SINGULAR_T_SHIRT, STR_SHOP_ITEM_PLURAL_T_SHIRT, STR_SHOP_ITEM_INDEFINITE_T_SHIRT, STR_SHOP_ITEM_DISPLAY_T_SHIRT }, - { STR_SHOP_ITEM_PRICE_LABEL_DOUGHNUT, STR_SHOP_ITEM_SINGULAR_DOUGHNUT, STR_SHOP_ITEM_PLURAL_DOUGHNUT, STR_SHOP_ITEM_INDEFINITE_DOUGHNUT, STR_SHOP_ITEM_DISPLAY_DOUGHNUT }, - { STR_SHOP_ITEM_PRICE_LABEL_COFFEE, STR_SHOP_ITEM_SINGULAR_COFFEE, STR_SHOP_ITEM_PLURAL_COFFEE, STR_SHOP_ITEM_INDEFINITE_COFFEE, STR_SHOP_ITEM_DISPLAY_COFFEE }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_CUP, STR_SHOP_ITEM_SINGULAR_EMPTY_CUP, STR_SHOP_ITEM_PLURAL_EMPTY_CUP, STR_SHOP_ITEM_INDEFINITE_EMPTY_CUP, STR_SHOP_ITEM_DISPLAY_EMPTY_CUP }, - { STR_SHOP_ITEM_PRICE_LABEL_FRIED_CHICKEN, STR_SHOP_ITEM_SINGULAR_FRIED_CHICKEN, STR_SHOP_ITEM_PLURAL_FRIED_CHICKEN, STR_SHOP_ITEM_INDEFINITE_FRIED_CHICKEN, STR_SHOP_ITEM_DISPLAY_FRIED_CHICKEN }, - { STR_SHOP_ITEM_PRICE_LABEL_LEMONADE, STR_SHOP_ITEM_SINGULAR_LEMONADE, STR_SHOP_ITEM_PLURAL_LEMONADE, STR_SHOP_ITEM_INDEFINITE_LEMONADE, STR_SHOP_ITEM_DISPLAY_LEMONADE }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOX, STR_SHOP_ITEM_SINGULAR_EMPTY_BOX, STR_SHOP_ITEM_PLURAL_EMPTY_BOX, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOX, STR_SHOP_ITEM_DISPLAY_EMPTY_BOX }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOTTLE, STR_SHOP_ITEM_SINGULAR_EMPTY_BOTTLE, STR_SHOP_ITEM_PLURAL_EMPTY_BOTTLE, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOTTLE, STR_SHOP_ITEM_DISPLAY_EMPTY_BOTTLE }, - { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE }, - { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE }, - { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE }, - { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE }, - { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO }, - { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO }, - { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO }, - { STR_SHOP_ITEM_PRICE_LABEL_PRETZEL, STR_SHOP_ITEM_SINGULAR_PRETZEL, STR_SHOP_ITEM_PLURAL_PRETZEL, STR_SHOP_ITEM_INDEFINITE_PRETZEL, STR_SHOP_ITEM_DISPLAY_PRETZEL }, - { STR_SHOP_ITEM_PRICE_LABEL_HOT_CHOCOLATE, STR_SHOP_ITEM_SINGULAR_HOT_CHOCOLATE, STR_SHOP_ITEM_PLURAL_HOT_CHOCOLATE, STR_SHOP_ITEM_INDEFINITE_HOT_CHOCOLATE, STR_SHOP_ITEM_DISPLAY_HOT_CHOCOLATE }, - { STR_SHOP_ITEM_PRICE_LABEL_ICED_TEA, STR_SHOP_ITEM_SINGULAR_ICED_TEA, STR_SHOP_ITEM_PLURAL_ICED_TEA, STR_SHOP_ITEM_INDEFINITE_ICED_TEA, STR_SHOP_ITEM_DISPLAY_ICED_TEA }, - { STR_SHOP_ITEM_PRICE_LABEL_FUNNEL_CAKE, STR_SHOP_ITEM_SINGULAR_FUNNEL_CAKE, STR_SHOP_ITEM_PLURAL_FUNNEL_CAKE, STR_SHOP_ITEM_INDEFINITE_FUNNEL_CAKE, STR_SHOP_ITEM_DISPLAY_FUNNEL_CAKE }, - { STR_SHOP_ITEM_PRICE_LABEL_SUNGLASSES, STR_SHOP_ITEM_SINGULAR_SUNGLASSES, STR_SHOP_ITEM_PLURAL_SUNGLASSES, STR_SHOP_ITEM_INDEFINITE_SUNGLASSES, STR_SHOP_ITEM_DISPLAY_SUNGLASSES }, - { STR_SHOP_ITEM_PRICE_LABEL_BEEF_NOODLES, STR_SHOP_ITEM_SINGULAR_BEEF_NOODLES, STR_SHOP_ITEM_PLURAL_BEEF_NOODLES, STR_SHOP_ITEM_INDEFINITE_BEEF_NOODLES, STR_SHOP_ITEM_DISPLAY_BEEF_NOODLES }, - { STR_SHOP_ITEM_PRICE_LABEL_FRIED_RICE_NOODLES, STR_SHOP_ITEM_SINGULAR_FRIED_RICE_NOODLES, STR_SHOP_ITEM_PLURAL_FRIED_RICE_NOODLES, STR_SHOP_ITEM_INDEFINITE_FRIED_RICE_NOODLES, STR_SHOP_ITEM_DISPLAY_FRIED_RICE_NOODLES }, - { STR_SHOP_ITEM_PRICE_LABEL_WONTON_SOUP, STR_SHOP_ITEM_SINGULAR_WONTON_SOUP, STR_SHOP_ITEM_PLURAL_WONTON_SOUP, STR_SHOP_ITEM_INDEFINITE_WONTON_SOUP, STR_SHOP_ITEM_DISPLAY_WONTON_SOUP }, - { STR_SHOP_ITEM_PRICE_LABEL_MEATBALL_SOUP, STR_SHOP_ITEM_SINGULAR_MEATBALL_SOUP, STR_SHOP_ITEM_PLURAL_MEATBALL_SOUP, STR_SHOP_ITEM_INDEFINITE_MEATBALL_SOUP, STR_SHOP_ITEM_DISPLAY_MEATBALL_SOUP }, - { STR_SHOP_ITEM_PRICE_LABEL_FRUIT_JUICE, STR_SHOP_ITEM_SINGULAR_FRUIT_JUICE, STR_SHOP_ITEM_PLURAL_FRUIT_JUICE, STR_SHOP_ITEM_INDEFINITE_FRUIT_JUICE, STR_SHOP_ITEM_DISPLAY_FRUIT_JUICE }, - { STR_SHOP_ITEM_PRICE_LABEL_SOYBEAN_MILK, STR_SHOP_ITEM_SINGULAR_SOYBEAN_MILK, STR_SHOP_ITEM_PLURAL_SOYBEAN_MILK, STR_SHOP_ITEM_INDEFINITE_SOYBEAN_MILK, STR_SHOP_ITEM_DISPLAY_SOYBEAN_MILK }, - { STR_SHOP_ITEM_PRICE_LABEL_SUJONGKWA, STR_SHOP_ITEM_SINGULAR_SUJONGKWA, STR_SHOP_ITEM_PLURAL_SUJONGKWA, STR_SHOP_ITEM_INDEFINITE_SUJONGKWA, STR_SHOP_ITEM_DISPLAY_SUJONGKWA }, - { STR_SHOP_ITEM_PRICE_LABEL_SUB_SANDWICH, STR_SHOP_ITEM_SINGULAR_SUB_SANDWICH, STR_SHOP_ITEM_PLURAL_SUB_SANDWICH, STR_SHOP_ITEM_INDEFINITE_SUB_SANDWICH, STR_SHOP_ITEM_DISPLAY_SUB_SANDWICH }, - { STR_SHOP_ITEM_PRICE_LABEL_COOKIE, STR_SHOP_ITEM_SINGULAR_COOKIE, STR_SHOP_ITEM_PLURAL_COOKIE, STR_SHOP_ITEM_INDEFINITE_COOKIE, STR_SHOP_ITEM_DISPLAY_COOKIE }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOWL_RED, STR_SHOP_ITEM_SINGULAR_EMPTY_BOWL_RED, STR_SHOP_ITEM_PLURAL_EMPTY_BOWL_RED, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOWL_RED, STR_SHOP_ITEM_DISPLAY_EMPTY_BOWL_RED }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_SINGULAR_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_PLURAL_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_INDEFINITE_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_DISPLAY_EMPTY_DRINK_CARTON }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_JUICE_CUP, STR_SHOP_ITEM_SINGULAR_EMPTY_JUICE_CUP, STR_SHOP_ITEM_PLURAL_EMPTY_JUICE_CUP, STR_SHOP_ITEM_INDEFINITE_EMPTY_JUICE_CUP, STR_SHOP_ITEM_DISPLAY_EMPTY_JUICE_CUP }, - { STR_SHOP_ITEM_PRICE_LABEL_ROAST_SAUSAGE, STR_SHOP_ITEM_SINGULAR_ROAST_SAUSAGE, STR_SHOP_ITEM_PLURAL_ROAST_SAUSAGE, STR_SHOP_ITEM_INDEFINITE_ROAST_SAUSAGE, STR_SHOP_ITEM_DISPLAY_ROAST_SAUSAGE }, - { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_SINGULAR_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_PLURAL_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_DISPLAY_EMPTY_BOWL_BLUE }, +/** rct2: 0x00982164 (cost, base value, hot and cold value); 0x00982358 (default price) */ +const ShopItemDescriptor ShopItems[SHOP_ITEM_COUNT] = { + // Item, Cost, Base value, Hot value, Cold value, Default price, Image, Price label, Singular, Plural, Indefinite, Display (in guest inventory) + /* SHOP_ITEM_BALLOON */ { 3, 14, 14, 14, MONEY(0, 90), SPR_SHOP_ITEM_BALLOON, { STR_SHOP_ITEM_PRICE_LABEL_BALLOON, STR_SHOP_ITEM_SINGULAR_BALLOON, STR_SHOP_ITEM_PLURAL_BALLOON, STR_SHOP_ITEM_INDEFINITE_BALLOON, STR_SHOP_ITEM_DISPLAY_BALLOON } }, + /* SHOP_ITEM_TOY */ { 15, 30, 30, 30, MONEY(2, 50), SPR_SHOP_ITEM_TOY, { STR_SHOP_ITEM_PRICE_LABEL_CUDDLY_TOY, STR_SHOP_ITEM_SINGULAR_CUDDLY_TOY, STR_SHOP_ITEM_PLURAL_CUDDLY_TOY, STR_SHOP_ITEM_INDEFINITE_CUDDLY_TOY, STR_SHOP_ITEM_DISPLAY_CUDDLY_TOY } }, + /* SHOP_ITEM_MAP */ { 1, 7, 7, 8, MONEY(0, 60), SPR_SHOP_ITEM_MAP, { STR_SHOP_ITEM_PRICE_LABEL_PARK_MAP, STR_SHOP_ITEM_SINGULAR_PARK_MAP, STR_SHOP_ITEM_PLURAL_PARK_MAP, STR_SHOP_ITEM_INDEFINITE_PARK_MAP, STR_SHOP_ITEM_DISPLAY_PARK_MAP } }, + /* SHOP_ITEM_PHOTO */ { 2, 30, 30, 30, MONEY(0, 00), SPR_SHOP_ITEM_PHOTO, { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO } }, + /* SHOP_ITEM_UMBRELLA */ { 20, 35, 25, 50, MONEY(2, 50), SPR_SHOP_ITEM_UMBRELLA, { STR_SHOP_ITEM_PRICE_LABEL_UMBRELLA, STR_SHOP_ITEM_SINGULAR_UMBRELLA, STR_SHOP_ITEM_PLURAL_UMBRELLA, STR_SHOP_ITEM_INDEFINITE_UMBRELLA, STR_SHOP_ITEM_DISPLAY_UMBRELLA } }, + /* SHOP_ITEM_DRINK */ { 3, 12, 20, 10, MONEY(1, 20), SPR_SHOP_ITEM_DRINK, { STR_SHOP_ITEM_PRICE_LABEL_DRINK, STR_SHOP_ITEM_SINGULAR_DRINK, STR_SHOP_ITEM_PLURAL_DRINK, STR_SHOP_ITEM_INDEFINITE_DRINK, STR_SHOP_ITEM_DISPLAY_DRINK } }, + /* SHOP_ITEM_BURGER */ { 5, 19, 19, 22, MONEY(1, 50), SPR_SHOP_ITEM_BURGER, { STR_SHOP_ITEM_PRICE_LABEL_BURGER, STR_SHOP_ITEM_SINGULAR_BURGER, STR_SHOP_ITEM_PLURAL_BURGER, STR_SHOP_ITEM_INDEFINITE_BURGER, STR_SHOP_ITEM_DISPLAY_BURGER } }, + /* SHOP_ITEM_CHIPS */ { 4, 16, 16, 18, MONEY(1, 50), SPR_SHOP_ITEM_CHIPS, { STR_SHOP_ITEM_PRICE_LABEL_CHIPS, STR_SHOP_ITEM_SINGULAR_CHIPS, STR_SHOP_ITEM_PLURAL_CHIPS, STR_SHOP_ITEM_INDEFINITE_CHIPS, STR_SHOP_ITEM_DISPLAY_CHIPS } }, + /* SHOP_ITEM_ICE_CREAM */ { 4, 10, 15, 6, MONEY(0, 90), SPR_SHOP_ITEM_ICE_CREAM, { STR_SHOP_ITEM_PRICE_LABEL_ICE_CREAM, STR_SHOP_ITEM_SINGULAR_ICE_CREAM, STR_SHOP_ITEM_PLURAL_ICE_CREAM, STR_SHOP_ITEM_INDEFINITE_ICE_CREAM, STR_SHOP_ITEM_DISPLAY_ICE_CREAM } }, + /* SHOP_ITEM_CANDYFLOSS */ { 3, 9, 9, 6, MONEY(0, 80), SPR_SHOP_ITEM_CANDYFLOSS, { STR_SHOP_ITEM_PRICE_LABEL_CANDYFLOSS, STR_SHOP_ITEM_SINGULAR_CANDYFLOSS, STR_SHOP_ITEM_PLURAL_CANDYFLOSS, STR_SHOP_ITEM_INDEFINITE_CANDYFLOSS, STR_SHOP_ITEM_DISPLAY_CANDYFLOSS } }, + /* SHOP_ITEM_EMPTY_CAN */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_CAN, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_CAN, STR_SHOP_ITEM_SINGULAR_EMPTY_CAN, STR_SHOP_ITEM_PLURAL_EMPTY_CAN, STR_SHOP_ITEM_INDEFINITE_EMPTY_CAN, STR_SHOP_ITEM_DISPLAY_EMPTY_CAN } }, + /* SHOP_ITEM_RUBBISH */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_RUBBISH, { STR_SHOP_ITEM_PRICE_LABEL_RUBBISH, STR_SHOP_ITEM_SINGULAR_RUBBISH, STR_SHOP_ITEM_PLURAL_RUBBISH, STR_SHOP_ITEM_INDEFINITE_RUBBISH, STR_SHOP_ITEM_DISPLAY_RUBBISH } }, + /* SHOP_ITEM_EMPTY_BURGER_BOX */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_BURGER_BOX, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BURGER_BOX, STR_SHOP_ITEM_SINGULAR_EMPTY_BURGER_BOX, STR_SHOP_ITEM_PLURAL_EMPTY_BURGER_BOX, STR_SHOP_ITEM_INDEFINITE_EMPTY_BURGER_BOX, STR_SHOP_ITEM_DISPLAY_EMPTY_BURGER_BOX } }, + /* SHOP_ITEM_PIZZA */ { 6, 21, 21, 25, MONEY(1, 60), SPR_SHOP_ITEM_PIZZA, { STR_SHOP_ITEM_PRICE_LABEL_PIZZA, STR_SHOP_ITEM_SINGULAR_PIZZA, STR_SHOP_ITEM_PLURAL_PIZZA, STR_SHOP_ITEM_INDEFINITE_PIZZA, STR_SHOP_ITEM_DISPLAY_PIZZA } }, + /* SHOP_ITEM_VOUCHER */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_VOUCHER, { STR_SHOP_ITEM_PRICE_LABEL_VOUCHER, STR_SHOP_ITEM_SINGULAR_VOUCHER, STR_SHOP_ITEM_PLURAL_VOUCHER, STR_SHOP_ITEM_INDEFINITE_VOUCHER, STR_SHOP_ITEM_DISPLAY_VOUCHER } }, + /* SHOP_ITEM_POPCORN */ { 5, 13, 13, 11, MONEY(1, 20), SPR_SHOP_ITEM_POPCORN, { STR_SHOP_ITEM_PRICE_LABEL_POPCORN, STR_SHOP_ITEM_SINGULAR_POPCORN, STR_SHOP_ITEM_PLURAL_POPCORN, STR_SHOP_ITEM_INDEFINITE_POPCORN, STR_SHOP_ITEM_DISPLAY_POPCORN } }, + /* SHOP_ITEM_HOT_DOG */ { 5, 17, 17, 20, MONEY(1, 00), SPR_SHOP_ITEM_HOT_DOG, { STR_SHOP_ITEM_PRICE_LABEL_HOT_DOG, STR_SHOP_ITEM_SINGULAR_HOT_DOG, STR_SHOP_ITEM_PLURAL_HOT_DOG, STR_SHOP_ITEM_INDEFINITE_HOT_DOG, STR_SHOP_ITEM_DISPLAY_HOT_DOG } }, + /* SHOP_ITEM_TENTACLE */ { 11, 22, 20, 18, MONEY(1, 50), SPR_SHOP_ITEM_TENTACLE, { STR_SHOP_ITEM_PRICE_LABEL_TENTACLE, STR_SHOP_ITEM_SINGULAR_TENTACLE, STR_SHOP_ITEM_PLURAL_TENTACLE, STR_SHOP_ITEM_INDEFINITE_TENTACLE, STR_SHOP_ITEM_DISPLAY_TENTACLE } }, + /* SHOP_ITEM_HAT */ { 9, 27, 32, 24, MONEY(1, 50), SPR_SHOP_ITEM_HAT, { STR_SHOP_ITEM_PRICE_LABEL_HAT, STR_SHOP_ITEM_SINGULAR_HAT, STR_SHOP_ITEM_PLURAL_HAT, STR_SHOP_ITEM_INDEFINITE_HAT, STR_SHOP_ITEM_DISPLAY_HAT } }, + /* SHOP_ITEM_TOFFEE_APPLE */ { 4, 10, 10, 10, MONEY(0, 70), SPR_SHOP_ITEM_TOFFEE_APPLE, { STR_SHOP_ITEM_PRICE_LABEL_TOFFEE_APPLE, STR_SHOP_ITEM_SINGULAR_TOFFEE_APPLE, STR_SHOP_ITEM_PLURAL_TOFFEE_APPLE, STR_SHOP_ITEM_INDEFINITE_TOFFEE_APPLE, STR_SHOP_ITEM_DISPLAY_TOFFEE_APPLE } }, + /* SHOP_ITEM_TSHIRT */ { 20, 37, 37, 37, MONEY(3, 00), SPR_SHOP_ITEM_TSHIRT, { STR_SHOP_ITEM_PRICE_LABEL_T_SHIRT, STR_SHOP_ITEM_SINGULAR_T_SHIRT, STR_SHOP_ITEM_PLURAL_T_SHIRT, STR_SHOP_ITEM_INDEFINITE_T_SHIRT, STR_SHOP_ITEM_DISPLAY_T_SHIRT } }, + /* SHOP_ITEM_DOUGHNUT */ { 4, 8, 7, 10, MONEY(0, 70), SPR_SHOP_ITEM_DOUGHNUT, { STR_SHOP_ITEM_PRICE_LABEL_DOUGHNUT, STR_SHOP_ITEM_SINGULAR_DOUGHNUT, STR_SHOP_ITEM_PLURAL_DOUGHNUT, STR_SHOP_ITEM_INDEFINITE_DOUGHNUT, STR_SHOP_ITEM_DISPLAY_DOUGHNUT } }, + /* SHOP_ITEM_COFFEE */ { 3, 11, 15, 20, MONEY(1, 20), SPR_SHOP_ITEM_COFFEE, { STR_SHOP_ITEM_PRICE_LABEL_COFFEE, STR_SHOP_ITEM_SINGULAR_COFFEE, STR_SHOP_ITEM_PLURAL_COFFEE, STR_SHOP_ITEM_INDEFINITE_COFFEE, STR_SHOP_ITEM_DISPLAY_COFFEE } }, + /* SHOP_ITEM_EMPTY_CUP */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_CUP, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_CUP, STR_SHOP_ITEM_SINGULAR_EMPTY_CUP, STR_SHOP_ITEM_PLURAL_EMPTY_CUP, STR_SHOP_ITEM_INDEFINITE_EMPTY_CUP, STR_SHOP_ITEM_DISPLAY_EMPTY_CUP } }, + /* SHOP_ITEM_CHICKEN */ { 5, 19, 19, 22, MONEY(1, 50), SPR_SHOP_ITEM_CHICKEN, { STR_SHOP_ITEM_PRICE_LABEL_FRIED_CHICKEN, STR_SHOP_ITEM_SINGULAR_FRIED_CHICKEN, STR_SHOP_ITEM_PLURAL_FRIED_CHICKEN, STR_SHOP_ITEM_INDEFINITE_FRIED_CHICKEN, STR_SHOP_ITEM_DISPLAY_FRIED_CHICKEN } }, + /* SHOP_ITEM_LEMONADE */ { 4, 11, 21, 10, MONEY(1, 20), SPR_SHOP_ITEM_LEMONADE, { STR_SHOP_ITEM_PRICE_LABEL_LEMONADE, STR_SHOP_ITEM_SINGULAR_LEMONADE, STR_SHOP_ITEM_PLURAL_LEMONADE, STR_SHOP_ITEM_INDEFINITE_LEMONADE, STR_SHOP_ITEM_DISPLAY_LEMONADE } }, + /* SHOP_ITEM_EMPTY_BOX */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_BOX, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOX, STR_SHOP_ITEM_SINGULAR_EMPTY_BOX, STR_SHOP_ITEM_PLURAL_EMPTY_BOX, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOX, STR_SHOP_ITEM_DISPLAY_EMPTY_BOX } }, + /* SHOP_ITEM_EMPTY_BOTTLE */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_BOTTLE, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOTTLE, STR_SHOP_ITEM_SINGULAR_EMPTY_BOTTLE, STR_SHOP_ITEM_PLURAL_EMPTY_BOTTLE, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOTTLE, STR_SHOP_ITEM_DISPLAY_EMPTY_BOTTLE } }, + /* 28 */ { 0, 0, 0, 0, MONEY(0, 00), 0, { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE } }, + /* 29 */ { 0, 0, 0, 0, MONEY(0, 00), 0, { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE } }, + /* 30 */ { 0, 0, 0, 0, MONEY(0, 00), 0, { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE } }, + /* SHOP_ITEM_ADMISSION */ { 0, 0, 0, 0, MONEY(0, 00), 0, { STR_NONE, STR_NONE, STR_NONE, STR_NONE, STR_NONE } }, + /* SHOP_ITEM_PHOTO2 */ { 2, 30, 30, 30, MONEY(0, 00), SPR_SHOP_ITEM_PHOTO2, { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO } }, + /* SHOP_ITEM_PHOTO3 */ { 2, 30, 30, 30, MONEY(0, 00), SPR_SHOP_ITEM_PHOTO3, { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO } }, + /* SHOP_ITEM_PHOTO4 */ { 2, 30, 30, 30, MONEY(0, 00), SPR_SHOP_ITEM_PHOTO4, { STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO, STR_SHOP_ITEM_SINGULAR_ON_RIDE_PHOTO, STR_SHOP_ITEM_PLURAL_ON_RIDE_PHOTO, STR_SHOP_ITEM_INDEFINITE_ON_RIDE_PHOTO, STR_SHOP_ITEM_DISPLAY_ON_RIDE_PHOTO } }, + /* SHOP_ITEM_PRETZEL */ { 5, 11, 11, 11, MONEY(1, 10), SPR_SHOP_ITEM_PRETZEL, { STR_SHOP_ITEM_PRICE_LABEL_PRETZEL, STR_SHOP_ITEM_SINGULAR_PRETZEL, STR_SHOP_ITEM_PLURAL_PRETZEL, STR_SHOP_ITEM_INDEFINITE_PRETZEL, STR_SHOP_ITEM_DISPLAY_PRETZEL } }, + /* SHOP_ITEM_CHOCOLATE */ { 4, 13, 13, 20, MONEY(1, 20), SPR_SHOP_ITEM_CHOCOLATE, { STR_SHOP_ITEM_PRICE_LABEL_HOT_CHOCOLATE, STR_SHOP_ITEM_SINGULAR_HOT_CHOCOLATE, STR_SHOP_ITEM_PLURAL_HOT_CHOCOLATE, STR_SHOP_ITEM_INDEFINITE_HOT_CHOCOLATE, STR_SHOP_ITEM_DISPLAY_HOT_CHOCOLATE } }, + /* SHOP_ITEM_ICED_TEA */ { 3, 10, 20, 10, MONEY(1, 10), SPR_SHOP_ITEM_ICED_TEA, { STR_SHOP_ITEM_PRICE_LABEL_ICED_TEA, STR_SHOP_ITEM_SINGULAR_ICED_TEA, STR_SHOP_ITEM_PLURAL_ICED_TEA, STR_SHOP_ITEM_INDEFINITE_ICED_TEA, STR_SHOP_ITEM_DISPLAY_ICED_TEA } }, + /* SHOP_ITEM_FUNNEL_CAKE */ { 5, 13, 11, 14, MONEY(1, 20), SPR_SHOP_ITEM_FUNNEL_CAKE, { STR_SHOP_ITEM_PRICE_LABEL_FUNNEL_CAKE, STR_SHOP_ITEM_SINGULAR_FUNNEL_CAKE, STR_SHOP_ITEM_PLURAL_FUNNEL_CAKE, STR_SHOP_ITEM_INDEFINITE_FUNNEL_CAKE, STR_SHOP_ITEM_DISPLAY_FUNNEL_CAKE } }, + /* SHOP_ITEM_SUNGLASSES */ { 8, 15, 20, 12, MONEY(1, 50), SPR_SHOP_ITEM_SUNGLASSES, { STR_SHOP_ITEM_PRICE_LABEL_SUNGLASSES, STR_SHOP_ITEM_SINGULAR_SUNGLASSES, STR_SHOP_ITEM_PLURAL_SUNGLASSES, STR_SHOP_ITEM_INDEFINITE_SUNGLASSES, STR_SHOP_ITEM_DISPLAY_SUNGLASSES } }, + /* SHOP_ITEM_BEEF_NOODLES */ { 7, 17, 17, 20, MONEY(1, 50), SPR_SHOP_ITEM_BEEF_NOODLES, { STR_SHOP_ITEM_PRICE_LABEL_BEEF_NOODLES, STR_SHOP_ITEM_SINGULAR_BEEF_NOODLES, STR_SHOP_ITEM_PLURAL_BEEF_NOODLES, STR_SHOP_ITEM_INDEFINITE_BEEF_NOODLES, STR_SHOP_ITEM_DISPLAY_BEEF_NOODLES } }, + /* SHOP_ITEM_FRIED_RICE_NOODLES */ { 6, 17, 17, 20, MONEY(1, 50), SPR_SHOP_ITEM_FRIED_RICE_NOODLES, { STR_SHOP_ITEM_PRICE_LABEL_FRIED_RICE_NOODLES, STR_SHOP_ITEM_SINGULAR_FRIED_RICE_NOODLES, STR_SHOP_ITEM_PLURAL_FRIED_RICE_NOODLES, STR_SHOP_ITEM_INDEFINITE_FRIED_RICE_NOODLES, STR_SHOP_ITEM_DISPLAY_FRIED_RICE_NOODLES } }, + /* SHOP_ITEM_WONTON_SOUP */ { 4, 13, 13, 15, MONEY(1, 50), SPR_SHOP_ITEM_WONTON_SOUP, { STR_SHOP_ITEM_PRICE_LABEL_WONTON_SOUP, STR_SHOP_ITEM_SINGULAR_WONTON_SOUP, STR_SHOP_ITEM_PLURAL_WONTON_SOUP, STR_SHOP_ITEM_INDEFINITE_WONTON_SOUP, STR_SHOP_ITEM_DISPLAY_WONTON_SOUP } }, + /* SHOP_ITEM_MEATBALL_SOUP */ { 5, 14, 14, 16, MONEY(1, 50), SPR_SHOP_ITEM_MEATBALL_SOUP, { STR_SHOP_ITEM_PRICE_LABEL_MEATBALL_SOUP, STR_SHOP_ITEM_SINGULAR_MEATBALL_SOUP, STR_SHOP_ITEM_PLURAL_MEATBALL_SOUP, STR_SHOP_ITEM_INDEFINITE_MEATBALL_SOUP, STR_SHOP_ITEM_DISPLAY_MEATBALL_SOUP } }, + /* SHOP_ITEM_FRUIT_JUICE */ { 4, 11, 19, 11, MONEY(1, 20), SPR_SHOP_ITEM_FRUIT_JUICE, { STR_SHOP_ITEM_PRICE_LABEL_FRUIT_JUICE, STR_SHOP_ITEM_SINGULAR_FRUIT_JUICE, STR_SHOP_ITEM_PLURAL_FRUIT_JUICE, STR_SHOP_ITEM_INDEFINITE_FRUIT_JUICE, STR_SHOP_ITEM_DISPLAY_FRUIT_JUICE } }, + /* SHOP_ITEM_SOYBEAN_MILK */ { 4, 10, 14, 10, MONEY(1, 20), SPR_SHOP_ITEM_SOYBEAN_MILK, { STR_SHOP_ITEM_PRICE_LABEL_SOYBEAN_MILK, STR_SHOP_ITEM_SINGULAR_SOYBEAN_MILK, STR_SHOP_ITEM_PLURAL_SOYBEAN_MILK, STR_SHOP_ITEM_INDEFINITE_SOYBEAN_MILK, STR_SHOP_ITEM_DISPLAY_SOYBEAN_MILK } }, + /* SHOP_ITEM_SUJEONGGWA */ { 3, 11, 14, 11, MONEY(1, 20), SPR_SHOP_ITEM_SUJEONGGWA, { STR_SHOP_ITEM_PRICE_LABEL_SUJONGKWA, STR_SHOP_ITEM_SINGULAR_SUJONGKWA, STR_SHOP_ITEM_PLURAL_SUJONGKWA, STR_SHOP_ITEM_INDEFINITE_SUJONGKWA, STR_SHOP_ITEM_DISPLAY_SUJONGKWA } }, + /* SHOP_ITEM_SUB_SANDWICH */ { 5, 19, 19, 17, MONEY(1, 50), SPR_SHOP_ITEM_SUB_SANDWICH, { STR_SHOP_ITEM_PRICE_LABEL_SUB_SANDWICH, STR_SHOP_ITEM_SINGULAR_SUB_SANDWICH, STR_SHOP_ITEM_PLURAL_SUB_SANDWICH, STR_SHOP_ITEM_INDEFINITE_SUB_SANDWICH, STR_SHOP_ITEM_DISPLAY_SUB_SANDWICH } }, + /* SHOP_ITEM_COOKIE */ { 4, 8, 8, 8, MONEY(0, 70), SPR_SHOP_ITEM_COOKIE, { STR_SHOP_ITEM_PRICE_LABEL_COOKIE, STR_SHOP_ITEM_SINGULAR_COOKIE, STR_SHOP_ITEM_PLURAL_COOKIE, STR_SHOP_ITEM_INDEFINITE_COOKIE, STR_SHOP_ITEM_DISPLAY_COOKIE } }, + /* SHOP_ITEM_EMPTY_BOWL_RED */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_BOWL_RED, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOWL_RED, STR_SHOP_ITEM_SINGULAR_EMPTY_BOWL_RED, STR_SHOP_ITEM_PLURAL_EMPTY_BOWL_RED, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOWL_RED, STR_SHOP_ITEM_DISPLAY_EMPTY_BOWL_RED } }, + /* SHOP_ITEM_EMPTY_DRINK_CARTON */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_DRINK_CARTON, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_SINGULAR_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_PLURAL_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_INDEFINITE_EMPTY_DRINK_CARTON, STR_SHOP_ITEM_DISPLAY_EMPTY_DRINK_CARTON } }, + /* SHOP_ITEM_EMPTY_JUICE_CUP */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_JUICE_CUP, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_JUICE_CUP, STR_SHOP_ITEM_SINGULAR_EMPTY_JUICE_CUP, STR_SHOP_ITEM_PLURAL_EMPTY_JUICE_CUP, STR_SHOP_ITEM_INDEFINITE_EMPTY_JUICE_CUP, STR_SHOP_ITEM_DISPLAY_EMPTY_JUICE_CUP } }, + /* SHOP_ITEM_ROAST_SAUSAGE */ { 5, 16, 16, 20, MONEY(1, 50), SPR_SHOP_ITEM_ROAST_SAUSAGE, { STR_SHOP_ITEM_PRICE_LABEL_ROAST_SAUSAGE, STR_SHOP_ITEM_SINGULAR_ROAST_SAUSAGE, STR_SHOP_ITEM_PLURAL_ROAST_SAUSAGE, STR_SHOP_ITEM_INDEFINITE_ROAST_SAUSAGE, STR_SHOP_ITEM_DISPLAY_ROAST_SAUSAGE } }, + /* SHOP_ITEM_EMPTY_BOWL_BLUE */ { 0, 0, 0, 0, MONEY(0, 00), SPR_SHOP_ITEM_EMPTY_BOWL_BLUE, { STR_SHOP_ITEM_PRICE_LABEL_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_SINGULAR_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_PLURAL_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_INDEFINITE_EMPTY_BOWL_BLUE, STR_SHOP_ITEM_DISPLAY_EMPTY_BOWL_BLUE } }, }; // clang-format on -const uint32_t ShopItemImage[SHOP_ITEM_COUNT] = { - SPR_SHOP_ITEM_BALLOON, - SPR_SHOP_ITEM_TOY, - SPR_SHOP_ITEM_MAP, - SPR_SHOP_ITEM_PHOTO, - SPR_SHOP_ITEM_UMBRELLA, - SPR_SHOP_ITEM_DRINK, - SPR_SHOP_ITEM_BURGER, - SPR_SHOP_ITEM_CHIPS, - SPR_SHOP_ITEM_ICE_CREAM, - SPR_SHOP_ITEM_CANDYFLOSS, - SPR_SHOP_ITEM_EMPTY_CAN, - SPR_SHOP_ITEM_RUBBISH, - SPR_SHOP_ITEM_EMPTY_BURGER_BOX, - SPR_SHOP_ITEM_PIZZA, - SPR_SHOP_ITEM_VOUCHER, - SPR_SHOP_ITEM_POPCORN, - SPR_SHOP_ITEM_HOT_DOG, - SPR_SHOP_ITEM_TENTACLE, - SPR_SHOP_ITEM_HAT, - SPR_SHOP_ITEM_TOFFEE_APPLE, - SPR_SHOP_ITEM_TSHIRT, - SPR_SHOP_ITEM_DOUGHNUT, - SPR_SHOP_ITEM_COFFEE, - SPR_SHOP_ITEM_EMPTY_CUP, - SPR_SHOP_ITEM_CHICKEN, - SPR_SHOP_ITEM_LEMONADE, - SPR_SHOP_ITEM_EMPTY_BOX, - SPR_SHOP_ITEM_EMPTY_BOTTLE, - 0, // 28 - 0, // 29 - 0, // 30 - 0, // 31 - SPR_SHOP_ITEM_PHOTO2, - SPR_SHOP_ITEM_PHOTO3, - SPR_SHOP_ITEM_PHOTO4, - SPR_SHOP_ITEM_PRETZEL, - SPR_SHOP_ITEM_CHOCOLATE, - SPR_SHOP_ITEM_ICED_TEA, - SPR_SHOP_ITEM_FUNNEL_CAKE, - SPR_SHOP_ITEM_SUNGLASSES, - SPR_SHOP_ITEM_BEEF_NOODLES, - SPR_SHOP_ITEM_FRIED_RICE_NOODLES, - SPR_SHOP_ITEM_WONTON_SOUP, - SPR_SHOP_ITEM_MEATBALL_SOUP, - SPR_SHOP_ITEM_FRUIT_JUICE, - SPR_SHOP_ITEM_SOYBEAN_MILK, - SPR_SHOP_ITEM_SUJEONGGWA, - SPR_SHOP_ITEM_SUB_SANDWICH, - SPR_SHOP_ITEM_COOKIE, - SPR_SHOP_ITEM_EMPTY_BOWL_RED, - SPR_SHOP_ITEM_EMPTY_DRINK_CARTON, - SPR_SHOP_ITEM_EMPTY_JUICE_CUP, - SPR_SHOP_ITEM_ROAST_SAUSAGE, - SPR_SHOP_ITEM_EMPTY_BOWL_BLUE, -}; - -money32 get_shop_item_cost(int32_t shopItem) -{ - return ShopItemStats[shopItem].cost; -} - -money16 get_shop_base_value(int32_t shopItem) -{ - return ShopItemStats[shopItem].base_value; -} - -money16 get_shop_cold_value(int32_t shopItem) -{ - return ShopItemStats[shopItem].cold_value; -} - -money16 get_shop_hot_value(int32_t shopItem) -{ - return ShopItemStats[shopItem].hot_value; -} - money32 shop_item_get_common_price(Ride* forRide, int32_t shopItem) { rct_ride_entry* rideEntry; diff --git a/src/openrct2/ride/ShopItem.h b/src/openrct2/ride/ShopItem.h index c8a8ea67b5..5d22872562 100644 --- a/src/openrct2/ride/ShopItem.h +++ b/src/openrct2/ride/ShopItem.h @@ -70,33 +70,29 @@ enum SHOP_ITEM_NONE = 255 }; -struct rct_shop_item_stats +struct ShopItemStrings { - uint16_t cost; - uint16_t base_value; - uint16_t hot_value; - uint16_t cold_value; + rct_string_id PriceLabel; // Balloon price: + rct_string_id Singular; // Balloon + rct_string_id Plural; // Balloons + rct_string_id Indefinite; // a Balloon + rct_string_id Display; // "Diamond Heights" Balloon }; -struct rct_shop_item_string_types +struct ShopItemDescriptor { - rct_string_id price_label; // Balloon price: - rct_string_id singular; // Balloon - rct_string_id plural; // Balloons - rct_string_id indefinite; // a Balloon - rct_string_id display; // "Diamond Heights" Balloon + uint16_t Cost; + uint16_t BaseValue; + uint16_t HotValue; + uint16_t ColdValue; + money8 DefaultPrice; + uint32_t Image; + ShopItemStrings Naming; }; +extern const ShopItemDescriptor ShopItems[SHOP_ITEM_COUNT]; extern uint64_t gSamePriceThroughoutPark; -extern const money8 DefaultShopItemPrice[SHOP_ITEM_COUNT]; -extern const rct_shop_item_string_types ShopItemStringIds[SHOP_ITEM_COUNT]; -extern const uint32_t ShopItemImage[SHOP_ITEM_COUNT]; - -money32 get_shop_item_cost(int32_t shopItem); -money16 get_shop_base_value(int32_t shopItem); -money16 get_shop_hot_value(int32_t shopItem); -money16 get_shop_cold_value(int32_t shopItem); money32 shop_item_get_common_price(Ride* forRide, int32_t shopItem); bool shop_item_is_photo(int32_t shopItem); bool shop_item_has_common_price(int32_t shopItem); From 53bbe683112d66798246dfcb2e2ccce93792665d Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 29 Apr 2019 04:00:22 +0000 Subject: [PATCH 244/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/de-DE.txt | 46 ++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/data/language/de-DE.txt b/data/language/de-DE.txt index 6e1b49cbe1..43fc7deedd 100644 --- a/data/language/de-DE.txt +++ b/data/language/de-DE.txt @@ -2034,7 +2034,7 @@ STR_2696 :Bäume platzieren STR_2697 :??? STR_2698 :??? STR_2699 :??? -STR_2700 :Autosave-Frequenz: +STR_2700 :Autosavefrequenz: STR_2701 :Jede Minute STR_2702 :Alle 5 Minuten STR_2703 :Alle 15 Minuten @@ -2077,7 +2077,7 @@ STR_2739 :Keine STR_2740 :RollerCoaster Tycoon 1 STR_2741 :RollerCoaster Tycoon 2 STR_2742 :css50.dat nicht gefunden -STR_2743 :Kopieren Sie „data/css17.dat“ aus Ihrem RCT1-Verzeichnis nach „data/css50.dat“ in Ihrem RCT2-Verzeichnis oder versichern Sie sich, dass der Pfad zur RCT1-Installation in den Optionen korrekt angegeben ist. +STR_2743 :Kopieren Sie „data/css17.dat“ aus Ihrem RCT1-Verzeichnis nach „data/css50.dat“ in Ihrem RCT2-Verzeichnis oder versichern Sie sich, dass der Pfad zur RCT1-Installation im Tab „Erweitert“ korrekt angegeben ist. STR_2744 :[ STR_2745 :\ STR_2746 :] @@ -2222,7 +2222,7 @@ STR_2896 :{WINDOW_COLOUR_2}Hypothermia: (Allister Brimble) Copyright © Chr STR_2897 :{WINDOW_COLOUR_2}Last Sleigh Ride: (Allister Brimble) Copyright © Chris Sawyer STR_2898 :{WINDOW_COLOUR_2}Pipes of Glencairn: (Allister Brimble) Copyright © Chris Sawyer STR_2899 :{WINDOW_COLOUR_2}Traffic Jam: (Allister Brimble) Copyright © Chris Sawyer -STR_2901 :{WINDOW_COLOUR_2}(Auszüge mit freundlicher Genehmigung von Spectrasonics “Liquid Grooves“) +STR_2901 :{WINDOW_COLOUR_2}(Auszüge mit freundlicher Genehmigung von Spectrasonics „Liquid Grooves“) STR_2902 :{WINDOW_COLOUR_2}Toccata: (C.M.Widor, gespielt von Peter James Adcock) Aufnahme © Chris Sawyer STR_2903 :{WINDOW_COLOUR_2}Space Rock: (Allister Brimble) Copyright © Chris Sawyer STR_2904 :{WINDOW_COLOUR_2}Manic Mechanic: (Allister Brimble) Copyright © Chris Sawyer @@ -2430,7 +2430,6 @@ STR_3190 :Fußwegextras STR_3191 :Szeneriegruppen STR_3192 :Parkeingang STR_3193 :Wasser -STR_3194 :Szenariobeschreibung STR_3195 :Erfindungsliste STR_3196 :{WINDOW_COLOUR_2}Forschungsgruppe: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Vor dem Spielstart erfundene Objekte: @@ -3590,8 +3589,8 @@ STR_6125 :Objekttyp STR_6126 :Unbekannter Typ STR_6127 :Datei: {STRING} STR_6128 :Die Datei konnte aufgrund fehlender oder beschädigter Objekte nicht geladen werden. Eine Liste dieser Elemente ist nachstehend aufgeführt. -STR_6129 :Ausgewählte Elemente kopieren -STR_6130 :Vollständige Liste kopieren +STR_6129 :Kopieren +STR_6130 :Alle kopieren STR_6131 :Objektquelle STR_6132 :Forschungsstatus ignorieren STR_6133 :{SMALLFONT}{BLACK}Ermöglicht den Zugriff auf Attraktionen und Szenerie, die bisher noch nicht erforscht wurden @@ -3626,7 +3625,7 @@ STR_6161 :Gitternetzlinien ein-/ausblenden STR_6162 :Rotierende Wilde Maus STR_6163 :Mausförmige Wagen rasen um enge Kurven und kurze Gefälle herunter, wobei sie sich sanft drehen, um die Fahrgäste zu desorientieren STR_6164 :{WHITE}❌ -STR_6165 :Vertikale Synchronisation verwenden +STR_6165 :Vertikale Synchr. STR_6166 :{SMALLFONT}{BLACK}Synchronisiert die angezeigten Frames mit der Bildwiederholrate des Monitors, dies verhindert Screen Tearing STR_6167 :{SMALLFONT}{BLACK}Erweitert STR_6168 :Titelsequenz @@ -3733,8 +3732,39 @@ STR_6270 :Geländeflächen STR_6271 :Geländekanten STR_6272 :Stationen STR_6273 :Musik -STR_6274 :Farbgebung kann nicht erkannt werden... +STR_6274 :Farbschema kann nicht gesetzt werden... STR_6275 :{WINDOW_COLOUR_2}Stil der Station: +STR_6276 :{RED}{STRINGID} hat steckengebliebene Gäste, möglicherweise aufgrund eines ungültigen Streckentyps oder Betriebsmodus. +STR_6277 :{WINDOW_COLOUR_2}Stationsindex: {BLACK}{COMMA16} +STR_6278 :Autosaveanzahl: +STR_6279 :{SMALLFONT}{BLACK}Anzahl der Autosaves, die{NEWLINE}behalten werden sollen +STR_6280 :{SMALLFONT}{BLACK}Chat +STR_6281 :{SMALLFONT}{BLACK}Eine separate Schaltfläche für das Chatfenster in der Symbolleiste anzeigen +STR_6282 :Chat +STR_6283 :Der Chat ist derzeit nicht verfügbar. Sind Sie mit einem Server verbunden? +STR_6284 :Netzwerk +STR_6285 :Netzwerkinformation +STR_6286 :Empfangen +STR_6287 :Senden +STR_6288 :Ges. empfangen +STR_6289 :Ges. gesendet +STR_6290 :Basisprotokoll +STR_6291 :Befehle +STR_6292 :Karte +STR_6293 :B +STR_6294 :KiB +STR_6295 :MiB +STR_6296 :GiB +STR_6297 :TiB +STR_6298 :{STRING}/s +STR_6299 :Alle herunterladen +STR_6300 :{SMALLFONT}{BLACK}Falls online verfügbar, alle fehlenden Objekte herunterladen +STR_6301 :{SMALLFONT}{BLACK}Kopiert den ausgewählten Objektnamen in die Zwischenablage +STR_6302 :{SMALLFONT}{BLACK}Kopiert die gesamte Liste der fehlenden Objekte in die Zwischenablage +STR_6303 :Lädt Objekt herunter ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Szeneriewähler öffnen +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Experimentelle Option, um mehrere Threads für das Rendern zu verwenden, kann Instabilität verursachen ############# # Scenarios # From c5b66c029483a8344889bbadf24f6ed196262dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 29 Apr 2019 20:08:09 +0200 Subject: [PATCH 245/506] Fix #9152: Spectators can modify ride colours --- distribution/changelog.txt | 1 + src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkAction.h | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 8519354643..639194b677 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -25,6 +25,7 @@ - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. +- Fix: [#9152] Spectators can modify ride colours. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. - Improved: Allow the use of numpad enter key for console and chat. diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 2d0b6319e2..4fae374021 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 "19" +#define NETWORK_STREAM_VERSION "20" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/network/NetworkAction.h b/src/openrct2/network/NetworkAction.h index 8c98110831..fa8cb27389 100644 --- a/src/openrct2/network/NetworkAction.h +++ b/src/openrct2/network/NetworkAction.h @@ -13,6 +13,7 @@ #include #include +#include enum MISC_COMMAND { @@ -55,7 +56,7 @@ class NetworkAction final public: rct_string_id Name; std::string PermissionName; - std::array Commands; + std::vector Commands; }; class NetworkActions final From 1e1d263daeefe006e3309fbb4397f090cf1e91a0 Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 1 May 2019 16:54:12 +0100 Subject: [PATCH 246/506] PlayerSetGroupAction (#9072) * First pass at action. * Version 2. Do all the work in Network.cpp * Mark game command as complete * Make requested changes * Increment of network version --- src/openrct2-ui/windows/Player.cpp | 11 +++- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/PlayerSetGroupAction.hpp | 52 +++++++++++++++ src/openrct2/network/Network.cpp | 64 ++++++++----------- src/openrct2/network/network.h | 5 +- 7 files changed, 96 insertions(+), 42 deletions(-) create mode 100644 src/openrct2/actions/PlayerSetGroupAction.hpp diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index 8425d8bee3..ec560a8009 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -310,8 +311,14 @@ void window_player_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex, return; } int32_t group = network_get_group_id(dropdownIndex); - game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, group, GAME_COMMAND_SET_PLAYER_GROUP, 0, 0); - window_invalidate(w); + auto playerSetGroupAction = PlayerSetGroupAction(w->number, group); + playerSetGroupAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { + if (result->Error == GA_ERROR::OK) + { + window_invalidate(w); + } + }); + GameActions::Execute(&playerSetGroupAction); } void window_player_overview_resize(rct_window* w) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 1b289cd05e..37830717af 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1264,7 +1264,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_player_group, + nullptr, game_command_modify_groups, game_command_kick_player, game_command_cheat, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index bd7e0b674d..612e12f632 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -81,7 +81,7 @@ enum GAME_COMMAND GAME_COMMAND_SET_SIGN_NAME, // GA GAME_COMMAND_SET_BANNER_STYLE, // GA GAME_COMMAND_SET_SIGN_STYLE, // GA - GAME_COMMAND_SET_PLAYER_GROUP, + GAME_COMMAND_SET_PLAYER_GROUP, // GA GAME_COMMAND_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, GAME_COMMAND_CHEAT, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index d9e69ae2e3..2b50cbaaf4 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -39,6 +39,7 @@ #include "PauseToggleAction.hpp" #include "PlaceParkEntranceAction.hpp" #include "PlacePeepSpawnAction.hpp" +#include "PlayerSetGroupAction.hpp" #include "RideCreateAction.hpp" #include "RideDemolishAction.hpp" #include "RideEntranceExitPlaceAction.hpp" @@ -97,6 +98,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/PlayerSetGroupAction.hpp b/src/openrct2/actions/PlayerSetGroupAction.hpp new file mode 100644 index 0000000000..688d26ab03 --- /dev/null +++ b/src/openrct2/actions/PlayerSetGroupAction.hpp @@ -0,0 +1,52 @@ +/***************************************************************************** + * 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 "../network/network.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(PlayerSetGroupAction, GAME_COMMAND_SET_PLAYER_GROUP, GameActionResult) +{ +private: + NetworkPlayerId_t _playerId{ -1 }; + uint8_t _groupId{ std::numeric_limits::max() }; + +public: + PlayerSetGroupAction() + { + } + + PlayerSetGroupAction(NetworkPlayerId_t playerId, uint8_t groupId) + : _playerId(playerId) + , _groupId(groupId) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_playerId) << DS_TAG(_groupId); + } + GameActionResult::Ptr Query() const override + { + return network_set_player_group(GetPlayer(), _playerId, _groupId, false); + } + + GameActionResult::Ptr Execute() const override + { + return network_set_player_group(GetPlayer(), _playerId, _groupId, true); + } +}; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 4fae374021..6e890297ff 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 "20" +#define NETWORK_STREAM_VERSION "21" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; @@ -3364,61 +3364,51 @@ void network_chat_show_server_greeting() } } -void game_command_set_player_group( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) +GameActionResult::Ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting) { - uint8_t playerid = (uint8_t)*ecx; - uint8_t groupid = (uint8_t)*edx; - NetworkPlayer* player = gNetwork.GetPlayerByID(playerid); - NetworkGroup* fromgroup = gNetwork.GetGroupByID(game_command_playerid); - if (!player) + NetworkPlayer* player = gNetwork.GetPlayerByID(playerId); + + NetworkGroup* fromgroup = gNetwork.GetGroupByID(actionPlayerId); + if (player == nullptr) { - gGameCommandErrorTitle = STR_CANT_DO_THIS; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DO_THIS); } - if (!gNetwork.GetGroupByID(groupid)) + + if (!gNetwork.GetGroupByID(groupId)) { - gGameCommandErrorTitle = STR_CANT_DO_THIS; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DO_THIS); } + if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) { - gGameCommandErrorTitle = STR_CANT_CHANGE_GROUP_THAT_THE_HOST_BELONGS_TO; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_GROUP_THAT_THE_HOST_BELONGS_TO); } - if (groupid == 0 && fromgroup && fromgroup->Id != 0) + + if (groupId == 0 && fromgroup && fromgroup->Id != 0) { - gGameCommandErrorTitle = STR_CANT_SET_TO_THIS_GROUP; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_SET_TO_THIS_GROUP); } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + + if (isExecuting) { - player->Group = groupid; + player->Group = groupId; if (network_get_mode() == NETWORK_MODE_SERVER) { // Add or update saved user NetworkUserManager* userManager = &gNetwork._userManager; NetworkUser* networkUser = userManager->GetOrAddUser(player->KeyHash); - networkUser->GroupId = groupid; + networkUser->GroupId = groupId; networkUser->Name = player->Name; userManager->Save(); } - window_invalidate_by_number(WC_PLAYER, playerid); + window_invalidate_by_number(WC_PLAYER, playerId); // Log set player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(game_command_playerid); - NetworkGroup* new_player_group = gNetwork.GetGroupByID(groupid); + NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); + NetworkGroup* new_player_group = gNetwork.GetGroupByID(groupId); char log_msg[256]; const char* args[3] = { player->Name.c_str(), @@ -3428,7 +3418,7 @@ void game_command_set_player_group( format_string(log_msg, 256, STR_LOG_SET_PLAYER_GROUP, args); network_append_server_log(log_msg); } - *ebx = 0; + return std::make_unique(); } void game_command_modify_groups( @@ -4089,9 +4079,11 @@ const char* network_get_group_name(uint32_t index) { return ""; }; -void game_command_set_player_group( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) + +GameActionResult::Ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting) { + return std::make_unique(); } void game_command_modify_groups( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 693bcd44dc..5d528eae17 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -22,6 +22,7 @@ struct GameAction; struct Peep; struct LocationXYZ16; +class GameActionResult; namespace OpenRCT2 { @@ -65,8 +66,8 @@ int32_t network_get_current_player_group_index(); uint8_t network_get_group_id(uint32_t index); int32_t network_get_num_groups(); const char* network_get_group_name(uint32_t index); -void game_command_set_player_group( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); +std::unique_ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting); void game_command_modify_groups( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_kick_player(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); From 181a722c3b2979eba13489a571bd69b4b513272d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Wed, 1 May 2019 22:53:11 +0200 Subject: [PATCH 247/506] Fix game action errors not showing if no round trip was done (#9175) --- src/openrct2/actions/GameAction.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 036f8aab3f..aab701bc92 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -363,7 +363,10 @@ namespace GameActions // In network mode the error should be only shown to the issuer of the action. if (network_get_mode() != NETWORK_MODE_NONE) { - if (action->GetPlayer() != network_get_current_player_id()) + // If the action was never networked and query fails locally the player id is not assigned. + // So compare only if the action went into the queue otherwise show errors by default. + const bool isActionFromNetwork = (action->GetFlags() & GAME_COMMAND_FLAG_NETWORKED) != 0; + if (isActionFromNetwork && action->GetPlayer() != network_get_current_player_id()) { shouldShowError = false; } From a1454be3364b0ee97159885491b23d8f30e0e0a2 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Wed, 30 Jan 2019 16:07:22 -0800 Subject: [PATCH 248/506] Add new localizable strings for sign tooltips re: OpenRCT2/OpenRCT2#8593 These strings use high IDs right now and are probably not entirely suited for direct inclusion. There is also some duplication in that "No entry" had to be unique, as the actual no entry string is "No entry - -". --- data/language/en-GB.txt | 2 ++ src/openrct2/localisation/StringIds.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 172ac686ad..111a662395 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3755,6 +3755,8 @@ STR_6304 :Open scenery picker STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to render, may cause instability. STR_6307 :Colour scheme: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :{RED}No entry ############# # Scenarios # diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 0d77e03726..7d24d03726 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3939,6 +3939,9 @@ enum STR_TILE_INSPECTOR_COLOUR_SCHEME = 6307, + STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID = 6308, + STR_NO_ENTRY_TOOLTIP = 6309, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; From 8a674297eb303c61991f5d63e64485a380c0310f Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Wed, 30 Jan 2019 16:07:44 -0800 Subject: [PATCH 249/506] Add sign tooltips that display the sign message re: OpenRCT2/OpenRCT2#8593 Modifies the code for tooltip displays to show the string assigned to a banner. It also uses the color assigned to the sign (by sheer coincidence). As of right now I do not think that it works for non-banner signs (such as the 3D landscapes or scrolling signs etc), but it works for the typical case of banners, as well as "No entry" banners. --- src/openrct2-ui/interface/ViewportInteraction.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index fd92214c8a..aa210593b9 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -337,8 +337,15 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter banner = &gBanners[tileElement->AsBanner()->GetIndex()]; sceneryEntry = get_banner_entry(banner->type); - set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); - set_map_tooltip_format_arg(2, rct_string_id, sceneryEntry->name); + set_map_tooltip_format_arg( 0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); + if (banner->flags & BANNER_FLAG_NO_ENTRY) + { + set_map_tooltip_format_arg( 2, rct_string_id, STR_NO_ENTRY_TOOLTIP); + } else { + set_map_tooltip_format_arg( 2, rct_string_id, banner->string_idx); + } + set_map_tooltip_format_arg( 4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); + set_map_tooltip_format_arg( 6, rct_string_id, sceneryEntry->name); return info->type; } From 8ac6c9e9dee99b1a4585785eb17737e5d27eb27a Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Wed, 30 Jan 2019 16:21:19 -0800 Subject: [PATCH 250/506] Tweak sign changes to match style guide --- src/openrct2-ui/interface/ViewportInteraction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index aa210593b9..6932c17794 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -338,12 +338,12 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter sceneryEntry = get_banner_entry(banner->type); set_map_tooltip_format_arg( 0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); + if (banner->flags & BANNER_FLAG_NO_ENTRY) - { set_map_tooltip_format_arg( 2, rct_string_id, STR_NO_ENTRY_TOOLTIP); - } else { + else set_map_tooltip_format_arg( 2, rct_string_id, banner->string_idx); - } + set_map_tooltip_format_arg( 4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); set_map_tooltip_format_arg( 6, rct_string_id, sceneryEntry->name); return info->type; From c6a4316bd4f0b28321ba9e1e83444b5bfb1506be Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Thu, 31 Jan 2019 14:27:38 -0800 Subject: [PATCH 251/506] Update banner formatting code/strings Changes some things to use STR_BANNER_TEXT_FORMAT and removes instances of " - - " attached to other strings in the localization files. This can be used in the future to show the messages on a sign or banner via a tooltip without having to duplicate those messages without " - - ". --- data/language/en-GB.txt | 8 ++--- .../paint/tile_element/Paint.Banner.cpp | 24 +++++++------ .../paint/tile_element/Paint.Entrance.cpp | 35 ++++++++++--------- .../paint/tile_element/Paint.Path.cpp | 17 +++++---- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 111a662395..f0d159d956 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -551,8 +551,8 @@ STR_1167 :Can't raise water level here... STR_1168 :Options STR_1169 :(None) STR_1170 :{STRING} -STR_1171 :{RED}Closed - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Closed +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Build footpaths and queue lines STR_1174 :Banner sign in the way STR_1175 :Can't build this on sloped footpath @@ -1108,7 +1108,7 @@ STR_1726 :Land not for sale! STR_1727 :Construction rights not for sale! STR_1728 :Can't buy construction rights here... STR_1729 :Land not owned by park! -STR_1730 :{RED}Closed - - +STR_1730 :{RED}Closed STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Build STR_1733 :Mode @@ -2237,7 +2237,7 @@ STR_2977 :Staff member name STR_2978 :Enter new name for this member of staff: STR_2979 :Can't name staff member... STR_2980 :Too many banners in game -STR_2981 :{RED}No entry - - +STR_2981 :{RED}No entry STR_2982 :Banner text STR_2983 :Enter new text for this banner: STR_2984 :Can't set new text for banner... diff --git a/src/openrct2/paint/tile_element/Paint.Banner.cpp b/src/openrct2/paint/tile_element/Paint.Banner.cpp index 2471f8c287..4dcc7329d9 100644 --- a/src/openrct2/paint/tile_element/Paint.Banner.cpp +++ b/src/openrct2/paint/tile_element/Paint.Banner.cpp @@ -95,19 +95,23 @@ void banner_paint(paint_session* session, uint8_t direction, int32_t height, con set_format_arg(0, uint32_t, 0); set_format_arg(4, uint32_t, 0); - rct_string_id string_id = STR_NO_ENTRY; - if (!(gBanners[tile_element->AsBanner()->GetIndex()].flags & BANNER_FLAG_NO_ENTRY)) + if (gBanners[tile_element->AsBanner()->GetIndex()].flags & BANNER_FLAG_NO_ENTRY) { - set_format_arg(0, rct_string_id, gBanners[tile_element->AsBanner()->GetIndex()].string_idx); - string_id = STR_BANNER_TEXT_FORMAT; - } - if (gConfigGeneral.upper_case_banners) - { - format_string_to_upper(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), string_id, gCommonFormatArgs); + set_format_arg(0, rct_string_id, STR_NO_ENTRY); } else { - format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), string_id, gCommonFormatArgs); + set_format_arg(0, rct_string_id, gBanners[tile_element->AsBanner()->GetIndex()].string_idx); + } + + + if (gConfigGeneral.upper_case_banners) + { + format_string_to_upper(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); + } + else + { + format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY; @@ -116,6 +120,6 @@ void banner_paint(paint_session* session, uint8_t direction, int32_t height, con uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, string_id, scroll, scrollingMode), 0, 0, 1, 1, 0x15, height + 22, + session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, scrollingMode), 0, 0, 1, 1, 0x15, height + 22, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ); } diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index d98643341e..bffeea5013 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -158,27 +158,28 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, if (!is_exit && !(tile_element->IsGhost()) && tile_element->AsEntrance()->GetRideIndex() != RIDE_ID_NULL && stationObj->ScrollingMode != SCROLLING_MODE_NONE) { - set_format_arg(0, uint32_t, 0); + set_format_arg(0, rct_string_id, STR_RIDE_ENTRANCE_NAME); set_format_arg(4, uint32_t, 0); - rct_string_id string_id = STR_RIDE_ENTRANCE_CLOSED; - if (ride->status == RIDE_STATUS_OPEN && !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { - set_format_arg(0, rct_string_id, ride->name); - set_format_arg(2, uint32_t, ride->name_arguments); - - string_id = STR_RIDE_ENTRANCE_NAME; + set_format_arg(2, rct_string_id, STR_RIDE_ENTRANCE_NAME); + set_format_arg(4, rct_string_id, ride->name); + set_format_arg(6, uint32_t, ride->name_arguments); + } + else + { + set_format_arg(2, rct_string_id, STR_RIDE_ENTRANCE_CLOSED); } utf8 entrance_string[256]; if (gConfigGeneral.upper_case_banners) { - format_string_to_upper(entrance_string, sizeof(entrance_string), string_id, gCommonFormatArgs); + format_string_to_upper(entrance_string, sizeof(entrance_string), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } else { - format_string(entrance_string, sizeof(entrance_string), string_id, gCommonFormatArgs); + format_string(entrance_string, sizeof(entrance_string), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY; @@ -187,7 +188,7 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, string_id, scroll, stationObj->ScrollingMode), 0, 0, 0x1C, 0x1C, 0x33, + session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, stationObj->ScrollingMode), 0, 0, 0x1C, 0x1C, 0x33, height + stationObj->Height, 2, 2, height + stationObj->Height); } @@ -264,7 +265,6 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32 break; { - rct_string_id park_text_id = STR_BANNER_TEXT_CLOSED; set_format_arg(0, uint32_t, 0); set_format_arg(4, uint32_t, 0); @@ -272,18 +272,21 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32 { set_format_arg(0, rct_string_id, gParkName); set_format_arg(2, uint32_t, gParkNameArgs); - - park_text_id = STR_BANNER_TEXT_FORMAT; + } + else + { + set_format_arg(0, rct_string_id, STR_BANNER_TEXT_CLOSED); + set_format_arg(2, uint32_t, 0); } utf8 park_name[256]; if (gConfigGeneral.upper_case_banners) { - format_string_to_upper(park_name, sizeof(park_name), park_text_id, gCommonFormatArgs); + format_string_to_upper(park_name, sizeof(park_name), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } else { - format_string(park_name, sizeof(park_name), park_text_id, gCommonFormatArgs); + format_string(park_name, sizeof(park_name), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY; @@ -294,7 +297,7 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32 if (entrance->scrolling_mode == SCROLLING_MODE_NONE) break; - int32_t stsetup = scrolling_text_setup(session, park_text_id, scroll, entrance->scrolling_mode + direction / 2); + int32_t stsetup = scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, entrance->scrolling_mode + direction / 2); int32_t text_height = height + entrance->text_height; sub_98199C(session, stsetup, 0, 0, 0x1C, 0x1C, 0x2F, text_height, 2, 2, text_height); } diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 26d0b8d3aa..b8483787a3 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -451,21 +451,24 @@ static void sub_6A4101( set_format_arg(4, uint32_t, 0); Ride* ride = get_ride(tile_element->AsPath()->GetRideIndex()); - rct_string_id string_id = STR_RIDE_ENTRANCE_CLOSED; if (ride->status == RIDE_STATUS_OPEN && !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { - set_format_arg(0, rct_string_id, ride->name); - set_format_arg(2, uint32_t, ride->name_arguments); - string_id = STR_RIDE_ENTRANCE_NAME; + set_format_arg(0, rct_string_id, STR_RIDE_ENTRANCE_NAME); + set_format_arg(2, rct_string_id, ride->name); + set_format_arg(4, uint32_t, ride->name_arguments); + } + else + { + set_format_arg(0, rct_string_id, STR_RIDE_ENTRANCE_CLOSED); } if (gConfigGeneral.upper_case_banners) { format_string_to_upper( - gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), string_id, gCommonFormatArgs); + gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } else { - format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), string_id, gCommonFormatArgs); + format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY; @@ -474,7 +477,7 @@ static void sub_6A4101( uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, string_id, scroll, scrollingMode), 0, 0, 1, 1, 21, height + 7, + session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, scrollingMode), 0, 0, 1, 1, 21, height + 7, boundBoxOffsets.x, boundBoxOffsets.y, boundBoxOffsets.z); } From 877ce58f0be6de1f647fc066294525324663ffdb Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Thu, 31 Jan 2019 14:33:09 -0800 Subject: [PATCH 252/506] Update sign tooltip to use STR_NO_ENTRY Changes the number of the sign tooltip string and removes the now-duplicate "no entry" string --- data/language/en-GB.txt | 1 - src/openrct2-ui/interface/ViewportInteraction.cpp | 2 +- src/openrct2/localisation/StringIds.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index f0d159d956..b9becb6007 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3756,7 +3756,6 @@ STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to render, may cause instability. STR_6307 :Colour scheme: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} -STR_6309 :{RED}No entry ############# # Scenarios # diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 6932c17794..8e135ceb5f 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -340,7 +340,7 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter set_map_tooltip_format_arg( 0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); if (banner->flags & BANNER_FLAG_NO_ENTRY) - set_map_tooltip_format_arg( 2, rct_string_id, STR_NO_ENTRY_TOOLTIP); + set_map_tooltip_format_arg( 2, rct_string_id, STR_NO_ENTRY); else set_map_tooltip_format_arg( 2, rct_string_id, banner->string_idx); diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 7d24d03726..e3fbb2173c 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3940,7 +3940,6 @@ enum STR_TILE_INSPECTOR_COLOUR_SCHEME = 6307, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID = 6308, - STR_NO_ENTRY_TOOLTIP = 6309, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 From a3106e4c4c2194e2b95f9b3cdfe22140ddde6640 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Thu, 31 Jan 2019 14:50:53 -0800 Subject: [PATCH 253/506] Add sign tooltips to 3d signs For some reason, all signs report "Sign" as their text before actually being modified. This also happens with the tile inspector, so for now I'm not terribly worried about it --- .../interface/ViewportInteraction.cpp | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 8e135ceb5f..195872f23b 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -317,8 +317,11 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter sceneryEntry = tileElement->AsWall()->GetEntry(); if (sceneryEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) { - set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); - set_map_tooltip_format_arg(2, rct_string_id, sceneryEntry->name); + banner = &gBanners[tileElement->AsWall()->GetBannerIndex()]; + set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); + set_map_tooltip_format_arg(2, rct_string_id, banner->string_idx); + set_map_tooltip_format_arg(4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); + set_map_tooltip_format_arg(6, rct_string_id, sceneryEntry->name); return info->type; } break; @@ -327,8 +330,12 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter sceneryEntry = tileElement->AsLargeScenery()->GetEntry(); if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) { - set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); - set_map_tooltip_format_arg(2, rct_string_id, sceneryEntry->name); + + banner = &gBanners[tileElement->AsLargeScenery()->GetBannerIndex()]; + set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); + set_map_tooltip_format_arg(2, rct_string_id, banner->string_idx); + set_map_tooltip_format_arg(4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); + set_map_tooltip_format_arg(6, rct_string_id, sceneryEntry->name); return info->type; } break; @@ -337,15 +344,15 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter banner = &gBanners[tileElement->AsBanner()->GetIndex()]; sceneryEntry = get_banner_entry(banner->type); - set_map_tooltip_format_arg( 0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); + set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); if (banner->flags & BANNER_FLAG_NO_ENTRY) - set_map_tooltip_format_arg( 2, rct_string_id, STR_NO_ENTRY); + set_map_tooltip_format_arg(2, rct_string_id, STR_NO_ENTRY); else - set_map_tooltip_format_arg( 2, rct_string_id, banner->string_idx); + set_map_tooltip_format_arg(2, rct_string_id, banner->string_idx); - set_map_tooltip_format_arg( 4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); - set_map_tooltip_format_arg( 6, rct_string_id, sceneryEntry->name); + set_map_tooltip_format_arg(4, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY); + set_map_tooltip_format_arg(6, rct_string_id, sceneryEntry->name); return info->type; } From 100ee139f572f21117dcfb4982348a47225d75c1 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Fri, 1 Feb 2019 12:29:49 -0800 Subject: [PATCH 254/506] Update code style with clang-format --- src/openrct2-ui/interface/ViewportInteraction.cpp | 3 +-- src/openrct2/paint/tile_element/Paint.Banner.cpp | 4 ++-- src/openrct2/paint/tile_element/Paint.Entrance.cpp | 7 ++++--- src/openrct2/paint/tile_element/Paint.Path.cpp | 7 ++++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 195872f23b..310dbcb54d 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -330,7 +330,6 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter sceneryEntry = tileElement->AsLargeScenery()->GetEntry(); if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) { - banner = &gBanners[tileElement->AsLargeScenery()->GetBannerIndex()]; set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); set_map_tooltip_format_arg(2, rct_string_id, banner->string_idx); @@ -345,7 +344,7 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter sceneryEntry = get_banner_entry(banner->type); set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID); - + if (banner->flags & BANNER_FLAG_NO_ENTRY) set_map_tooltip_format_arg(2, rct_string_id, STR_NO_ENTRY); else diff --git a/src/openrct2/paint/tile_element/Paint.Banner.cpp b/src/openrct2/paint/tile_element/Paint.Banner.cpp index 4dcc7329d9..d23b69c2b2 100644 --- a/src/openrct2/paint/tile_element/Paint.Banner.cpp +++ b/src/openrct2/paint/tile_element/Paint.Banner.cpp @@ -104,10 +104,10 @@ void banner_paint(paint_session* session, uint8_t direction, int32_t height, con set_format_arg(0, rct_string_id, gBanners[tile_element->AsBanner()->GetIndex()].string_idx); } - if (gConfigGeneral.upper_case_banners) { - format_string_to_upper(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); + format_string_to_upper( + gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } else { diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index bffeea5013..75c1c96f5d 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -188,8 +188,8 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, stationObj->ScrollingMode), 0, 0, 0x1C, 0x1C, 0x33, - height + stationObj->Height, 2, 2, height + stationObj->Height); + session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, stationObj->ScrollingMode), 0, 0, 0x1C, 0x1C, + 0x33, height + stationObj->Height, 2, 2, height + stationObj->Height); } image_id = entranceImageId; @@ -297,7 +297,8 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32 if (entrance->scrolling_mode == SCROLLING_MODE_NONE) break; - int32_t stsetup = scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, entrance->scrolling_mode + direction / 2); + int32_t stsetup = scrolling_text_setup( + session, STR_BANNER_TEXT_FORMAT, scroll, entrance->scrolling_mode + direction / 2); int32_t text_height = height + entrance->text_height; sub_98199C(session, stsetup, 0, 0, 0x1C, 0x1C, 0x2F, text_height, 2, 2, text_height); } diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index b8483787a3..02f24592bd 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -468,7 +468,8 @@ static void sub_6A4101( } else { - format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); + format_string( + gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, gCommonFormatArgs); } gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY; @@ -477,8 +478,8 @@ static void sub_6A4101( uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, scrollingMode), 0, 0, 1, 1, 21, height + 7, - boundBoxOffsets.x, boundBoxOffsets.y, boundBoxOffsets.z); + session, scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, scroll, scrollingMode), 0, 0, 1, 1, 21, + height + 7, boundBoxOffsets.x, boundBoxOffsets.y, boundBoxOffsets.z); } session->InteractionType = VIEWPORT_INTERACTION_ITEM_FOOTPATH; From 51593c540a5a529ed6f81442a1fe5da3b1a92f7c Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Fri, 1 Feb 2019 12:56:26 -0800 Subject: [PATCH 255/506] Fix ride entrance hut banner issue This fixes the problem where the ride entrance hut banner would show a nonsense number after auto-named rides based on the amount the text had scrolled. --- src/openrct2/paint/tile_element/Paint.Entrance.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 75c1c96f5d..23774ce176 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -163,9 +163,8 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, if (ride->status == RIDE_STATUS_OPEN && !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { - set_format_arg(2, rct_string_id, STR_RIDE_ENTRANCE_NAME); - set_format_arg(4, rct_string_id, ride->name); - set_format_arg(6, uint32_t, ride->name_arguments); + set_format_arg(2, rct_string_id, ride->name); + set_format_arg(4, uint32_t, ride->name_arguments); } else { From df42cfe1e1b3703a54441a5da44f90f90f6dbb95 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 2 May 2019 00:07:20 +0200 Subject: [PATCH 256/506] Change map toolbar icon with current rotation (#9154) --- distribution/changelog.txt | 1 + resources/g2/icons/map_east.png | Bin 0 -> 551 bytes resources/g2/icons/map_east_pressed.png | Bin 0 -> 1202 bytes resources/g2/icons/map_north.png | Bin 0 -> 577 bytes resources/g2/icons/map_north_pressed.png | Bin 0 -> 1223 bytes resources/g2/icons/map_south.png | Bin 0 -> 578 bytes resources/g2/icons/map_south_pressed.png | Bin 0 -> 1222 bytes resources/g2/icons/map_west.png | Bin 0 -> 561 bytes resources/g2/icons/map_west_pressed.png | Bin 0 -> 1205 bytes resources/g2/sprites.json | 24 +++++++++++++++++++++++ src/openrct2-ui/windows/TopToolbar.cpp | 14 +++++++++++++ src/openrct2/sprites.h | 11 ++++++++++- 12 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 resources/g2/icons/map_east.png create mode 100644 resources/g2/icons/map_east_pressed.png create mode 100644 resources/g2/icons/map_north.png create mode 100644 resources/g2/icons/map_north_pressed.png create mode 100644 resources/g2/icons/map_south.png create mode 100644 resources/g2/icons/map_south_pressed.png create mode 100644 resources/g2/icons/map_west.png create mode 100644 resources/g2/icons/map_west_pressed.png diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 639194b677..cd3e7a8be2 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Feature: [#8481] Multi-threaded rendering. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. +- Feature: [#9154] Change map toolbar icon with current viewport rotation. - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5579] Network desync immediately after connecting. diff --git a/resources/g2/icons/map_east.png b/resources/g2/icons/map_east.png new file mode 100644 index 0000000000000000000000000000000000000000..2d078a88e8466b9bad79906b0cb11a6dfbc0bbd0 GIT binary patch literal 551 zcmV+?0@(eDP)a{n=}900RQ`sWL^SE00001bW%=J06^y0W&i*IT}ebiR4C7ll7Dl9APj~TFo3wl zLDNOFU2WI;{lDQtZ>Rp#-E!wE$CFS%hy#EgjM1djzP5`&OvJh9 zq)wD3R_whep{_`v@DW@zT5q^T777dwJqr#bjc%=tk0m~qU2DUXx7ONrxh#(WY!Q*$ zVVbY=9^+%YED#8Bn&$Z`wvWbiejCqekg&N>k;{cw+>J~BK6YKNVJJ3D(~vjJ?}t7f z)~OYbBlG@XloBGLhK5>9-SJ4Y8%xWwmpBP$D?Ez#immrq_EMH}>8zU;V~1(O){?~h zRsd~fh4|kKZAx^x7w=O?wvhozvJE$urGRH!F2@RIX<&z&Y$Zi5K3UTE47yqIUk~~A p^^)FBRrP(lzpz59>h#j8>Icp@M_FGYH0uBW002ovPDHLkV1nL%@|XYs literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_east_pressed.png b/resources/g2/icons/map_east_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..8979ef881c4f8113d0c3f5e0f6303c34ec7528db GIT binary patch literal 1202 zcmaJ>|Busj82<3Z3^{R_L3U7~!id#0uuBRIt)?D5vcm%9=*4k2v8PpL*kRABW+B6? zu;A1oMVGLU9n7SJ-CcoU5DQMy$mA|zkR~25LXpKRVZk#Qy1)zvek}ihZ=UykpZAyN z`Qd%@ez9?bf7ZsDyVcfE6^*Z4N6bV?SDHwEx!)PSxjVH)dn$70;ydf3MM7g5U zxFbL|iHutgpo)NHB;r(zHd29NPPE42RZDHu3VsCeIEYX{;T&1fVI-WTtgBu`VATuj zJe*V@EO-E50pJ}D(dm>CM8PnXBu}yISSVDI<%vuN8U{kRJe1qZq9l*`MLZxAf*ewBTCD~FA_6SsAhJ$6k8njiRHoyVpjwUOYsz>%SDh?1 zU=!|i`rK|m>fvy&K#~%}#(7&TnoA_dvN@|@*2@&&8HdCG~32iSV1c+!8rMOuY<#kN7NTn9k z>XCdSRh-nzuvEibz=t~gUT2U(!yFL}F^U{klX6~5ngy+D6=1#WV;HCdXaNX;?PUW~ z;z%rN6JI)IBVDOT#iC8swE#j61iF`9 z_Po(QXWg;u-ORVc?MEMeo&0i9?-|#!Jtw^fb`gW4m%F9yS5N=emEL-;YvRZI*WZ%f z@hrZ%zTV$;fAfjU->pB`c6&$Hvd=#`eWnnV`dk+etX?$c$(<2zJUD)5^5rALzr125 zZ?zbQwtd_!9)EZ6V8h|5wzaRGKjbQ9%(i^^PIGwQf>lW0oc6_7mA)8g83uQk4D%dHFDrR2Q6*7tw-{pXgICwnhen)^Q6wP4}*txa3{m*3cY v==|MZm7Q?l^_o6%{_c{Q$49L3p%E(h=$|X1r;P)eGL6HiMETW>>Kb8}mx z=Wm09Z--BJM=O6iv&V>Fn%#qxAXPsx}B?ql~P5@x-NAs z>LTjzt9oT)RN|w*&+j3Lt)HDBhtAfZG}drlO(K&jmO%S;`Gz^7DJZU8#? z0Qh|EKTT(pk|e~wcM|}hpW&@eaGB(=zn=aryrx`ar_%C?W6IFQHX!3i+}K*;8eDiJBQ5tr{5RTZ;VC~%O)u5Xolf~OjDyuYAb!}!+NPyJ zDwk48h$P==)A4KAJ;` P00000NkvXXu0mjfr;G!n literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_north_pressed.png b/resources/g2/icons/map_north_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..7ad105074260d799d3e964c17ac9d3a1690af115 GIT binary patch literal 1223 zcmaJ>|Busj82)%fs$6i$B9kj&$ha#~xq&5=P_Q07GGIyxg-mae5i87N9@X^X!p+>& zK?WH|FH9U~feFP7tuT`dHeuoHBkgd5NlV7-lgzdaOkh9mBHf=bD3CL74*#bPN@sVWSP z_^3v~>xlZC5|5=tVlc+!Q@&zWFbZ+gP{wMy2L%BfglQmgNJc>N30pa1uNP5hx?w#4 z?@AErE&x~n0th15Y*7@IFifGSL6$89gXL)SW;zY?d6clbXos71QUS~(;JzrqOOz-x zG1Z&QaY`|u89^tBx;-w6!@WG|7Z@SV#?yhcCTOLoZX`=)rZSed(ZJ3DM-Vt80Fw|h z?eJtVf1VafzC=Y-YLX5IS=`Q(XxM`%d{l;Kaw1oX@#U0QRb#b$YOJKfs&2EB815s; zAkBn1F2VD1IGjx+^67L*(<(zlwOS1VQ~+2CAu={5hjK+cSYhH-zhZ`SHEF1xHSdEduVPf?u!%fN^TRRtPl76SqSk~Gjfz+eI702CZBK|qCt zS_l^7&``jG#go9x03VBlctt`B!W|>sDVk6jBJXt%vAF4T!GIG+F(?yIqm%2j z)7I%f)V+2!2c91t*=+I1%J#N(vrBzfUfCnhn}oc%=iNf@)yCf*9odP#bWZ5~Wl`|h z?aAkFzkcMwmF^Kmxk6HZ|G{hb~rxegS`hA8v20$-!u1a zpN=RWuDZ~FEc&W^k9pVy>JPi|q~v_res%cFO?7kn#V>R)}= U)-G;)@Qzk4U)_FU*~a((13~~H!2kdN literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_south.png b/resources/g2/icons/map_south.png new file mode 100644 index 0000000000000000000000000000000000000000..8e66136186b6f451c9368c763b036c7ce31b9794 GIT binary patch literal 578 zcmV-I0=@l-P)eGL6HiMETW>>Kb8}mx z=Wm09Z--BJM=O6IE`mR-jOiGUAz}0rVhqQC(V49}gwV@o z=+$Vt9>cFd=*;(Ml>2|tcppt(j8Z~ro57GI36$_CE`7WQY!)G9CWI%G*#>TQV7-su6 zpxhZ?39w^Rtg&zJ*1o$U$G8G&8_Q2W^6mFiy`8J-&+YzXEm~FQr>m;|0)+lfRtl1% QLI3~&07*qoM6N<$g7g>#wg3PC literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_south_pressed.png b/resources/g2/icons/map_south_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..a58d2d3b509d54b7a6e0c4810cbfd9f00c3698d9 GIT binary patch literal 1222 zcmaJ>@oy7#6#ovL0OLMCbv;S!2>Q*ppX-9(6GbQ zP?rjYU0BtcRjgV}qlFzXms6Y3n1+p{*)B3naYs_Mi477{v_i!}z8?R8FQ50`=l$~e z{P14hiOvr9y!wUp0DyVz8{0M;eUXukbDl72>k=3TVAj8#o4VE;Nl_%r z(md}KMIjUl#bOCXQFFN|U9VKDxD${BU}&?~YxVo>0m&JT5V1IuQn*Z3%xjTiDM?`_ z4`CK)BU@@9^c?C)cGvNf6Pz6;B=JcpmP8Dle3kj?&KzzV10aP}* z5{O$ty;)MwJdvW9tjIYy%wSgDWed2mh=)k=R7PaA5MPLirF5v0jn%X?Eafa#7m9gs zmye_ZEF0nZcp#ueBH2VjQ`O?sRHagZz$O4RX2MezDq~~wn6F5MOWtHTkg3R1Ri!*r zs6jJkvA7V#ZFjJklP3s~X2P5yCMl8VcuLW8TD3?5jy8#`CCJ%jKNgqBbePS=edFn1 zAsa6ja@Fb`NCMyiKmDTpa?qEU7Z#VZCytlorwQH$%df+jq<_DQOD)`ix(!I7iOzIwRg zjn^;!`myy?>ByQp&8uG6TK(&zu|NCIicRl-AzkR~?>pSF@9NsmI>#Ptf3AMT?m_#H zrv}T%;K T-FurKf1~#G9c@GFb{_u^H-{I= literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_west.png b/resources/g2/icons/map_west.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa74611d7231ebc02120ad333116f050b37d1c6 GIT binary patch literal 561 zcmV-10?z%3P)eGL6HiMETW>>Kb8}mx z=Wm09Z--BJM=OJumxrHUj{pFV)AOINud4t6x5LA~ix0;D0Mkz^*QXQbS0nSw8~+CY z|4&2zUmyQ}C;yu>|Jwln`;T&zF|Pms00DGTPE!Ct=GbNc00Ci1L_t(2&yAAZcB>!| zg%xlBN!zi|Y0d;q8%-16{{=hbLcB@WnYG-q_~vH|Hn;QjY240D!N!=Zb=&5)Rc%)7 zW7TdLz_2`;l~#&{Jfv0w5I8WTwN|8zYH5#|;t+}RAa4?hBAhquLKwn75eEPR7^6w4 z{cIP5goty|$($%AHtfA8p{_`v@E%+=T36g73k3#;o&^UIqZ=kV9{1M9`%3q#tD%y;eEWU?-gGz^E@w$$Shf(hp*T1t5)YcElZ)()b#@% z#+Ba2ZinYZ$~J3nA50&4UwulcjMdOlkLf@OUv|gRv+N~K!r2OslD%Q;eU`nH<-2s& zU61jAsbXtMYLFfiKwDWM{_ll$rMldU_u|TS5K6O(JIgY_vn`ing|isg;VxTgkxNdN zHa>%{$MV;YeEoh(uji)ux!#^cp-pps8cp*H71~RQgiWX(00000NkvXXu0mjf?P~X+ literal 0 HcmV?d00001 diff --git a/resources/g2/icons/map_west_pressed.png b/resources/g2/icons/map_west_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..93bf7d0bf4535e97addd90c0844cc1b7e499fe63 GIT binary patch literal 1205 zcmaJ>@oy7#6#oK0v@)<@ogEbD4^_|Pj0JAtST1m|+w9;RH+RD`R#VuaWj4zJ2h^mJ zOID#`0|(ZmiJeq9v9JS5oaBH?ikvu1l}lD*l`|I8XoC|9lrXc!d_DdFUq0`>&->-` z`Qg31{XHA}b7wD{4FH(CuB)Th>PxI#WS?c#wa>yd05hk0Uh3<##{UVI*XzYFA4QQY zOY?j{6optUmP%!EIZf9~rde+^FdrZZz|c*BfHNHSM54ZUf=H#AY%Z8Dh(#k&sVWp| zb1YsnmC3s9cY`1bA|#MmTUM|Y5{`1#*(kbU%?BGn zI4wh{djVho2-<9d!y&odGJ+@sG0HGwp-@?pCNddVD7Z1Fmvs3U4-rKC0?J7kFB4*# zim7xm&nm^BW`;bt+voQZEK2iuK%j&;6VC)QnxGkyZYGUdwlZ08kif|TR|t5b0FiBY z#^ui;fdVNQT%sZ>by@@cf^k-I3mkad66|@d^sgn)mXidnlw~c)g4Y8K{*T$ zkyM0b6Fi@eL~@BlA(JsQtx_u0>vag+0zgtWEbE~1ZnlVqDpb50P->BUT`o0pwdwLC zY(gCl+~x9nye#VD2|}cqc+e7y<`T)VY|hk;Muh}H+9t9NDd>^IXgW%&aWWMq>h!0B`_^0LTES0E_`pwE<{>ppylNb0W8`?$}UFn1T{o33Ar9n z83A0!r;kgit6V$mX0Ai##hd^9Rxz8LOHk(f$h1=?3)&>H83K@XG=n8u(+Ci}EY z*6GjK*}H)SYySNCEsGDV>sZ_OoN?g8;^4&6d7T@FTJ`R!o;kbL^!&E{@aDJee)4{44?ei^ z__cRtPTyP=`}O!M*^bAC+wDi*ec-&kj4ki}X5{MnLyun>Sz%oGp)&8wuE7tM9h#i} z>>2cQ@Yq{p|C_i|tQsx#S6wQ{~rA|M=CJz1K$< z2ihLay7XXoJk|VW`do_noH>_UO>p1t+cNNEE_}u@KXm~UMbG5 zH}{=YcKWwBhr3VAzsPj0<&pb;@4eCc#+|Dz=f_w4F@CCFT`+6T#E!Ow!<#q7Pmgas zy8d9hTj@Q^{CiD(H9->zreDr+Qb#CZ5)4plwKj&2z A-~a#s literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index f1b78eacbb..81eabe7675 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -394,6 +394,30 @@ "x_offset": 2, "y_offset": 1 }, + { + "path": "icons/map_north.png" + }, + { + "path": "icons/map_north_pressed.png" + }, + { + "path": "icons/map_west.png" + }, + { + "path": "icons/map_west_pressed.png" + }, + { + "path": "icons/map_south.png" + }, + { + "path": "icons/map_south_pressed.png" + }, + { + "path": "icons/map_east.png" + }, + { + "path": "icons/map_east_pressed.png" + }, { "path": "font/latin/ae-uc-small.png", "y_offset": 0, diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index ec173da5b3..855d53d892 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -849,6 +849,20 @@ static void window_top_toolbar_invalidate(rct_window* w) else window_top_toolbar_widgets[WIDX_MUTE].image = IMAGE_TYPE_REMAP | SPR_G2_TOOLBAR_UNMUTE; + // Set map button to the right image. + if (window_top_toolbar_widgets[WIDX_MAP].type != WWT_EMPTY) + { + static constexpr uint32_t imageIdByRotation[] = { + SPR_G2_MAP_NORTH, + SPR_G2_MAP_WEST, + SPR_G2_MAP_SOUTH, + SPR_G2_MAP_EAST, + }; + + uint32_t mapImageId = imageIdByRotation[get_current_rotation()]; + window_top_toolbar_widgets[WIDX_MAP].image = IMAGE_TYPE_REMAP | mapImageId; + } + // Zoomed out/in disable. Not sure where this code is in the original. if (window_get_main()->viewport->zoom == 0) { diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 50b8d1ec3b..8f31e5f2e1 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -829,7 +829,16 @@ enum SPR_G2_EYEDROPPER = SPR_G2_BEGIN + 112, SPR_G2_CHAT = SPR_G2_BEGIN + 113, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 114, + SPR_G2_MAP_NORTH = SPR_G2_BEGIN + 114, + SPR_G2_MAP_NORTH_PRESSED = SPR_G2_BEGIN + 115, + SPR_G2_MAP_WEST = SPR_G2_BEGIN + 116, + SPR_G2_MAP_WEST_PRESSED = SPR_G2_BEGIN + 117, + SPR_G2_MAP_SOUTH = SPR_G2_BEGIN + 118, + SPR_G2_MAP_SOUTH_PRESSED = SPR_G2_BEGIN + 119, + SPR_G2_MAP_EAST = SPR_G2_BEGIN + 120, + SPR_G2_MAP_EAST_PRESSED = SPR_G2_BEGIN + 121, + + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 122, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From 05a1ce63397ebd9309ee436f8c65e362739e7865 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 2 May 2019 00:21:02 +0200 Subject: [PATCH 257/506] Update changelog. [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 639194b677..155f397444 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,6 +3,7 @@ - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. - Feature: [#8481] Multi-threaded rendering. +- Feature: [#8659] Banner and sign texts are now shown in tooltips. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Change: [#7877] Files are now sorted in logical rather than dictionary order. From d614fb4035aa8833a7f214f50bd177041bc1380e Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Sun, 3 Feb 2019 21:54:45 -0800 Subject: [PATCH 258/506] add network indicators for desync/player count --- src/openrct2-ui/windows/TopToolbar.cpp | 5 +++++ src/openrct2/network/Network.cpp | 11 +++++++++++ src/openrct2/network/network.h | 1 + 3 files changed, 17 insertions(+) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 855d53d892..ffae097f1b 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -995,6 +995,11 @@ static void window_top_toolbar_paint(rct_window* w, rct_drawpixelinfo* dpi) y++; imgId = SPR_SHOW_GUESTS_ON_THIS_RIDE_ATTRACTION; gfx_draw_sprite(dpi, imgId, x, y, 0); + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + if (network_is_desynchronised()) + gfx_draw_string(dpi, "", COLOUR_BORDEAUX_RED | COLOUR_FLAG_OUTLINE, x - 1, y + 2); + int32_t player_count = network_get_num_players(); + gfx_draw_string_right(dpi, STR_COMMA16, &player_count, COLOUR_WHITE | COLOUR_FLAG_OUTLINE, x + 24, y + 15); } } diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 6e890297ff..c8b4d310c2 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -135,6 +135,7 @@ public: static const char* FormatChat(NetworkPlayer* fromplayer, const char* text); void SendPacketToClients(NetworkPacket& packet, bool front = false, bool gameCmd = false); bool CheckSRAND(uint32_t tick, uint32_t srand0); + bool IsDesynchronized(); void CheckDesynchronizaton(); void KickPlayer(int32_t playerId); void SetPassword(const char* password); @@ -987,6 +988,11 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) return true; } +bool Network::IsDesynchronized() +{ + return gNetwork._desynchronised; +} + void Network::CheckDesynchronizaton() { // Check synchronisation @@ -3193,6 +3199,11 @@ int32_t network_get_status() return gNetwork.GetStatus(); } +bool network_is_desynchronised() +{ + return gNetwork.IsDesynchronized(); +} + void network_check_desynchronization() { return gNetwork.CheckDesynchronizaton(); diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 5d528eae17..434a1bfe06 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -37,6 +37,7 @@ int32_t network_begin_server(int32_t port, const std::string& address); int32_t network_get_mode(); int32_t network_get_status(); +bool network_is_desynchronised(); void network_check_desynchronization(); void network_send_tick(); void network_update(); From bc8ecd8e672a7a9543533c9264e0930c30b83c87 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Mon, 4 Feb 2019 21:57:09 -0800 Subject: [PATCH 259/506] Add "Reconnect" option under the multiplayer button --- data/language/en-GB.txt | 1 + src/openrct2-ui/windows/TopToolbar.cpp | 12 ++++++++--- src/openrct2/localisation/StringIds.h | 2 ++ src/openrct2/network/Network.cpp | 29 ++++++++++++++++++++++++++ src/openrct2/network/network.h | 1 + 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index b9becb6007..f3a3f8b9f2 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3756,6 +3756,7 @@ STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to render, may cause instability. STR_6307 :Colour scheme: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Reconnect ############# # Scenarios # diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index ffae097f1b..0bddbc5f78 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -152,6 +152,9 @@ enum TOP_TOOLBAR_DEBUG_DDIDX { enum TOP_TOOLBAR_NETWORK_DDIDX { DDIDX_MULTIPLAYER = 0, DDIDX_NETWORK = 1, + DDIDX_MULTIPLAYER_RECONNECT = 2, + + TOP_TOOLBAR_NETWORK_COUNT }; enum { @@ -3415,13 +3418,13 @@ static void top_toolbar_init_debug_menu(rct_window* w, rct_widget* widget) static void top_toolbar_init_network_menu(rct_window* w, rct_widget* widget) { - gDropdownItemsFormat[0] = STR_MULTIPLAYER; - gDropdownItemsFormat[DDIDX_MULTIPLAYER] = STR_MULTIPLAYER; gDropdownItemsFormat[DDIDX_NETWORK] = STR_NETWORK; + gDropdownItemsFormat[DDIDX_MULTIPLAYER_RECONNECT] = STR_MULTIPLAYER_RECONNECT; window_dropdown_show_text( - w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0, 2); + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0, + TOP_TOOLBAR_NETWORK_COUNT); gDropdownDefaultIndex = DDIDX_MULTIPLAYER; } @@ -3466,6 +3469,9 @@ static void top_toolbar_network_menu_dropdown(int16_t dropdownIndex) case DDIDX_NETWORK: context_open_window(WC_NETWORK); break; + case DDIDX_MULTIPLAYER_RECONNECT: + network_reconnect(); + break; } } } diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index e3fbb2173c..7c017ff11e 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3941,6 +3941,8 @@ enum STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID = 6308, + STR_MULTIPLAYER_RECONNECT = 6309, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index c8b4d310c2..a486bf31eb 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -113,6 +113,7 @@ public: void SetEnvironment(const std::shared_ptr& env); bool Init(); + void Reconnect(); void Close(); bool BeginClient(const std::string& host, uint16_t port); bool BeginServer(uint16_t port, const std::string& address); @@ -299,6 +300,7 @@ private: int32_t status = NETWORK_STATUS_NONE; bool _closeLock = false; bool _requireClose = false; + bool _requireReconnect = false; bool wsa_initialized = false; bool _clientMapLoaded = false; std::unique_ptr _listenSocket; @@ -312,6 +314,8 @@ private: std::list> client_connection_list; std::multiset game_command_queue; std::vector chunk_buffer; + std::string _host; + uint16_t _port = 0; std::string _password; bool _desynchronised = false; uint32_t server_connect_time = 0; @@ -430,6 +434,20 @@ bool Network::Init() return true; } +void Network::Reconnect() +{ + if (status != NETWORK_STATUS_NONE) + { + Close(); + } + if (_requireClose) + { + _requireReconnect = true; + return; + } + BeginClient(_host, _port); +} + void Network::Close() { if (status != NETWORK_STATUS_NONE) @@ -508,6 +526,8 @@ bool Network::BeginClient(const std::string& host, uint16_t port) mode = NETWORK_MODE_CLIENT; log_info("Connecting to %s:%u\n", host.c_str(), port); + _host = host; + _port = port; _serverConnection = std::make_unique(); _serverConnection->Socket = CreateTcpSocket(); @@ -715,6 +735,10 @@ void Network::Update() if (_requireClose) { Close(); + if (_requireReconnect) + { + Reconnect(); + } } } @@ -3159,6 +3183,11 @@ void network_close() gNetwork.Close(); } +void network_reconnect() +{ + gNetwork.Reconnect(); +} + void network_shutdown_client() { gNetwork.ShutdownClient(); diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 434a1bfe06..9c294c65e0 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -31,6 +31,7 @@ namespace OpenRCT2 void network_set_env(const std::shared_ptr& env); void network_close(); +void network_reconnect(); void network_shutdown_client(); int32_t network_begin_client(const std::string& host, int32_t port); int32_t network_begin_server(int32_t port, const std::string& address); From 8c4de402391225c3807804ee36d448754245f706 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Tue, 5 Feb 2019 01:43:27 -0800 Subject: [PATCH 260/506] Add graphics for desync notice --- resources/g2/icons/multiplayer_desync.png | Bin 0 -> 264 bytes resources/g2/icons/multiplayer_sync.png | Bin 0 -> 267 bytes resources/g2/sprites.json | 10 ++++++++++ src/openrct2-ui/windows/TopToolbar.cpp | 7 ++++--- src/openrct2/sprites.h | 5 ++++- 5 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 resources/g2/icons/multiplayer_desync.png create mode 100644 resources/g2/icons/multiplayer_sync.png diff --git a/resources/g2/icons/multiplayer_desync.png b/resources/g2/icons/multiplayer_desync.png new file mode 100644 index 0000000000000000000000000000000000000000..899cfde22699474e7330cffaff887efde0dfbf48 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^VnEEt!3-p2-pl+4QpN#3A+8M!4gZ1Q@`}5Y{WpL4 zsGOGj|FPTN9F=(s?Ek;Kq~AGtPP6URpWpxg-~IfKL~?}e|Njgp+P`oBwKJ9k`2{mL zJiCzwvL>2?hKLWyxQ?>b|fr5FSE{-7;ajB=m`HmQHxCXAuKJ})4>*oRy^@;D< z7bt6FC5!#KcEh<|{iVBk{@H`4euX7J3wXM!zwf}At^4ktSx~C-^xN4x2bB(8sNL0? zcH~0IobAFA*4}#6?B~}B&-ztU&$RqO=NXLCeu8PkngwuGo&FFXx|Jd)KzMDz$jK`r)iJZJX@1|LYh7?=f$zEWDlsw3)%v L)z4*}Q$iB}y0>nM literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 81eabe7675..7f3bac5eb7 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -418,6 +418,16 @@ { "path": "icons/map_east_pressed.png" }, + { + "path": "icons/multiplayer_sync.png", + "x_offset": 0, + "y_offset": 0 + }, + { + "path": "icons/multiplayer_desync.png", + "x_offset": 0, + "y_offset": 0 + }, { "path": "font/latin/ae-uc-small.png", "y_offset": 0, diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 0bddbc5f78..349180f178 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -999,10 +999,11 @@ static void window_top_toolbar_paint(rct_window* w, rct_drawpixelinfo* dpi) imgId = SPR_SHOW_GUESTS_ON_THIS_RIDE_ATTRACTION; gfx_draw_sprite(dpi, imgId, x, y, 0); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - if (network_is_desynchronised()) - gfx_draw_string(dpi, "", COLOUR_BORDEAUX_RED | COLOUR_FLAG_OUTLINE, x - 1, y + 2); + imgId = (network_is_desynchronised() ? SPR_G2_MULTIPLAYER_DESYNC : SPR_G2_MULTIPLAYER_SYNC); + gfx_draw_sprite(dpi, imgId, x + 3, y + 11, 0); + int32_t player_count = network_get_num_players(); - gfx_draw_string_right(dpi, STR_COMMA16, &player_count, COLOUR_WHITE | COLOUR_FLAG_OUTLINE, x + 24, y + 15); + gfx_draw_string_right(dpi, STR_COMMA16, &player_count, COLOUR_WHITE | COLOUR_FLAG_OUTLINE, x + 23, y + 1); } } diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 8f31e5f2e1..869a5ca1f5 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -838,7 +838,10 @@ enum SPR_G2_MAP_EAST = SPR_G2_BEGIN + 120, SPR_G2_MAP_EAST_PRESSED = SPR_G2_BEGIN + 121, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 122, + SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 122, + SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 123, + + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 124, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From c075eec224f081bbab00aafd8781941afb1155a3 Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Tue, 5 Feb 2019 10:10:52 -0800 Subject: [PATCH 261/506] Update sync icons, new multiplayer toolbar button The multiplayer toolbar button is the same globe used for the multiplayer option on the title screen, since it seems like a nicer (and better?) looking option than the two riders. Also conflicts less with the new sync icons. --- resources/g2/icons/multiplayer_desync.png | Bin 264 -> 976 bytes resources/g2/icons/multiplayer_sync.png | Bin 267 -> 972 bytes resources/g2/icons/multiplayer_toolbar.png | Bin 0 -> 910 bytes resources/g2/sprites.json | 5 +++++ src/openrct2-ui/windows/TopToolbar.cpp | 4 ++-- src/openrct2/sprites.h | 7 ++++--- 6 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 resources/g2/icons/multiplayer_toolbar.png diff --git a/resources/g2/icons/multiplayer_desync.png b/resources/g2/icons/multiplayer_desync.png index 899cfde22699474e7330cffaff887efde0dfbf48..43e989b94527281f44eea97b532293f16943b138 100644 GIT binary patch literal 976 zcmaJ=!He8<6n;`9b(b~BKu1hVggHdaA(SYw4JFlV8Q18hG}{KrAxf}w7}kJMMjA2V z90r+UglP$Nz!7p7Fz6@?8!(61Mj2typaUHt$P`99hdo3IINC*irvHGC@4fGPm-ijs zdmo(Nu5YY8wgvzjThDJ^DEU~K4<9{J*5mnc1aJh-zqoU*Z2u>!wOWm38Br7zMKTP{ zvdnh7?RkUIC`^)RmgPmkG9d6EOY53eX*S80&2+lF*O!MQJ&LVK+MO?ak;YVh-IS`1 zO1cI$u-Lt}7<=kuWM<>eGV@n?QYS#Cp(TK;U_%p&yZCHaDJBG3GN{nep^H#b1CRl9 z3^Q@uAqbbEe4gKv<#D4ibDV?00L3xER%$|(kx5>s>L#r^tl{!jUu*|bFH-!89%c=a zBba)PS7^!LG*dJ?a%Z3qLNiRABJHh{E&axrdDt&b=z7R*%b&MiN8 z6SODO6@w#Mb-JtaLqm)#C2bos&sqfSJoZ*;fEEc};V4>VxrQLN6s2nz{Z?z#?Z$&a z8iw=fG|zJcgb9>~u|r&p2xUSy=3-}|`O8+6yVGK{Je;l2I*sF8wOS`@3e6ZiZ%J}T zFNfKqZf`ssWl37h1<)nTQgBBn-6q|)g`lHE{l++OW^sQxON!zE2>>d91>gb%0Aqj! z2B?HABHKcNkFuFefyqKofUpjk3`hZFR#BHlzKp^qnsiX+!~Ml`Ac>&LSktIFExPB{ zhrSU-?KBOR%M_JfL<3lRU2vfFrRwgKGlWR9L$q zxlYsXIZ@C{lVF)8sF-t-ghD_WAOxjX3CisdZMzg)-z(8yEUd|-6r!dn&8A`7Cd;%r z#uL~;WMhe$%JfpLA)Q1Hh59TC1(ZtV<^M3h^I1s`ym?_;fwOmixm-5yZf!oh^XT>0 ze!RKy-Q!2!d-e7ocWylN!q1;S^Ch%SUuD04(sZ$p_xJzBzkTQA6K8)r_315k_Q^f^ z8~n`IHh%f{i!WVNUMA+J*DmeuzQwNZ)=uevC0AZQ_Q=MsOt^FPscZXh-23|ktld7r we0cZdwT~_h9-Mm0p9k0Xe>%K!<0kpf+h^>jZ@FLH|I4j&+nZlJ_saYK0a`bs00000 delta 237 zcmVC!KW zlbnM+)%o}T|GVeh7-Lu+|Nj8Uhx7;l0004WQchC)6ep4I2WFrnC~9LC`qtP(e<$fj zH*d|s%KBDg=1}FTkB-31wZ7fVpmikW_RZYEBErypx`k%M&~%))6Bs*7E_(;ht`nO2 ne18I`;8pwTB^}Z7eqPZZKN$sw;PZ`|00000NkvXXu0mjfMkjCQ diff --git a/resources/g2/icons/multiplayer_sync.png b/resources/g2/icons/multiplayer_sync.png index bb78f2bc4e8c44895ba29c5b20985b87f2a58fa4..596f876fa3f9cd77afbf21113702d8a91173a2da 100644 GIT binary patch literal 972 zcmaJ=(W~2Z6h5+tjCC`(!m4Hvq0ArwBSeWBG~04Vyk^{tWe~JTHo{i1Zh6R{XdVI< zEK*p|A{kUH7@@k16}e!p7L5|24?*H6tU?Bz7T1TV!R4XgefXLE10KF}zVE!8@8O*D z!Kp3jz`n=#0l}78%D#j z%uc7{dBgEIjN@6B5bl}4l5YLRW5>GpVUpp3@)B(jpUw^;fjjcI(vlxvPg zx&}40*zJxOd0H|yvuSsg`RhEE2+(P03*f5Q$i$)^J|9(!gg`3>6*}5=5sK>o3V@Db zCXPD<;Zl^(^V^CtZ8qnQb8k3AQADuSx=>>jlGiE8q&0^%T;3Xpoj~qSR6o(ftVwbN zBh`78mJP09ie^{o4)tMZhN%;0{d6^2tRq~2stUCxkTy^*#tm!Im}*3VnQFa-<>zjU zwiUW+a70_8dm2A7#EGS*9b@iU%b=4--Z~A?GRCVMMQbeA6vVcw_6%dtZjXDtXgEy6 za50@FMrsy)fwSutMi&ey0y<2YBVNn~B68H497S?TKK zFniqVPeNueNK9hzhCsGd)^5tK z)AIYyBO6BtMe_q_VR?}9Mvmai%{g3wQt>pUCe|_?sG{0ph zNA~`G?W3pQ%bm-gpZ)Ol{KjKDSFXPN{adX&^>3biqj>(sgHN)%|GsdrFYO5W(L>`S sw?Dn~)ya3>zCS&0tuNj`mJj~C`n{UREa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC~+*nC&cwX!~fZjAFqG@ z`~Bz7_rLG2Uf;d`_TkI7Z(slZ|NQ6si{JOVFJIg~KYsG=;Qq^>x8F`b|9p9J^6ci- z-t)KTm+yWbz4-az|Cq-|k;tzFs^1KD+U9``}>jWb^2JXX)V6&F9Z|-!EoRpKffP9vs}w@4Q=GJ6zw{ zIeB(DgLMAl)A9Mu&DO!%*754m#l`OV+TO{@&C{m`XJuNfFi zg8YIR9G=}s196hP-CZ0z@8$RbIh+L^k;M!Qd`Cc-ajG_-G*FPe#M9T6{V@}(peeVd z?55>FJ&QeE978nD_fC2nw%9({cSI#cSEqB*_uMf56JoW0L z{JszGEzh4Z@Db>-xpcZb$4%(e4asgb z#pgf%X!UNM82h~COuoQ#d&A^8u?yFDbcd^XHB3p{^GHvEx##{bJ+B2P|AaqPJp9Ax zbif?Gq}cneN^HtMKBnD5QC>S`HTAoc-tNlV#k0k9cbJE!TLrT~#3UOwwgs8) zTUT1VwL0ISoo%vZ>g~79i$fnP_$oY+Vl&!SA9QH7ae$=&J7*=^?(%_(xONRryKJKg_)~@eneL?1_jv9M@c`e~O0i$w{djk% zOn+}y + window_top_toolbar_widgets[WIDX_NETWORK].top + 0; if (widget_is_pressed(w, WIDX_NETWORK)) y++; - imgId = SPR_SHOW_GUESTS_ON_THIS_RIDE_ATTRACTION; - gfx_draw_sprite(dpi, imgId, x, y, 0); + imgId = SPR_G2_MULTIPLAYER_TOOLBAR; + gfx_draw_sprite(dpi, imgId, x - 2, y - 2, 0); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; imgId = (network_is_desynchronised() ? SPR_G2_MULTIPLAYER_DESYNC : SPR_G2_MULTIPLAYER_SYNC); gfx_draw_sprite(dpi, imgId, x + 3, y + 11, 0); diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 869a5ca1f5..ff09958c04 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -838,10 +838,11 @@ enum SPR_G2_MAP_EAST = SPR_G2_BEGIN + 120, SPR_G2_MAP_EAST_PRESSED = SPR_G2_BEGIN + 121, - SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 122, - SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 123, + SPR_G2_MULTIPLAYER_TOOLBAR = SPR_G2_BEGIN + 122, + SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 123, + SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 124, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 124, + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 125, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From 7e6bed39d4e6b602001cf97d7f18209a12a044ad Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Thu, 7 Feb 2019 16:32:05 -0800 Subject: [PATCH 262/506] Fix z->s and DISABLE_NETWORK support --- src/openrct2/network/Network.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index a486bf31eb..05a0659751 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -136,7 +136,7 @@ public: static const char* FormatChat(NetworkPlayer* fromplayer, const char* text); void SendPacketToClients(NetworkPacket& packet, bool front = false, bool gameCmd = false); bool CheckSRAND(uint32_t tick, uint32_t srand0); - bool IsDesynchronized(); + bool IsDesynchronised(); void CheckDesynchronizaton(); void KickPlayer(int32_t playerId); void SetPassword(const char* password); @@ -1012,7 +1012,7 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) return true; } -bool Network::IsDesynchronized() +bool Network::IsDesynchronised() { return gNetwork._desynchronised; } @@ -3230,7 +3230,7 @@ int32_t network_get_status() bool network_is_desynchronised() { - return gNetwork.IsDesynchronized(); + return gNetwork.IsDesynchronised(); } void network_check_desynchronization() @@ -4017,6 +4017,10 @@ void network_flush() void network_send_tick() { } +bool network_is_desynchronised() +{ + return false; +} void network_check_desynchronization() { } @@ -4177,6 +4181,9 @@ void network_send_password(const std::string& password) void network_close() { } +void network_reconnect() +{ +} void network_set_env(const std::shared_ptr&) { } From 4a34d2a6da5147dd4c1062cc97821cdb751af0df Mon Sep 17 00:00:00 2001 From: Xkeeper Date: Fri, 8 Feb 2019 10:53:31 -0800 Subject: [PATCH 263/506] Disable "Reconnect" if not desynced. --- src/openrct2-ui/windows/TopToolbar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 0817612147..ae3607868e 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3427,6 +3427,8 @@ static void top_toolbar_init_network_menu(rct_window* w, rct_widget* widget) w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0, TOP_TOOLBAR_NETWORK_COUNT); + dropdown_set_disabled(DDIDX_MULTIPLAYER_RECONNECT, !network_is_desynchronised()); + gDropdownDefaultIndex = DDIDX_MULTIPLAYER; } From f842d8a69392d118a2a1b0f4f553e02befccc67a Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 1 May 2019 20:51:55 +0000 Subject: [PATCH 264/506] Fix #5103: OpenGL: ride track preview not rendered --- distribution/changelog.txt | 1 + .../engines/opengl/OpenGLDrawingEngine.cpp | 1 + src/openrct2-ui/windows/InstallTrack.cpp | 1 + src/openrct2-ui/windows/TrackList.cpp | 27 +++++++------------ src/openrct2/drawing/Drawing.Sprite.cpp | 2 +- src/openrct2/drawing/Drawing.cpp | 7 +---- src/openrct2/drawing/Drawing.h | 21 ++++++++++----- src/openrct2/drawing/LightFX.cpp | 3 +-- src/openrct2/drawing/NewDrawing.cpp | 16 +++++------ src/openrct2/drawing/ScrollingText.cpp | 13 +++------ src/openrct2/drawing/X8DrawingEngine.cpp | 1 + src/openrct2/interface/Viewport.cpp | 2 +- src/openrct2/interface/Window.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 7 +++++ 14 files changed, 51 insertions(+), 53 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 338d9f98c8..a7779cd08d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -9,6 +9,7 @@ - Feature: [#9154] Change map toolbar icon with current viewport rotation. - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. +- Fix: [#5103] OpenGL: ride track preview not rendered. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#5893] Looking at guest window tabs other than the main tab eventually causes assertion. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 7dfaac808e..0316349754 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -148,6 +148,7 @@ public: { _window = (SDL_Window*)_uiContext->GetWindow(); _drawingContext = new OpenGLDrawingContext(this); + _bitsDPI.DrawingEngine = this; # ifdef __ENABLE_LIGHTFX__ lightfx_set_available(false); # endif diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index cb80258cb6..fe669ad2f3 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -238,6 +238,7 @@ static void window_install_track_paint(rct_window* w, rct_drawpixelinfo* dpi) g1temp.height = 217; g1temp.flags = G1_FLAG_BMP; gfx_set_g1_element(SPR_TEMP, &g1temp); + drawing_engine_invalidate_image(SPR_TEMP); gfx_draw_sprite(dpi, SPR_TEMP, x, y, 0); x = w->x + (widget->left + widget->right) / 2; diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index ea9d93a13d..9ebad3bc71 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -544,20 +544,14 @@ static void window_track_list_paint(rct_window* w, rct_drawpixelinfo* dpi) x = w->x + (widget->left + widget->right) / 2; y = w->y + (widget->top + widget->bottom) / 2; - if (drawing_engine_get_type() != DRAWING_ENGINE_OPENGL) - { - rct_g1_element g1temp = {}; - g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); - g1temp.width = 370; - g1temp.height = 217; - g1temp.flags = G1_FLAG_BMP; - gfx_set_g1_element(SPR_TEMP, &g1temp); - gfx_draw_sprite(dpi, SPR_TEMP, trackPreviewX, trackPreviewY, 0); - } - else - { - gfx_draw_string_centred_clipped(dpi, STR_NOT_SUPPPORTED_IN_OPENGL, nullptr, COLOUR_BLACK, x, y, 368); - } + rct_g1_element g1temp = {}; + g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); + g1temp.width = 370; + g1temp.height = 217; + g1temp.flags = G1_FLAG_BMP; + gfx_set_g1_element(SPR_TEMP, &g1temp); + drawing_engine_invalidate_image(SPR_TEMP); + gfx_draw_sprite(dpi, SPR_TEMP, trackPreviewX, trackPreviewY, 0); y = w->y + widget->bottom - 12; @@ -810,10 +804,7 @@ static bool track_list_load_design_for_preview(utf8* path) _loadedTrackDesign = track_design_open(path); if (_loadedTrackDesign != nullptr) { - if (drawing_engine_get_type() != DRAWING_ENGINE_OPENGL) - { - track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels.data()); - } + track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels.data()); return true; } return false; diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 8c93edcfed..855de4ce9d 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -619,7 +619,7 @@ void FASTCALL gfx_draw_sprite_palette_set_software( if (dpi->zoom_level != 0 && (g1->flags & G1_FLAG_HAS_ZOOM_SPRITE)) { - rct_drawpixelinfo zoomed_dpi; + rct_drawpixelinfo zoomed_dpi = *dpi; zoomed_dpi.bits = dpi->bits; zoomed_dpi.x = dpi->x >> 1; zoomed_dpi.y = dpi->y >> 1; diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index a2caf9e958..7d05c50978 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -591,12 +591,7 @@ bool clip_drawpixelinfo(rct_drawpixelinfo* dst, rct_drawpixelinfo* src, int32_t int32_t right = x + width; int32_t bottom = y + height; - dst->bits = src->bits; - dst->x = src->x; - dst->y = src->y; - dst->width = src->width; - dst->height = src->height; - dst->pitch = src->pitch; + *dst = *src; dst->zoom_level = 0; if (x > dst->x) diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 0e98f3358c..be47eac4dc 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -18,6 +18,11 @@ namespace OpenRCT2 interface IPlatformEnvironment; } +namespace OpenRCT2::Drawing +{ + interface IDrawingEngine; +} + struct rct_g1_element { uint8_t* offset; // 0x00 @@ -31,13 +36,15 @@ struct rct_g1_element struct rct_drawpixelinfo { - uint8_t* bits; // 0x00 - int16_t x; // 0x04 - int16_t y; // 0x06 - int16_t width; // 0x08 - int16_t height; // 0x0A - int16_t pitch; // 0x0C note: this is actually (pitch - width) - uint16_t zoom_level; // 0x0E + uint8_t* bits{}; + int16_t x{}; + int16_t y{}; + int16_t width{}; + int16_t height{}; + int16_t pitch{}; // note: this is actually (pitch - width) + uint16_t zoom_level{}; + + OpenRCT2::Drawing::IDrawingEngine* DrawingEngine{}; }; struct rct_g1_element_32bit diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index 8dc6bc4b61..7965d478e1 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -170,8 +170,7 @@ void lightfx_update_buffers(rct_drawpixelinfo* info) { _light_rendered_buffer_front = realloc(_light_rendered_buffer_front, info->width * info->height); _light_rendered_buffer_back = realloc(_light_rendered_buffer_back, info->width * info->height); - - std::memcpy(&_pixelInfo, info, sizeof(rct_drawpixelinfo)); + _pixelInfo = *info; } extern void viewport_paint_setup(); diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index b96d8c4e6e..caf66f57e9 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -170,7 +170,7 @@ void gfx_draw_all_dirty_blocks() void gfx_clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -180,7 +180,7 @@ void gfx_clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) void gfx_fill_rect(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -191,7 +191,7 @@ void gfx_fill_rect(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t ri void gfx_filter_rect( rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, FILTER_PALETTE_ID palette) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -201,7 +201,7 @@ void gfx_filter_rect( void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -211,7 +211,7 @@ void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, i void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint32_t tertiary_colour) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -221,7 +221,7 @@ void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, int32_t x, void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t* palette) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -231,7 +231,7 @@ void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image, int32_t x, i void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); @@ -241,7 +241,7 @@ void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, int32_t x, int3 void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t colour) { - auto drawingEngine = GetDrawingEngine(); + auto drawingEngine = dpi->DrawingEngine; if (drawingEngine != nullptr) { IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index a054247a43..0cd93dd614 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -49,15 +49,10 @@ static void scrolling_text_set_bitmap_for_ttf( void scrolling_text_initialise_bitmaps() { uint8_t drawingSurface[64]; - rct_drawpixelinfo dpi = { - /* .bits = */ (uint8_t*)&drawingSurface, - /* .x = */ 0, - /* .y = */ 0, - /* .width = */ 8, - /* .height = */ 8, - /* .pitch = */ 0, - /* .zoom_level = */ 0, - }; + rct_drawpixelinfo dpi; + dpi.bits = (uint8_t*)&drawingSurface; + dpi.width = 8; + dpi.height = 8; for (int32_t i = 0; i < FONT_SPRITE_GLYPH_COUNT; i++) { diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 310dfb6280..6569f5bbe8 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -131,6 +131,7 @@ void X8RainDrawer::Restore() X8DrawingEngine::X8DrawingEngine([[maybe_unused]] const std::shared_ptr& uiContext) { _drawingContext = new X8DrawingContext(this); + _bitsDPI.DrawingEngine = this; #ifdef __ENABLE_LIGHTFX__ lightfx_set_available(true); _lastLightFXenabled = (gConfigGeneral.enable_light_fx != 0); diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index d2b3a4ce25..b85c0201c2 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -903,7 +903,7 @@ void viewport_paint( y >>= viewport->zoom; y += viewport->y; - rct_drawpixelinfo dpi1; + rct_drawpixelinfo dpi1 = *dpi; dpi1.bits = dpi->bits + (x - dpi->x) + ((y - dpi->y) * (dpi->width + dpi->pitch)); dpi1.x = left; dpi1.y = top; diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index b294806ba8..c29279a90a 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -2098,7 +2098,7 @@ bool window_is_visible(rct_window* w) */ void window_draw_all(rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom) { - rct_drawpixelinfo windowDPI; + rct_drawpixelinfo windowDPI = *dpi; windowDPI.bits = dpi->bits + left + ((dpi->width + dpi->pitch) * top); windowDPI.x = left; windowDPI.y = top; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 83ba5a32cb..8a64473623 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -28,6 +28,7 @@ #include "../audio/audio.h" #include "../core/File.h" #include "../core/String.hpp" +#include "../drawing/X8DrawingEngine.h" #include "../localisation/Localisation.h" #include "../localisation/StringIds.h" #include "../management/Finance.h" @@ -54,6 +55,9 @@ #include #include +using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; + struct map_backup { TileElement tile_elements[MAX_TILE_ELEMENTS]; @@ -2245,6 +2249,9 @@ void track_design_draw_preview(rct_track_td6* td6, uint8_t* pixels) dpi.pitch = 0; dpi.bits = pixels; + auto drawingEngine = std::make_unique(GetContext()->GetUiContext()); + dpi.DrawingEngine = drawingEngine.get(); + CoordsXY offset = { size_x / 2, size_y / 2 }; for (uint8_t i = 0; i < 4; i++) { From 39123f68ebe16358db239e6aee69bdf7d3c90d0c Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 1 May 2019 23:01:46 +0100 Subject: [PATCH 265/506] Fix #5889: Giant screenshot does not work while using OpenGL renderer --- distribution/changelog.txt | 1 + src/openrct2/interface/Screenshot.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index a7779cd08d..f9f5a0b353 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -10,6 +10,7 @@ - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5103] OpenGL: ride track preview not rendered. +- Fix: [#5889] Giant screenshot does not work while using OpenGL renderer. - Fix: [#5579] Network desync immediately after connecting. - Fix: [#5893] Looking at guest window tabs other than the main tab eventually causes assertion. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 763fd2a89a..0075b9340b 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -17,6 +17,7 @@ #include "../core/Console.hpp" #include "../core/Imaging.h" #include "../drawing/Drawing.h" +#include "../drawing/X8DrawingEngine.h" #include "../localisation/Localisation.h" #include "../platform/platform.h" #include "../util/Util.h" @@ -31,6 +32,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; uint8_t gScreenshotCountdown = 0; @@ -293,6 +295,9 @@ void screenshot_giant() dpi.zoom_level = 0; dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); + auto drawingEngine = std::make_unique(GetContext()->GetUiContext()); + dpi.DrawingEngine = drawingEngine.get(); + viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); // Get a free screenshot path From 57040c392c0c475cdf1dde0188fbdb08db51f933 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 2 May 2019 12:32:45 +0200 Subject: [PATCH 266/506] Change multiplayer toolbar image to framed globe, with pressed state. --- resources/g2/icons/multiplayer_toolbar.png | Bin 910 -> 1240 bytes .../g2/icons/multiplayer_toolbar_pressed.png | Bin 0 -> 1235 bytes resources/g2/sprites.json | 15 ++++++--------- src/openrct2-ui/windows/TopToolbar.cpp | 9 +++++---- src/openrct2/sprites.h | 9 +++++---- 5 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 resources/g2/icons/multiplayer_toolbar_pressed.png diff --git a/resources/g2/icons/multiplayer_toolbar.png b/resources/g2/icons/multiplayer_toolbar.png index 4838985f304d5477120cc73fdda76202f78d6dd9..a2c9e734fa45a8d3dcaab8742dfd6b4367d184f2 100644 GIT binary patch literal 1240 zcmaJ>@oy7#6#ovCB6D`qV1+{~l;kE=FK{e3DRRh-l%>lKIbto{a*%^H(1b%yD6`;2 z8fc`!i>XN&6>D-}A)Ov(W(}0Az~Poy$pIx+J+XljDo$6Vm?|ZHJ^le-KJUHH`{jLJ z@?PEtYkFKQGv>?y0JLq%U9$r)rM{+n-72H}AG6x+b{xkjiewl! z$N2<-4~N6?cv4X^s#?(XYORK2fOG=d-R$#O0s&hvghisxc!EwTY&Iw4wP>j1TarU770Cf;lo5kx{!+36gn>2bfmD2fxwB+TUy++ruK7;SU1sEc=aM4XeHLV^mX z-LWhq=h=+zw-E^DvO5`vnq(aVXO; z6M*>$)MfB!@dR*Fz(bn?oK*}uVv;K*bJ=WI)6$iS1`RF55AaYkDOqXR#%54ncS==X zx)#jV+9OIomaJ<3oBZu-CYh^+jrdk=-B0zo34z!i_xe07A+WQ z{$p|kJv3zAv}ca_=Tkej_cu)K_xi-zrJf_}8+`*y8b|+%lJ}P1o@C#4%Wt=3@``uRVP=rn6_a_tM`A-uuG5YZH5BP9y&wxYdz3{>;rcx?a51Yx?&hKiKmA zYgp^xxwgmW9(b8-Ie-03w_g*3p69KhI4rDiGeUdyg!g zx2fN=_q$!YHxwe3*}t&gjF`pd#iw7G`fzE-`PreL=Esv`cV=DNvhT*>6T{cz&isRg ib=SVF-mLu95dZL>he}_gJnPYa>RQ#)`Q^$D`~Cw5z%Lm9 literal 910 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s3?yAI>n{UREa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC~+*nC&cwX!~fZjAFqG@ z`~Bz7_rLG2Uf;d`_TkI7Z(slZ|NQ6si{JOVFJIg~KYsG=;Qq^>x8F`b|9p9J^6ci- z-t)KTm+yWbz4-az|Cq-|k;tzFs^1KD+U9``}>jWb^2JXX)V6&F9Z|-!EoRpKffP9vs}w@4Q=GJ6zw{ zIeB(DgLMAl)A9Mu&DO!%*754m#l`OV+TO{@&C{m`XJuNfFi zg8YIR9G=}s196hP-CZ0z@8$RbIh+L^k;M!Qd`Cc-ajG_-G*FPe#M9T6{V@}(peeVd z?55>FJ&QeE978nD_fC2nw%9({cSI#cSEqB*_uMf56JoW0L z{JszGEzh4Z@Db>-xpcZb$4%(e4asgb z#pgf%X!UNM82h~COuoQ#d&A^8u?yFDbcd^XHB3p{^GHvEx##{bJ+B2P|AaqPJp9Ax zbif?Gq}cneN^HtMKBnD5QC>S`HTAoc-tNlV#k0k9cbJE!TLrT~#3UOwwgs8) zTUT1VwL0ISoo%vZ>g~79i$fnP_$oY+Vl&!SA9QH7ae$=&J7*=^?(%_(xONRryKJKg_)~@eneL?1_jv9M@c`e~O0i$w{djk% zOn+}@oy7#6#pvG62@#|F)fx*unD)Mh8j*NaAdb}KpDjyat#$usd7k#inmd;m|_mO z;AIxLKnEo@t}Z93>veBOJX_si$= z!+Uu>8#>+1GoGCR0BG)5yK1A}=ju6U`ZT?^FMtUE9-rK>-n&{K|0m3LyB$TH1c6hO zhhgYYh~;@c9#5vzimDb$rCPm?IsuLW($hrKreM$(jyQ!V7Eh3=v_F##<+W(JA`uRQ z4{KsQX3l3586+7(2YDhJ_vO=UDJN7*QlqB2t-$X9VH}8*A;lW9QDZS>s^_h+>V$Pa zoDv~a?EsJf_zecuXymL`5kVvj8zjkGAW-DE(PR>4vsTn($IVXChWQaU>+o?XBVwTh z!ONalhLZArr4+EatWLKbqZ}T_MY9AekV4X*R9Hph)KW~Vrpk@15eFs;m;=BT0f=aD zCC%!TNjS@e)sb2d%M8c+jBQxUwLDvW#DAbn@0rI*N1Lu{-Vn~@Y2xufi-;h zS#{vUOUL(Q(#x zor!<;H;)Xzr&=r%KYY41J^JsJz+e5pSs1eD?)B#47i~+}zD>UR8>m>g>wb5B>+aQZn}d literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 1f0a72d449..6a77ebd8b8 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -419,19 +419,16 @@ "path": "icons/map_east_pressed.png" }, { - "path": "icons/multiplayer_toolbar.png", - "x_offset": 0, - "y_offset": 0 + "path": "icons/multiplayer_toolbar.png" }, { - "path": "icons/multiplayer_sync.png", - "x_offset": 0, - "y_offset": 0 + "path": "icons/multiplayer_toolbar_pressed.png" }, { - "path": "icons/multiplayer_desync.png", - "x_offset": 0, - "y_offset": 0 + "path": "icons/multiplayer_sync.png" + }, + { + "path": "icons/multiplayer_desync.png" }, { "path": "font/latin/ae-uc-small.png", diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index ae3607868e..23d0ebf860 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -251,7 +251,7 @@ static rct_widget window_top_toolbar_widgets[] = { { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_TAB_TOOLBAR, STR_SCENARIO_OPTIONS_FINANCIAL_TIP },// Finances { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_TAB_TOOLBAR, STR_FINANCES_RESEARCH_TIP }, // Research { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_TAB_TOOLBAR, STR_SHOW_RECENT_MESSAGES_TIP }, // News - { WWT_TRNBTN, 0, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_TAB_TOOLBAR, STR_SHOW_MULTIPLAYER_STATUS_TIP }, // Network + { WWT_TRNBTN, 0, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_G2_TOOLBAR_MULTIPLAYER, STR_SHOW_MULTIPLAYER_STATUS_TIP }, // Network { WWT_TRNBTN, 0, 0x001E, 0x003B, 0, TOP_TOOLBAR_HEIGHT, IMAGE_TYPE_REMAP | SPR_TAB_TOOLBAR, STR_TOOLBAR_CHAT_TIP }, // Chat { WWT_EMPTY, 0, 0, 10-1, 0, 0, 0xFFFFFFFF, STR_NONE }, // Artificial widget separator @@ -996,13 +996,14 @@ static void window_top_toolbar_paint(rct_window* w, rct_drawpixelinfo* dpi) y = w->y + window_top_toolbar_widgets[WIDX_NETWORK].top + 0; if (widget_is_pressed(w, WIDX_NETWORK)) y++; - imgId = SPR_G2_MULTIPLAYER_TOOLBAR; - gfx_draw_sprite(dpi, imgId, x - 2, y - 2, 0); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + + // Draw (de)sync icon. imgId = (network_is_desynchronised() ? SPR_G2_MULTIPLAYER_DESYNC : SPR_G2_MULTIPLAYER_SYNC); gfx_draw_sprite(dpi, imgId, x + 3, y + 11, 0); + // Draw number of players. int32_t player_count = network_get_num_players(); + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_draw_string_right(dpi, STR_COMMA16, &player_count, COLOUR_WHITE | COLOUR_FLAG_OUTLINE, x + 23, y + 1); } } diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index ff09958c04..ee35b4c50c 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -838,11 +838,12 @@ enum SPR_G2_MAP_EAST = SPR_G2_BEGIN + 120, SPR_G2_MAP_EAST_PRESSED = SPR_G2_BEGIN + 121, - SPR_G2_MULTIPLAYER_TOOLBAR = SPR_G2_BEGIN + 122, - SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 123, - SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 124, + SPR_G2_TOOLBAR_MULTIPLAYER = SPR_G2_BEGIN + 122, + SPR_G2_TOOLBAR_MULTIPLAYER_PRESSED = SPR_G2_BEGIN + 123, + SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 124, + SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 125, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 125, + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 126, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From f6b610c325dea54472ccee905beaefc4e6e0a14c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 09:44:07 +0100 Subject: [PATCH 267/506] Implement Banner Place/Remove Actions --- src/openrct2-ui/windows/Banner.cpp | 9 +- src/openrct2-ui/windows/TopToolbar.cpp | 57 +++-- src/openrct2/Game.cpp | 45 +--- src/openrct2/actions/BannerPlaceAction.hpp | 199 ++++++++++++++++++ src/openrct2/actions/BannerRemoveAction.hpp | 155 ++++++++++++++ src/openrct2/actions/FootpathRemoveAction.hpp | 24 ++- .../actions/GameActionRegistration.cpp | 4 + src/openrct2/windows/_legacy.cpp | 13 -- src/openrct2/world/Banner.cpp | 191 ----------------- src/openrct2/world/Banner.h | 2 - src/openrct2/world/Footpath.cpp | 19 -- src/openrct2/world/Footpath.h | 1 - src/openrct2/world/Map.cpp | 10 +- src/openrct2/world/Map.h | 4 - src/openrct2/world/Scenery.cpp | 9 +- 15 files changed, 445 insertions(+), 297 deletions(-) create mode 100644 src/openrct2/actions/BannerPlaceAction.hpp create mode 100644 src/openrct2/actions/BannerRemoveAction.hpp diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index 3fe1b278f6..08237a7d8f 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -188,10 +189,12 @@ static void window_banner_mouseup(rct_window* w, rct_widgetindex widgetIndex) window_close(w); break; case WIDX_BANNER_DEMOLISH: - game_do_command( - x, 1, y, tile_element->base_height | (tile_element->AsBanner()->GetPosition() << 8), GAME_COMMAND_REMOVE_BANNER, - 0, 0); + { + auto bannerRemoveAction = BannerRemoveAction( + { x, y, tile_element->base_height * 8, tile_element->AsBanner()->GetPosition() }); + GameActions::Execute(&bannerRemoveAction); break; + } case WIDX_BANNER_TEXT: window_text_input_open( w, WIDX_BANNER_TEXT, STR_BANNER_TEXT, STR_ENTER_BANNER_TEXT, gBanners[w->number].string_idx, 0, 32); diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 855d53d892..c842b743f3 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1920,12 +1921,25 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo } case SCENERY_TYPE_BANNER: { - int32_t flags = (parameter_1 & 0xFF00) | GAME_COMMAND_FLAG_APPLY; - - gGameCommandErrorTitle = STR_CANT_POSITION_THIS_HERE; - game_command_callback = game_command_callback_place_banner; - game_do_command( - gridX, flags, gridY, parameter_2, GAME_COMMAND_PLACE_BANNER, parameter_3, gWindowSceneryPrimaryColour); + uint8_t direction = (parameter_2 >> 8) & 0xFF; + CoordsXYZD loc{ gridX, gridY, (parameter_2 & 0xFF) * 16, direction }; + auto primaryColour = gWindowSceneryPrimaryColour; + auto bannerType = (parameter_1 & 0xFF00) >> 8; + auto bannerIndex = create_new_banner(0); + if (bannerIndex == BANNER_INDEX_NULL) + { + context_show_error(STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + break; + } + auto bannerPlaceAction = BannerPlaceAction(loc, bannerType, bannerIndex, primaryColour); + bannerPlaceAction.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); + context_open_detail_window(WD_BANNER, bannerIndex); + } + }); + GameActions::Execute(&bannerPlaceAction); break; } } @@ -2611,20 +2625,35 @@ static money32 try_place_ghost_scenery( break; } case 4: + { // Banners // 6e2612 - cost = game_do_command( - map_tile.x, parameter_1 | 0x69, map_tile.y, parameter_2, GAME_COMMAND_PLACE_BANNER, parameter_3, 0); + uint8_t direction = (parameter_2 >> 8) & 0xFF; + CoordsXYZD loc{ map_tile.x, map_tile.y, (parameter_2 & 0xFF) * 16, direction }; + auto primaryColour = gWindowSceneryPrimaryColour; + auto bannerType = (parameter_1 & 0xFF00) >> 8; + auto bannerIndex = create_new_banner(0); + if (bannerIndex == BANNER_INDEX_NULL) + { + // Silently fail as this is just for the ghost + break; + } + auto bannerPlaceAction = BannerPlaceAction(loc, bannerType, bannerIndex, primaryColour); + bannerPlaceAction.SetFlags( + GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); + auto res = GameActions::Execute(&bannerPlaceAction); - if (cost == MONEY32_UNDEFINED) - return cost; + if (res->Error != GA_ERROR::OK) + return MONEY32_UNDEFINED; - gSceneryGhostPosition.x = map_tile.x; - gSceneryGhostPosition.y = map_tile.y; - gSceneryGhostPosition.z = (parameter_2 & 0xFF) * 2 + 2; - gSceneryPlaceRotation = ((parameter_2 >> 8) & 0xFF); + gSceneryGhostPosition.x = loc.x; + gSceneryGhostPosition.y = loc.y; + gSceneryGhostPosition.z = loc.z / 8 + 2; + gSceneryPlaceRotation = direction; gSceneryGhostType |= SCENERY_GHOST_FLAG_4; + cost = res->Cost; break; + } } return cost; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 37830717af..d211f75eae 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -92,7 +92,7 @@ static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = { nullptr, nullptr, nullptr, - game_command_callback_place_banner, + nullptr, nullptr, nullptr, game_command_callback_pickup_guest, @@ -407,12 +407,6 @@ int32_t game_do_command_p( // Increment nest count 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)) - { - scenery_remove_ghost_tool_placement(); - } - if (game_command_playerid == -1) { game_command_playerid = network_get_current_player_id(); @@ -608,39 +602,6 @@ 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_BANNER) - { - uint8_t flags = *ebx & 0xFF; - if (flags & GAME_COMMAND_FLAG_GHOST) - { - // Don't log ghost previews being removed - return; - } - - // Log placing scenery - char* args[1] = { - (char*)player_name, - }; - - format_string(log_msg, 256, STR_LOG_PLACE_SCENERY, args); - network_append_server_log(log_msg); - } - else if (command == GAME_COMMAND_REMOVE_BANNER) - { - uint8_t flags = *ebx & 0xFF; - if (flags & GAME_COMMAND_FLAG_GHOST) - { - // Don't log ghost previews being removed - return; - } - - // Log removing scenery - char* args[1] = { - (char*)player_name, - }; - format_string(log_msg, 256, STR_LOG_REMOVE_SCENERY, args); - network_append_server_log(log_msg); - } } void pause_toggle() @@ -1252,8 +1213,8 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_place_track_design, nullptr, game_command_place_maze_design, - game_command_place_banner, - game_command_remove_banner, + nullptr, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/actions/BannerPlaceAction.hpp b/src/openrct2/actions/BannerPlaceAction.hpp new file mode 100644 index 0000000000..4aa2317ee6 --- /dev/null +++ b/src/openrct2/actions/BannerPlaceAction.hpp @@ -0,0 +1,199 @@ +/***************************************************************************** + * 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 "../management/Finance.h" +#include "../world/Banner.h" +#include "../world/MapAnimation.h" +#include "../world/Scenery.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(BannerPlaceAction, GAME_COMMAND_PLACE_BANNER, GameActionResult) +{ +private: + CoordsXYZD _loc; + uint8_t _bannerType{ std::numeric_limits::max() }; + uint8_t _bannerIndex{ BANNER_INDEX_NULL }; + uint8_t _primaryColour; + +public: + BannerPlaceAction() = default; + BannerPlaceAction(CoordsXYZD loc, uint8_t bannerType, uint8_t bannerIndex, uint8_t primaryColour) + : _loc(loc) + , _bannerType(bannerType) + , _bannerIndex(bannerIndex) + , _primaryColour(primaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_bannerType) << DS_TAG(_bannerIndex) << DS_TAG(_primaryColour); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; + + if (!map_check_free_elements_and_reorganise(1)) + { + log_error("No free map elements."); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + + if (!map_is_location_valid({ _loc.x, _loc.y })) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + auto pathElement = GetValidPathElement(); + + if (pathElement == nullptr) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS); + } + + if (!map_can_build_at(_loc.x, _loc.y, _loc.z)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + } + + uint8_t baseHeight = _loc.z / 8 + 2; + BannerElement* existingBannerElement = map_get_banner_element_at(_loc.x / 32, _loc.y / 32, baseHeight, _loc.direction); + if (existingBannerElement != nullptr) + { + return MakeResult(GA_ERROR::ITEM_ALREADY_PLACED, STR_CANT_POSITION_THIS_HERE, STR_BANNER_SIGN_IN_THE_WAY); + } + + if (_bannerIndex == BANNER_INDEX_NULL || _bannerIndex >= MAX_BANNERS) + { + log_error("Invalid banner index, bannerIndex = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + if (gBanners[_bannerIndex].type != BANNER_NULL) + { + log_error("Banner index in use, bannerIndex = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + rct_scenery_entry* bannerEntry = get_banner_entry(_bannerType); + if (bannerEntry == nullptr) + { + log_error("Invalid banner object type. bannerType = ", _bannerType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + res->Cost = bannerEntry->banner.price; + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->ErrorTitle = STR_CANT_POSITION_THIS_HERE; + + if (!map_check_free_elements_and_reorganise(1)) + { + log_error("No free map elements."); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_CANT_POSITION_THIS_HERE); + } + + uint8_t baseHeight = _loc.z / 8 + 2; + + if (_bannerIndex == BANNER_INDEX_NULL || _bannerIndex >= MAX_BANNERS) + { + log_error("Invalid banner index, bannerIndex = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + if (gBanners[_bannerIndex].type != BANNER_NULL) + { + log_error("Banner index in use, bannerIndex = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + + TileElement* newTileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, baseHeight, 0); + assert(newTileElement != nullptr); + rct_banner* banner = &gBanners[_bannerIndex]; + + banner->flags = 0; + banner->string_idx = STR_DEFAULT_SIGN; + banner->text_colour = 2; + banner->type = _bannerType; + banner->colour = _primaryColour; + banner->x = _loc.x / 32; + banner->y = _loc.y / 32; + newTileElement->SetType(TILE_ELEMENT_TYPE_BANNER); + BannerElement* bannerElement = newTileElement->AsBanner(); + bannerElement->clearance_height = newTileElement->base_height + 2; + bannerElement->SetPosition(_loc.direction); + bannerElement->ResetAllowedEdges(); + bannerElement->SetIndex(_bannerIndex); + if (GetFlags() & GAME_COMMAND_FLAG_GHOST) + { + bannerElement->SetGhost(true); + } + map_invalidate_tile_full(_loc.x, _loc.y); + map_animation_create(MAP_ANIMATION_TYPE_BANNER, _loc.x, _loc.y, bannerElement->base_height); + + rct_scenery_entry* bannerEntry = get_banner_entry(_bannerType); + if (bannerEntry == nullptr) + { + log_error("Invalid banner object type. bannerType = ", _bannerType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + res->Cost = bannerEntry->banner.price; + return res; + } + +private: + PathElement* GetValidPathElement() const + { + TileElement* tileElement = map_get_first_element_at(_loc.x / 32, _loc.y / 32); + do + { + if (tileElement == nullptr) + break; + + if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + + auto pathElement = tileElement->AsPath(); + + if (pathElement->base_height != _loc.z / 8 && pathElement->base_height != _loc.z / 8 - 2) + continue; + + if (!(pathElement->GetEdges() & (1 << _loc.direction))) + continue; + + if (pathElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + continue; + + return pathElement; + } while (!(tileElement++)->IsLastForTile()); + return nullptr; + } +}; diff --git a/src/openrct2/actions/BannerRemoveAction.hpp b/src/openrct2/actions/BannerRemoveAction.hpp new file mode 100644 index 0000000000..6ee339b408 --- /dev/null +++ b/src/openrct2/actions/BannerRemoveAction.hpp @@ -0,0 +1,155 @@ +/***************************************************************************** + * 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 "../management/Finance.h" +#include "../world/Banner.h" +#include "../world/MapAnimation.h" +#include "../world/Scenery.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(BannerRemoveAction, GAME_COMMAND_REMOVE_BANNER, GameActionResult) +{ +private: + CoordsXYZD _loc; + +public: + BannerRemoveAction() = default; + BannerRemoveAction(CoordsXYZD loc) + : _loc(loc) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ErrorTitle = STR_CANT_REMOVE_THIS; + + if (!map_can_build_at(_loc.x, _loc.y, _loc.z - 16)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REMOVE_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + + BannerElement* bannerElement = GetBannerElementAt(); + if (bannerElement == nullptr) + { + log_error( + "Invalid banner location, x = %d, y = %d, z = %d, direction = %d", _loc.x, _loc.y, _loc.z, _loc.direction); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + if (bannerElement->GetIndex() >= MAX_BANNERS || bannerElement->GetIndex() == BANNER_INDEX_NULL) + { + log_error("Invalid banner index. index = ", bannerElement->GetIndex()); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + rct_banner* banner = &gBanners[bannerElement->GetIndex()]; + + if (banner == nullptr) + { + log_error("Invalid banner index. index = ", bannerElement->GetIndex()); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + rct_scenery_entry* bannerEntry = get_banner_entry(banner->type); + if (bannerEntry != nullptr) + { + res->Cost = -((bannerEntry->banner.price * 3) / 4); + } + + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ErrorTitle = STR_CANT_REMOVE_THIS; + + BannerElement* bannerElement = GetBannerElementAt(); + if (bannerElement == nullptr) + { + log_error( + "Invalid banner location, x = %d, y = %d, z = %d, direction = %d", _loc.x, _loc.y, _loc.z, _loc.direction); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + if (bannerElement->GetIndex() >= MAX_BANNERS || bannerElement->GetIndex() == BANNER_INDEX_NULL) + { + log_error("Invalid banner index. index = ", bannerElement->GetIndex()); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + rct_banner* banner = &gBanners[bannerElement->GetIndex()]; + + if (banner == nullptr) + { + log_error("Invalid banner index. index = ", bannerElement->GetIndex()); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + + rct_scenery_entry* bannerEntry = get_banner_entry(banner->type); + if (bannerEntry != nullptr) + { + res->Cost = -((bannerEntry->banner.price * 3) / 4); + } + + tile_element_remove_banner_entry(reinterpret_cast(bannerElement)); + map_invalidate_tile_zoom1(_loc.x, _loc.y, _loc.z / 8, _loc.z / 8 + 32); + bannerElement->Remove(); + + return res; + } + +private: + BannerElement* GetBannerElementAt() const + { + TileElement* tileElement = map_get_first_element_at(_loc.x / 32, _loc.y / 32); + + // Find the banner element at known z and position + do + { + if (tileElement == nullptr) + break; + if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER) + continue; + if (tileElement->base_height != _loc.z / 8) + continue; + if (tileElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + continue; + if (tileElement->AsBanner()->GetPosition() != _loc.direction) + continue; + + return tileElement->AsBanner(); + } while (!(tileElement++)->IsLastForTile()); + + return nullptr; + } +}; diff --git a/src/openrct2/actions/FootpathRemoveAction.hpp b/src/openrct2/actions/FootpathRemoveAction.hpp index 8869ed492b..34d8fce962 100644 --- a/src/openrct2/actions/FootpathRemoveAction.hpp +++ b/src/openrct2/actions/FootpathRemoveAction.hpp @@ -19,6 +19,7 @@ #include "../world/Location.hpp" #include "../world/Park.h" #include "../world/Wall.h" +#include "BannerRemoveAction.hpp" #include "GameAction.h" DEFINE_GAME_ACTION(FootpathRemoveAction, GAME_COMMAND_REMOVE_PATH, GameActionResult) @@ -89,7 +90,7 @@ public: if (footpathElement != nullptr) { footpath_queue_chain_reset(); - remove_banners_at_element(_x, _y, footpathElement); + RemoveBannersAtElement(_x, _y, footpathElement); footpath_remove_edges_at(_x, _y, footpathElement); map_invalidate_tile_full(_x, _y); tile_element_remove(footpathElement); @@ -140,4 +141,25 @@ private: money32 cost = -MONEY(10, 00); return cost; } + + /** + * + * rct2: 0x006BA23E + */ + void RemoveBannersAtElement(int32_t x, int32_t y, TileElement * tileElement) const + { + while (!(tileElement++)->IsLastForTile()) + { + if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH) + return; + else if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER) + continue; + + auto bannerRemoveAction = BannerRemoveAction( + { x, y, tileElement->base_height * 8, tileElement->AsBanner()->GetPosition() }); + bannerRemoveAction.SetFlags(GetFlags()); + GameActions::ExecuteNested(&bannerRemoveAction); + tileElement--; + } + } }; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 2b50cbaaf4..e43fd171c7 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -7,6 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "BannerPlaceAction.hpp" +#include "BannerRemoveAction.hpp" #include "BannerSetColourAction.hpp" #include "BannerSetNameAction.hpp" #include "BannerSetStyleAction.hpp" @@ -79,6 +81,8 @@ namespace GameActions { void Register() { + Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index c00e4026a5..d55d6f7029 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -593,19 +593,6 @@ void window_ride_construction_update_active_elements() context_broadcast_intent(&intent); } -void game_command_callback_place_banner( - [[maybe_unused]] int32_t eax, int32_t ebx, [[maybe_unused]] int32_t ecx, [[maybe_unused]] int32_t edx, - [[maybe_unused]] int32_t esi, int32_t edi, [[maybe_unused]] int32_t ebp) -{ - if (ebx != MONEY32_UNDEFINED) - { - int32_t bannerId = edi; - - audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); - context_open_detail_window(WD_BANNER, bannerId); - } -} - /** * * rct2: 0x0066DB3D diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 6390a25eba..af42fc01d4 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -59,174 +59,6 @@ static uint8_t banner_get_ride_index_at(int32_t x, int32_t y, int32_t z) return resultRideIndex; } -static money32 BannerRemove(int16_t x, int16_t y, uint8_t baseHeight, uint8_t direction, uint8_t flags) -{ - int32_t z = baseHeight * 8; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - return MONEY32_UNDEFINED; - } - - if (!map_can_build_at(x, y, z - 16)) - { - return MONEY32_UNDEFINED; - } - - // Slight modification to the code so that it now checks height as well - // This was causing a bug with banners on two paths stacked. - BannerElement* tileElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction); - if (tileElement == nullptr) - { - return MONEY32_UNDEFINED; - } - - rct_banner* banner = &gBanners[tileElement->GetIndex()]; - rct_scenery_entry* bannerEntry = get_banner_entry(banner->type); - money32 refund = 0; - if (bannerEntry != nullptr) - { - refund = -((bannerEntry->banner.price * 3) / 4); - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (gGameCommandNestLevel == 1 && !(flags & 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); - } - - tile_element_remove_banner_entry((TileElement*)tileElement); - map_invalidate_tile_zoom1(x, y, z, z + 32); - tileElement->Remove(); - } - - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - refund = 0; - } - return refund; -} - -static money32 BannerPlace( - int16_t x, int16_t y, uint8_t pathBaseHeight, uint8_t direction, uint8_t colour, uint8_t type, BannerIndex* bannerIndex, - uint8_t flags) -{ - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = pathBaseHeight * 16; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - if (game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - return MONEY32_UNDEFINED; - } - - if (!map_check_free_elements_and_reorganise(1)) - { - return MONEY32_UNDEFINED; - } - - if (!map_is_location_valid({ x, y })) - { - return MONEY32_UNDEFINED; - } - - TileElement* tileElement = map_get_first_element_at(x / 32, y / 32); - - bool pathFound = false; - do - { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - - if (tileElement->base_height != pathBaseHeight * 2 && tileElement->base_height != (pathBaseHeight - 1) * 2) - continue; - - if (!(tileElement->AsPath()->GetEdges() & (1 << direction))) - continue; - - pathFound = true; - break; - } while (!(tileElement++)->IsLastForTile()); - - if (!pathFound) - { - gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS; - return MONEY32_UNDEFINED; - } - - if (!map_can_build_at(x, y, pathBaseHeight * 16)) - { - return MONEY32_UNDEFINED; - } - - uint8_t baseHeight = (pathBaseHeight + 1) * 2; - BannerElement* bannerElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction); - if (bannerElement != nullptr) - { - gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY; - return MONEY32_UNDEFINED; - } - - *bannerIndex = create_new_banner(flags); - if (*bannerIndex == BANNER_INDEX_NULL) - { - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - if (gGameCommandNestLevel == 1 && !(flags & 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* newTileElement = tile_element_insert(x / 32, y / 32, baseHeight, 0); - assert(newTileElement != nullptr); - gBanners[*bannerIndex].type = type; - gBanners[*bannerIndex].colour = colour; - gBanners[*bannerIndex].x = x / 32; - gBanners[*bannerIndex].y = y / 32; - newTileElement->SetType(TILE_ELEMENT_TYPE_BANNER); - newTileElement->clearance_height = newTileElement->base_height + 2; - newTileElement->AsBanner()->SetPosition(direction); - newTileElement->AsBanner()->ResetAllowedEdges(); - newTileElement->AsBanner()->SetIndex(*bannerIndex); - if (flags & GAME_COMMAND_FLAG_GHOST) - { - newTileElement->SetGhost(true); - } - map_invalidate_tile_full(x, y); - map_animation_create(MAP_ANIMATION_TYPE_BANNER, x, y, newTileElement->base_height); - } - - rct_scenery_entry* bannerEntry = get_banner_entry(type); - if (bannerEntry == nullptr) - { - return MONEY32_UNDEFINED; - } - - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - return 0; - } - return bannerEntry->banner.price; -} - static BannerIndex BannerGetNewIndex() { for (BannerIndex bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) @@ -416,29 +248,6 @@ void fix_duplicated_banners() } } -/** - * - * rct2: 0x006BA058 - */ -void game_command_remove_banner( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - *ebx = BannerRemove(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebx & 0xFF); -} - -/** - * - * rct2: 0x006B9E6D - */ -void game_command_place_banner( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - *ebx = BannerPlace( - *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebp & 0xFF, (*ebx >> 8) & 0xFF, (BannerIndex*)edi, - *ebx & 0xFF); -} - BannerIndex BannerElement::GetIndex() const { return index; diff --git a/src/openrct2/world/Banner.h b/src/openrct2/world/Banner.h index 51cbb26b80..962bfb119f 100644 --- a/src/openrct2/world/Banner.h +++ b/src/openrct2/world/Banner.h @@ -52,5 +52,3 @@ TileElement* banner_get_tile_element(BannerIndex bannerIndex); uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z); void banner_reset_broken_index(); void fix_duplicated_banners(); -void game_command_callback_place_banner( - int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp); diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 95b08537fe..762ed93d09 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -124,25 +124,6 @@ TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z) return nullptr; } -/** - * - * rct2: 0x006BA23E - */ -void remove_banners_at_element(int32_t x, int32_t y, TileElement* tileElement) -{ - while (!(tileElement++)->IsLastForTile()) - { - if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH) - return; - else if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER) - continue; - - game_do_command( - x, 1, y, tileElement->base_height | tileElement->AsBanner()->GetPosition() << 8, GAME_COMMAND_REMOVE_BANNER, 0, 0); - tileElement--; - } -} - money32 footpath_remove(int32_t x, int32_t y, int32_t z, int32_t flags) { auto action = FootpathRemoveAction(x, y, z); diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 2575da28f0..8cd5f1967d 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -182,7 +182,6 @@ money32 footpath_remove(int32_t x, int32_t y, int32_t z, int32_t flags); money32 footpath_provisional_set(int32_t type, int32_t x, int32_t y, int32_t z, int32_t slope); void footpath_provisional_remove(); void footpath_provisional_update(); -void remove_banners_at_element(int32_t x, int32_t y, TileElement* tileElement); void footpath_get_coordinates_from_pos( int32_t screenX, int32_t screenY, int32_t* x, int32_t* y, int32_t* direction, TileElement** tileElement); void footpath_bridge_get_info_from_pos( diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 900c88b292..66c5ee7754 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -23,6 +23,7 @@ #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" #include "../actions/WaterSetHeightAction.hpp" +#include "../actions/BannerRemoveAction.hpp" #include "../audio/audio.h" #include "../config/Config.h" #include "../core/Guard.hpp" @@ -1808,11 +1809,12 @@ static void clear_element_at(int32_t x, int32_t y, TileElement** elementPtr) } break; case TILE_ELEMENT_TYPE_BANNER: - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command( - x, GAME_COMMAND_FLAG_APPLY, y, (element->base_height) | ((element->AsBanner()->GetPosition() & 3) << 8), - GAME_COMMAND_REMOVE_BANNER, 0, 0); + { + auto bannerRemoveAction = BannerRemoveAction( + { x, y, element->base_height * 8, element->AsBanner()->GetPosition() }); + GameActions::Execute(&bannerRemoveAction); break; + } default: tile_element_remove(element); break; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 3ff6251ed6..b8a6bb281d 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -190,10 +190,6 @@ money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -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_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( diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 5d2b0d01b1..a9e97144f7 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -16,6 +16,7 @@ #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" +#include "../actions/BannerRemoveAction.hpp" #include "../common.h" #include "../localisation/Localisation.h" #include "../network/network.h" @@ -235,9 +236,11 @@ void scenery_remove_ghost_tool_placement() if (gSceneryGhostType & SCENERY_GHOST_FLAG_4) { gSceneryGhostType &= ~SCENERY_GHOST_FLAG_4; - constexpr uint32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED - | GAME_COMMAND_FLAG_NO_SPEND; - game_do_command(x, flags, y, z | (gSceneryPlaceRotation << 8), GAME_COMMAND_REMOVE_BANNER, 0, 0); + + auto removeSceneryAction = BannerRemoveAction({ x, y, z * 8, gSceneryPlaceRotation }); + removeSceneryAction.SetFlags( + GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); + GameActions::Execute(&removeSceneryAction); } } From d14637e1ca19e258598993232f3b39aa8346c2b7 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 10:09:18 +0100 Subject: [PATCH 268/506] Fix narrowing and formatting --- src/openrct2-ui/windows/Banner.cpp | 2 +- src/openrct2-ui/windows/TopToolbar.cpp | 6 ++++-- src/openrct2/world/Map.cpp | 2 +- src/openrct2/world/Scenery.cpp | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index 08237a7d8f..a1597cbe85 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -10,9 +10,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index c842b743f3..8bf483e0ba 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1922,7 +1922,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo case SCENERY_TYPE_BANNER: { uint8_t direction = (parameter_2 >> 8) & 0xFF; - CoordsXYZD loc{ gridX, gridY, (parameter_2 & 0xFF) * 16, direction }; + int32_t z = (parameter_2 & 0xFF) * 16; + CoordsXYZD loc{ gridX, gridY, z, direction }; auto primaryColour = gWindowSceneryPrimaryColour; auto bannerType = (parameter_1 & 0xFF00) >> 8; auto bannerIndex = create_new_banner(0); @@ -2629,7 +2630,8 @@ static money32 try_place_ghost_scenery( // Banners // 6e2612 uint8_t direction = (parameter_2 >> 8) & 0xFF; - CoordsXYZD loc{ map_tile.x, map_tile.y, (parameter_2 & 0xFF) * 16, direction }; + int32_t z = (parameter_2 & 0xFF) * 16; + CoordsXYZD loc{ map_tile.x, map_tile.y, z, direction }; auto primaryColour = gWindowSceneryPrimaryColour; auto bannerType = (parameter_1 & 0xFF00) >> 8; auto bannerIndex = create_new_banner(0); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 66c5ee7754..f9ce97242f 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -14,6 +14,7 @@ #include "../Game.h" #include "../Input.h" #include "../OpenRCT2.h" +#include "../actions/BannerRemoveAction.hpp" #include "../actions/FootpathRemoveAction.hpp" #include "../actions/LandLowerAction.hpp" #include "../actions/LandRaiseAction.hpp" @@ -23,7 +24,6 @@ #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" #include "../actions/WaterSetHeightAction.hpp" -#include "../actions/BannerRemoveAction.hpp" #include "../audio/audio.h" #include "../config/Config.h" #include "../core/Guard.hpp" diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index a9e97144f7..5d2bf86b0b 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -12,11 +12,11 @@ #include "../Cheats.h" #include "../Context.h" #include "../Game.h" +#include "../actions/BannerRemoveAction.hpp" #include "../actions/FootpathSceneryRemoveAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" -#include "../actions/BannerRemoveAction.hpp" #include "../common.h" #include "../localisation/Localisation.h" #include "../network/network.h" From 7f42824642a9af2e0bbbd1fb528522d5365548b4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 6 Apr 2019 10:10:19 +0100 Subject: [PATCH 269/506] Update game.h --- src/openrct2/Game.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 612e12f632..2627ab9d37 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -69,8 +69,8 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_TRACK_DESIGN, GAME_COMMAND_START_MARKETING_CAMPAIGN, // GA GAME_COMMAND_PLACE_MAZE_DESIGN, - GAME_COMMAND_PLACE_BANNER, - GAME_COMMAND_REMOVE_BANNER, + GAME_COMMAND_PLACE_BANNER, // GA + GAME_COMMAND_REMOVE_BANNER, // GA GAME_COMMAND_SET_SCENERY_COLOUR, // GA GAME_COMMAND_SET_WALL_COLOUR, // GA GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA From f0df14bb0fc45c94fa4b84e5a3ac083420777316 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 2 May 2019 17:50:04 +0100 Subject: [PATCH 270/506] Use BannerIndex type --- src/openrct2/actions/BannerPlaceAction.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/BannerPlaceAction.hpp b/src/openrct2/actions/BannerPlaceAction.hpp index 4aa2317ee6..25354dc617 100644 --- a/src/openrct2/actions/BannerPlaceAction.hpp +++ b/src/openrct2/actions/BannerPlaceAction.hpp @@ -20,12 +20,12 @@ DEFINE_GAME_ACTION(BannerPlaceAction, GAME_COMMAND_PLACE_BANNER, GameActionResul private: CoordsXYZD _loc; uint8_t _bannerType{ std::numeric_limits::max() }; - uint8_t _bannerIndex{ BANNER_INDEX_NULL }; + BannerIndex _bannerIndex{ BANNER_INDEX_NULL }; uint8_t _primaryColour; public: BannerPlaceAction() = default; - BannerPlaceAction(CoordsXYZD loc, uint8_t bannerType, uint8_t bannerIndex, uint8_t primaryColour) + BannerPlaceAction(CoordsXYZD loc, uint8_t bannerType, BannerIndex bannerIndex, uint8_t primaryColour) : _loc(loc) , _bannerType(bannerType) , _bannerIndex(bannerIndex) From c06476f93fc776c2dca7a2acdaa84f7f97a1fc35 Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 2 May 2019 19:07:02 +0000 Subject: [PATCH 271/506] Update target Windows SDK to 10.0.17763.0 (#9190) --- openrct2.common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openrct2.common.props b/openrct2.common.props index 49376b04f8..7437297cfa 100644 --- a/openrct2.common.props +++ b/openrct2.common.props @@ -9,7 +9,7 @@ $(DefaultPlatformToolset) - 10.0.14393.0 + 10.0.17763.0 MultiByte From 48bf5e10f3b50cdbe0fbb17c9d42362219ada8c9 Mon Sep 17 00:00:00 2001 From: Duncan Date: Thu, 2 May 2019 20:20:20 +0100 Subject: [PATCH 272/506] 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 6e890297ff..de7e56f261 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 "21" +#define NETWORK_STREAM_VERSION "22" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 6a6465498f378fd103d2bf43aadb973ca76038e8 Mon Sep 17 00:00:00 2001 From: hokasha2016 <46494088+hokasha2016@users.noreply.github.com> Date: Thu, 2 May 2019 15:42:05 -0400 Subject: [PATCH 273/506] Fix #7878: Scroll shortcut keys ignore SHIFT/CTRL/ALT modifiers --- src/openrct2-ui/input/KeyboardShortcuts.cpp | 30 +++++++-------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/openrct2-ui/input/KeyboardShortcuts.cpp b/src/openrct2-ui/input/KeyboardShortcuts.cpp index 9046baa351..a77a8932dd 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.cpp +++ b/src/openrct2-ui/input/KeyboardShortcuts.cpp @@ -169,27 +169,17 @@ void KeyboardShortcuts::GetKeyboardMapScroll(const uint8_t* keysState, int32_t* if (!keysState[scancode]) continue; - if (shortcutKey & SHIFT) - { - if (!keysState[SDL_SCANCODE_LSHIFT] && !keysState[SDL_SCANCODE_RSHIFT]) - continue; - } - if (shortcutKey & CTRL) - { - if (!keysState[SDL_SCANCODE_LCTRL] && !keysState[SDL_SCANCODE_RCTRL]) - continue; - } - if (shortcutKey & ALT) - { - if (!keysState[SDL_SCANCODE_LALT] && !keysState[SDL_SCANCODE_RALT]) - continue; - } + // Check if SHIFT is either set in the shortcut key and currently, + // or not set in the shortcut key and not currently pressed (in other words: check if they match). + if ((bool)(shortcutKey & SHIFT) != (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT])) + continue; + if ((bool)(shortcutKey & CTRL) != (keysState[SDL_SCANCODE_LCTRL] || keysState[SDL_SCANCODE_RCTRL])) + continue; + if ((bool)(shortcutKey & ALT) != (keysState[SDL_SCANCODE_LALT] || keysState[SDL_SCANCODE_RALT])) + continue; #ifdef __MACOSX__ - if (shortcutKey & CMD) - { - if (!keysState[SDL_SCANCODE_LGUI] && !keysState[SDL_SCANCODE_RGUI]) - continue; - } + if ((bool)(shortcutKey & CMD) != (keysState[SDL_SCANCODE_LGUI] || keysState[SDL_SCANCODE_RGUI])) + continue; #endif switch (shortcutId) { From 76956a8fc108b6f649f7e45c76d4fda52618bb0e Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 2 May 2019 21:50:04 +0200 Subject: [PATCH 274/506] Add missing issue to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f9f5a0b353..fed59bb16f 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -19,6 +19,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#7700, #8079, #8969] Crash when unloading buggy custom rides. +- Fix: [#7878] Scroll shortcut keys ignore SHIFT/CTRL/ALT modifiers. - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8649] Setting date does not work in multiplayer. From 8c109307cfc1c5acd1556e22ea2b1c39d72d3783 Mon Sep 17 00:00:00 2001 From: Florian Will Date: Sat, 27 Apr 2019 11:51:59 +0200 Subject: [PATCH 275/506] Fix #8507: Incorrect change in vehicle rolling direction In OpenRCT2, when vehicles roll backward on a long, flat track piece, they would eventually change their direction of movement and move forward instead, after their velocity reached -4095. The acceleration due to rolling resistance and drag changes to 0 at that point, which caused the "implicit boost" up to a velocity of ~+32k (close to 2km/h) to trigger. The behavior is different in vanilla RCT2, where vehicles just keep on very slowly rolling backwards. This commit disables the "implicit forward boost" for vehicles rolling backward to mimic vanilla RCT2 behavior. --- distribution/changelog.txt | 1 + src/openrct2/network/Network.cpp | 2 +- src/openrct2/ride/Vehicle.cpp | 15 ++++++--------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index fed59bb16f..1120140d56 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -21,6 +21,7 @@ - Fix: [#7700, #8079, #8969] Crash when unloading buggy custom rides. - Fix: [#7878] Scroll shortcut keys ignore SHIFT/CTRL/ALT modifiers. - Fix: [#8219] Faulty folder recreation in "save" folder. +- Fix: [#8507] Incorrect change in vehicle rolling direction. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8649] Setting date does not work in multiplayer. - Fix: [#8873] Potential crash when placing footpaths. diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 6e890297ff..de7e56f261 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 "21" +#define NETWORK_STREAM_VERSION "22" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 40665151c7..1c52163f3f 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -9766,17 +9766,14 @@ int32_t vehicle_update_track_motion(rct_vehicle* vehicle, int32_t* outStation) { vehicle_update_track_motion_powered_ride_acceleration(vehicle, vehicleEntry, totalMass, &acceleration); } - else + else if (acceleration <= 0 && acceleration >= -500) { - if (acceleration <= 0) + // Probably moving slowly on a flat track piece, low rolling resistance and drag. + + if (vehicle->velocity <= 0x8000 && vehicle->velocity >= 0) { - if (acceleration >= -500) - { - if (vehicle->velocity <= 0x8000) - { - acceleration += 400; - } - } + // Vehicle is creeping forwards very slowly (less than ~2km/h), boost speed a bit. + acceleration += 400; } } From 72ca5ee3a4702e55c95ffcb08ed02a64874d1ac3 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 2 May 2019 22:39:54 +0200 Subject: [PATCH 276/506] Fix formatting --- src/openrct2-ui/input/KeyboardShortcuts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/input/KeyboardShortcuts.cpp b/src/openrct2-ui/input/KeyboardShortcuts.cpp index a77a8932dd..b7f29a6069 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.cpp +++ b/src/openrct2-ui/input/KeyboardShortcuts.cpp @@ -169,7 +169,7 @@ void KeyboardShortcuts::GetKeyboardMapScroll(const uint8_t* keysState, int32_t* if (!keysState[scancode]) continue; - // Check if SHIFT is either set in the shortcut key and currently, + // Check if SHIFT is either set in the shortcut key and currently pressed, // or not set in the shortcut key and not currently pressed (in other words: check if they match). if ((bool)(shortcutKey & SHIFT) != (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT])) continue; From 21104376ea3ad9160c18842bfafbfb2b676d5e0d Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 2 May 2019 12:38:12 +0200 Subject: [PATCH 277/506] Add changelog entry; add Xkeeper0 to contributors. [ci skip] --- contributors.md | 1 + distribution/changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/contributors.md b/contributors.md index f900f66381..3b7771e4bc 100644 --- a/contributors.md +++ b/contributors.md @@ -77,6 +77,7 @@ The following people are not part of the development team, but have been contrib * Albert Morgese (Fusxfaranto) - Shop auto-rotation, unicode uppercasing. * Olivier Wervers (oli414) - Remove unused objects command, various bugfixes * Christian Schubert (Osmodium) - Ensuring custom user content folders, incl. open folder. +* (Xkeeper0) - Improved banner tooltips; multiplayer status in toolbar. ## Bug fixes * (halfbro) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 338d9f98c8..6a4c476ba6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -4,6 +4,7 @@ - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. - Feature: [#8481] Multi-threaded rendering. - Feature: [#8659] Banner and sign texts are now shown in tooltips. +- Feature: [#8687] New multiplayer toolbar icon showing network status with reconnect option. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Feature: [#9154] Change map toolbar icon with current viewport rotation. From 63a38412aafb87dc606fe7da5203689dac25a3ad Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Mon, 18 Feb 2019 23:42:13 +0100 Subject: [PATCH 278/506] Add `optional` header --- src/openrct2/core/Optional.hpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/openrct2/core/Optional.hpp diff --git a/src/openrct2/core/Optional.hpp b/src/openrct2/core/Optional.hpp new file mode 100644 index 0000000000..66c67028fb --- /dev/null +++ b/src/openrct2/core/Optional.hpp @@ -0,0 +1,29 @@ +/***************************************************************************** + * 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 + +#ifdef __has_include +# if __has_include() +# include +# elif __has_include() +# include +# else +# error Missing +# endif +#else +# error __has_include is not defined +#endif + +// `optional` and friends will be available in NS `::opt` +#if __has_include() +namespace opt = std; +#elif __has_include() +namespace opt = std::experimental; +#endif From ddcebc9b4c17df7dca1acf86c11842ae4d7d70ef Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Fri, 3 May 2019 04:00:26 +0000 Subject: [PATCH 279/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 12 ++++--- data/language/da-DK.txt | 11 ++++--- data/language/hu-HU.txt | 72 ++++++++++++++++++++++++++++++++++------- data/language/ko-KR.txt | 10 +++--- data/language/nl-NL.txt | 12 ++++--- data/language/sv-SE.txt | 11 ++++--- 6 files changed, 94 insertions(+), 34 deletions(-) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 11396244c4..81cac805d6 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -552,8 +552,8 @@ STR_1167 :Tady nelze zvýšit hladinu vody... STR_1168 :Nastavení STR_1169 :(None) STR_1170 :{STRING} -STR_1171 :{RED}Zavřeno - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Zavřeno +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Nástroj pro cesty a fronty STR_1174 :Banner v cestě STR_1175 :Toto nelze postavit na strmé cestě @@ -1111,8 +1111,8 @@ STR_1726 :Pozemek není na prodej! STR_1727 :Stavební práva nejsou na prodej! STR_1728 :Tyto stavební práva nelze zakoupit... STR_1729 :Pozemek není ve vlastnictví parku! -STR_1730 :{RED}Zavřeno - - -STR_1731 :{WHITE}{STRINGID} - - +STR_1730 :{RED}Zavřeno +STR_1731 :{WHITE}{STRINGID} STR_1732 :Stavět STR_1733 :Mód STR_1734 :{WINDOW_COLOUR_2}Počet kol: @@ -2242,7 +2242,7 @@ STR_2977 :Přejmenovat zaměstnance STR_2978 :Zadejte nové jméno tohoto zaměstnance: STR_2979 :Nelze přejmenovat zaměstnance... STR_2980 :Příliš mnoho bannerů ve hře -STR_2981 :{RED}Zákaz vstupu - - +STR_2981 :{RED}Zákaz vstupu STR_2982 :Text banneru STR_2983 :Zadejte nový text banneru: STR_2984 :Nelze změnit text banneru... @@ -3774,6 +3774,8 @@ STR_6303 :Stahování objektu ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Otevřít výběr kulis STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimentální podpora více vláken pro vykreslování obrazu, může způsobit nestabilitu. +STR_6307 :Barevné schéma: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} ############################################################################### ## RCT2 Scenarios diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index dc7869ce91..34b9968ff5 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -552,8 +552,8 @@ STR_1167 :Kan ikke hæve vand her... STR_1168 :Indstillinger STR_1169 :(ingen) STR_1170 :{STRING} -STR_1171 :{RED}Lukket - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Lukket +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Byg stier og kø linjer STR_1174 :Banner skilt i vejen STR_1175 :Kan ikke bygge dette på en skrå sti @@ -1110,7 +1110,7 @@ STR_1726 :Land er ikke til salg! STR_1727 :Byggetilladelse er ikke til salg! STR_1728 :Kan ikke købe byggetilladelse her... STR_1729 :Land ikke ejet af parken! -STR_1730 :{RED}Lukket - - +STR_1730 :{RED}Lukket STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Byg STR_1733 :Tilstand @@ -2242,7 +2242,7 @@ STR_2977 :Navn på ansat STR_2978 :Angiv et navn for denne ansat: STR_2979 :Kan ikke navngive ansat... STR_2980 :For mange bannere i spillet -STR_2981 :{RED}Ingen indhold - - +STR_2981 :{RED}Ingen indhold STR_2982 :Banner tekst STR_2983 :Angiv ny tekst på dette banner: STR_2984 :Kan ikke sætte ny tekst på banner... @@ -3777,7 +3777,8 @@ STR_6303 :Henter objekt ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Åben scenarie vælger STR_6305 :Multi-tråde STR_6306 :{SMALLFONT}{BLACK}Eksperimentel indstilling, brug flere processor kerner til at gengive spillet, kan påvirke stabiliteten. - +STR_6307 :Farve tema: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} ############# # Scenarios # diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index 20d3fabde9..a008b09b2b 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -144,6 +144,8 @@ STR_0561 :Cirkuszi állatprodukció egy nagy sátorban STR_0562 :Motoros autók utaznak egy többszintes pálya mentén, miközben kísérteties díszletek és speciális effektusok mellett haladnak el STR_0563 :Kényelmes, egyszerű biztonsági rudas vonatokban ülve élvezhetik az utasok a hatalmas, sima eséseket és csavaros pályákat, valamint a bőséges „légi időt” az emelkedők után STR_0564 :Ez a fa pályán futó hullámvasút gyors, durva, hangos és „kontrollvesztett” utazási élményt nyújt, bőséges „légi idővel” +STR_0565 :Egy egyszerű, kizárólag enyhe lejtőkre és fordulókra képes fa hullámvasút, amelyen a kocsikat csak az oldalirányú súrlódásos kerekek és a gravitáció tartja a pályán +STR_0566 :Különálló hullámvasút-kocsik száguldanak egy szoros, cikcakkos alaprajzú, éles kanyarokat és rövid meredek eséseket tartalmazó pályán STR_0578 :A kocsik egy abroncsokkal körbefogott, meredek esésekkel és palástorsókkal teli pálya mentén haladnak STR_0579 :Egy enyhe minigolf-játék STR_0582 :Önvezető légpárnás járművek @@ -415,7 +417,7 @@ STR_1047 :A játék mentése meghiúsult! STR_1048 :A pálya mentése meghiúsult! STR_1049 :A táj mentése meghiúsult! STR_1050 :Sikertelen betöltés...{NEWLINE}A fájl érvénytelen adatot tartalmaz! -STR_1051 :Láthatatlan támpillérek +STR_1051 :Láthatatlan állványzatok STR_1052 :Láthatatlan emberek STR_1053 :{SMALLFONT}{BLACK}Játékok/épületek a parkban STR_1054 :{SMALLFONT}{BLACK}Játék/épület átnevezése @@ -536,12 +538,13 @@ STR_1165 :{STRINGID} - {STRINGID} {COMMA16} STR_1168 :Beállítások STR_1169 :(semmi) STR_1170 :{STRING} -STR_1171 :{RED}Zárva - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Zárva +STR_1172 :{YELLOW}{STRINGID} STR_1174 :Egy hirdetőtábla útban van STR_1175 :Nem építhető lejtős úton STR_1176 :Nem építhető ide út... STR_1177 :Nem távolítható el az út... +STR_1178 :A talaj lejtése nem megfelelő STR_1179 :Az út akadályozza STR_1180 :Nem építhető víz alá! STR_1181 :Utak @@ -570,11 +573,16 @@ STR_1203 :{COMMA16} ember áll a sorban STR_1204 :{COMMA16} perc a sorbanállási idő STR_1205 :{COMMA16} perc a sorbanállási idő STR_1206 :{WINDOW_COLOUR_2}Várjon erre: +STR_1207 :{WINDOW_COLOUR_2}Távozzon, ha másik vonat érkezik az állomásra +STR_1208 :{WINDOW_COLOUR_2}Távozzon, ha másik csónak érkezik az állomásra STR_1209 :{SMALLFONT}{BLACK}Válaszd ki, hogy várakozzon-e utasokra indulás előtt +STR_1210 :{SMALLFONT}{BLACK}Válaszd ki, hogy távozzon-e, ha egy másik jármű érkezik ugyanarra az állomásra STR_1211 :{WINDOW_COLOUR_2}Minimum várakozási idő STR_1212 :{WINDOW_COLOUR_2}Maximum várakozási idő: STR_1213 :{SMALLFONT}{BLACK}Az indulás előtti minimum várakozási idő kiválasztása STR_1214 :{SMALLFONT}{BLACK}Az indulás előtti maximum várakozási idő kiválasztása +STR_1215 :{WINDOW_COLOUR_2}Szinkronizálás a szomszédos állomásokkal +STR_1216 :{SMALLFONT}{BLACK}Válaszd ki, hogy szinkronizálva legyen-e a távozás az összes szomszédos állomással (a ’versenyzéshez’) STR_1217 :{COMMA16} másodperc STR_1218 :{BLACK}+ STR_1219 :{BLACK}- @@ -723,6 +731,10 @@ STR_1359 :{WINDOW_COLOUR_2}Sorbanállási idő: {BLACK}{COMMA16} perc STR_1360 :{WINDOW_COLOUR_2}Sorbanállási idő: {BLACK}{COMMA16} perc STR_1361 :Nem változtatható meg a sebesség... STR_1362 :Nem változtatható meg a kilövési sebesség... +STR_1363 :Túl magas az állványzat számára! +STR_1364 :A fenti pálya állványzata nem hosszabítható meg jobban! +STR_1365 :Kis csavar (balra) +STR_1366 :Kis csavar (jobbra) STR_1367 :Félhurok STR_1368 :Fél dugóhúzó (balra) STR_1369 :Fél dugóhúzó (jobbra) @@ -731,8 +743,14 @@ STR_1371 :Orsó (jobbra) STR_1372 :Kilövős felvonószakasz STR_1373 :Nagy félhurok (balra) STR_1374 :Nagy félhurok (jobbra) +STR_1375 :Felső átvitel +STR_1376 :Alsó átvitel STR_1377 :Palástorsó (balra) STR_1378 :Palástorsó (jobbra) +STR_1379 :Fordító (balra) +STR_1380 :Fordító (jobbra) +STR_1381 :Ívelt felvonószakasz (balra) +STR_1382 :Ívelt felvonószakasz (jobbra) STR_1383 :Negyed hurok STR_1384 :{YELLOW}{STRINGID} STR_1385 :{SMALLFONT}{BLACK}Egyéb pályaelemek @@ -752,7 +770,11 @@ STR_1398 :{SMALLFONT}{BLACK}Mérések és tesztadatok STR_1399 :{SMALLFONT}{BLACK}Grafikonok STR_1400 :Bejárat STR_1401 :Kijárat +STR_1402 :{SMALLFONT}{BLACK}Bejárat építése vagy mozgatása a játékhoz/épülethez +STR_1403 :{SMALLFONT}{BLACK}Kijárat építése vagy mozgatása a játékhoz/épülethez STR_1404 :{SMALLFONT}{BLACK}Forgatás 90°-kal +STR_1405 :{SMALLFONT}{BLACK}Kép tükrözése +STR_1406 :{SMALLFONT}{BLACK}Díszletek be/ki (ha elérhető ehhez a tervhez) STR_1407 :{WINDOW_COLOUR_2}Építés STR_1408 :{WINDOW_COLOUR_2}Ár: {BLACK}{CURRENCY} STR_1409 :Be- és kilépő terasz @@ -769,6 +791,8 @@ STR_1419 :{SMALLFONT}{BLACK}{VELOCITY} STR_1420 :{SMALLFONT}{BLACK}{LENGTH} STR_1421 :{SMALLFONT}{BLACK}{COMMA16}g STR_1422 :{SMALLFONT}{BLACK}Adatnaplózás: {POP16}{STRINGID} +STR_1423 :{SMALLFONT}{BLACK}Várósor +STR_1424 :{SMALLFONT}{BLACK}Út STR_1425 :Út STR_1426 :Várósor STR_1427 :{WINDOW_COLOUR_2}Óránkénti vendégek: {BLACK}{COMMA32} @@ -997,6 +1021,8 @@ STR_1649 :{SMALLFONT}„Mindjárt elfogy a pénzem!” STR_1650 :{SMALLFONT}„Hű! Egy új játék épül!” STR_1653 :{SMALLFONT}„...és itt vagyunk ezen: {STRINGID}!” STR_1654 :{WINDOW_COLOUR_2}Legutóbbi gondolatok: +STR_1655 :{SMALLFONT}{BLACK}Út építése a földön +STR_1656 :{SMALLFONT}{BLACK}Út építése hídon vagy alagútban STR_1657 :{WINDOW_COLOUR_2}Előnyben részesített játék- STR_1658 :{WINDOW_COLOUR_2}intenzitás: {BLACK}kevesebb mint {COMMA16} STR_1659 :{WINDOW_COLOUR_2}intenzitás: {BLACK}{COMMA16} és {COMMA16} között @@ -1013,6 +1039,7 @@ STR_1669 :{WINDOW_COLOUR_2}Elégedettség: {BLACK}{COMMA16}% STR_1670 :{WINDOW_COLOUR_2}Összes vendég: {BLACK}{COMMA32} STR_1671 :{WINDOW_COLOUR_2}Teljes nyereség: {BLACK}{CURRENCY2DP} STR_1672 :Fékek +STR_1673 :Forgásvezérlő kapcsolószakasz STR_1674 :Fékezési sebesség STR_1675 :{POP16}{VELOCITY} STR_1676 :{SMALLFONT}{BLACK}Sebességlimit beállítása a fékek számára @@ -1036,6 +1063,8 @@ STR_1693 :{SMALLFONT}{BLACK}Vendégek STR_1694 :{SMALLFONT}{BLACK}Személyzet STR_1695 :{SMALLFONT}{BLACK}Bevételek és kiadások STR_1696 :{SMALLFONT}{BLACK}Vendég információk +STR_1697 :Nem rakhatod várósorra +STR_1698 :Csak várósorra rakhatod STR_1699 :Túl sok ember van a játékban STR_1700 :Új mindenes felvétele STR_1701 :Új gépész felvétele @@ -1067,18 +1096,25 @@ STR_1726 :A terület nem eladó! STR_1727 :Az építési jogok nem eladók! STR_1728 :Nem vásárolhatók meg az építési jogok... STR_1729 :A terület nem a park tulajdona! -STR_1730 :{RED}Zárva - - -STR_1731 :{WHITE}{STRINGID} - - +STR_1730 :{RED}Zárva +STR_1731 :{WHITE}{STRINGID} STR_1732 :Építés STR_1733 :Mód +STR_1734 :{WINDOW_COLOUR_2}Körök száma: +STR_1735 :{SMALLFONT}{BLACK}A pályán megtett körök száma STR_1736 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1738 :Nem változtatható meg a körök száma... STR_1739 :Vendég {INT32} nyerte a versenyt STR_1740 :{STRINGID} nyerte a versenyt STR_1741 :Még nincs megépítve ! STR_1742 :{WINDOW_COLOUR_2}Max. ember a játékon: STR_1743 :{SMALLFONT}{BLACK}Maximum ennyi ember lehet egyszerre a játékon STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1746 :Nem változtathatod meg... +STR_1747 :{WINDOW_COLOUR_2}Időkorlát: +STR_1748 :{SMALLFONT}{BLACK}A játék időkorlátja STR_1749 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{DURATION} +STR_1751 :Nem változtatható meg a játék időkorlátja... STR_1752 :{SMALLFONT}{BLACK}A park egyedi vendégeinek listázása STR_1753 :{SMALLFONT}{BLACK}A park vendégeinek összegző listázása STR_1754 :{BLACK}{COMMA16} vendég @@ -1089,7 +1125,11 @@ STR_1758 :{SMALLFONT}{BLACK}Építő mód STR_1759 :{SMALLFONT}{BLACK}Mozgató mód STR_1760 :{SMALLFONT}{BLACK}Kitöltő mód STR_1761 :{SMALLFONT}{BLACK}Útvesztő építése ebbe az irányba +STR_1762 :Vízesések +STR_1763 :Vadvizek +STR_1764 :Farönk bukkanók STR_1765 :Élményfotó-szakasz +STR_1766 :Fordító korong STR_1767 :Forgó alagút STR_1768 :Nem változtatható meg a lengések száma... STR_1769 :{WINDOW_COLOUR_2}Lengések száma: @@ -1220,7 +1260,7 @@ STR_1906 :{WINDOW_COLOUR_2}Étel/ital készletek STR_1907 :{WINDOW_COLOUR_2}Alkalmazottak bére STR_1908 :{WINDOW_COLOUR_2}Marketing STR_1909 :{WINDOW_COLOUR_2}Kutatás -STR_1910 :{WINDOW_COLOUR_2}Kölcsön kamat: +STR_1910 :{WINDOW_COLOUR_2}Kölcsön kamat STR_1911 :{BLACK} {COMMA16}%-os éves kamattal STR_1912 :{MONTH} STR_1913 :{BLACK}+{CURRENCY2DP} @@ -1761,7 +1801,7 @@ STR_2502 :Talaj elrejtése be/ki STR_2503 :Függőleges felületek elrejtése be/ki STR_2504 :Átlátszó játékok be/ki STR_2505 :Átlátszó díszletek be/ki -STR_2506 :Láthatatlan támpillérek be/ki +STR_2506 :Láthatatlan állványzatok be/ki STR_2507 :Láthatatlan emberek be/ki STR_2508 :Magasságjelek a talajon be/ki STR_2509 :Magasságjelek a játékok pályáin be/ki @@ -2051,7 +2091,7 @@ STR_2801 :{WINDOW_COLOUR_2}Bevétel a belépőkből: {BLACK}{CURRENCY2DP} STR_2802 :Térkép STR_2803 :{SMALLFONT}{BLACK}A kiválasztott vendégek kiemelése a térképen STR_2804 :{SMALLFONT}{BLACK}A kiválasztott alkalmazottak kiemelése a térképen -STR_2805 :{SMALLFONT}{BLACK}A park térképének megjelenítése +STR_2805 :{SMALLFONT}{BLACK}A park térképe STR_2806 :{RED}A vendégek panaszkodnak, mert az utak a parkodban gyomorforgatóak{NEWLINE}Nézd meg hol vannak a mindeneseid és próbáld meg jobban szervezni őket STR_2807 :{RED}A vendégek panaszkodnak a parkodban lévő szemét mennyisége miatt{NEWLINE}Nézd meg hol vannak a mindeneseid és próbáld meg jobban szervezni őket STR_2808 :{RED}A vendégek panaszkodnak a parkodban lévő vandalizmus miatt{NEWLINE}Nézd meg hol vannak a biztonsági őreid és próbáld meg jobban szervezni őket @@ -2159,7 +2199,7 @@ STR_2977 :Alkalmazott neve STR_2978 :Írj be egy új nevet az alkalmazottad számára: STR_2979 :Nem nevezhető át az alkalmazott... STR_2980 :Túl sok hirdetőtábla van a játékban -STR_2981 :{RED}Tilos a belépés - - +STR_2981 :{RED}Tilos a belépés STR_2982 :Hirdetőtábla szövege STR_2983 :Írd be a hirdetőtábla új szövegét: STR_2984 :Nem állítható be új szöveg a hirdetőtáblán... @@ -2447,6 +2487,7 @@ STR_5123 :Játékok felújítása STR_5125 :Minden lerombolható STR_5126 :Véletlenszerű főcímzene STR_5130 :Térkép mérete +STR_5132 :Játékok megjavítása STR_5133 :{SMALLFONT}{BLACK}Vásárlás kisebb területen STR_5134 :{SMALLFONT}{BLACK}Vásárlás nagyobb területen STR_5135 :{SMALLFONT}{BLACK}Földterületek és építési jogok vásárlása @@ -2625,13 +2666,13 @@ STR_5358 :{BLACK}WC: STR_5359 :Vendégek eltávolítása STR_5360 :{SMALLFONT}{BLACK}Eltávolít minden vendéget a térképről STR_5361 :Minden vendég kapjon: -STR_5362 :{BLACK}A vendégek preferált játékintenzitása legyen: +STR_5362 :{BLACK}A vendégek preferált játékintenzitása: STR_5363 :Több mint 1 STR_5364 :Kevesebb mint 15 STR_5365 :{BLACK}Személyzet gyors.: STR_5366 :Normál STR_5367 :Gyors -STR_5368 :Visszaállítás ütközött állapotból +STR_5368 :Ütközés visszaáll. STR_5369 :Park paraméterei... STR_5370 :{SMALLFONT}{BLACK}Kattints erre a gombra, hogy módosítsd{NEWLINE}a park olyan paramétereit, mint{NEWLINE}a vendégek generálása és a pénz. STR_5371 :Objektum választás @@ -2718,6 +2759,7 @@ STR_5453 :Másik játék választása STR_5454 :Korlátlan FPS STR_5455 :Homokozó mód be STR_5456 :Távolság-ellenőrzés ki +STR_5457 :Állványzatlimitek ki STR_5458 :Forgatás órajárás szerint STR_5459 :Forgatás órajárással ellentétesen STR_5460 :Forgatás órajárással ellentétesen @@ -2757,6 +2799,7 @@ STR_5498 :Szerver lista STR_5499 :Játékos neve: STR_5500 :Szerver hozzáadása STR_5501 :Szerver indítása +STR_5506 :A vedégeket nem érdeklik az intenzitások STR_5508 :Hibás ellenőrző összegű fájlok engedélyezése STR_5509 :{SMALLFONT}{BLACK}Engedélyezi a hibás ellenőrző összeggel{NEWLINE}rendelkező pályák és mentések{NEWLINE}betöltését, mint például a próbaverzió pályái vagy a sérült mentések. STR_5511 :(ISMERETLEN) @@ -2926,8 +2969,10 @@ STR_5786 :Érvénytelen csoportnév STR_5787 :{COMMA32} játékos van online STR_5788 :Alapértelmezett ellenőrzési idő: STR_5789 :Villámhatás kikapcsolása +STR_5792 :{SMALLFONT}{BLACK}Minden meghibásodott játékot megjavít STR_5801 :Szemetelés kikapcsolása STR_5790 :{SMALLFONT}{BLACK}Az RCT1-stílusú árazás ki- és bekapcsolása{NEWLINE}(például belépési díj egyszerre a parkba és a játékokra) +STR_5795 :{SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is STR_5802 :{SMALLFONT}{BLACK}A vendégek nem szemetelnek és hánynak STR_5803 :{SMALLFONT}{BLACK}A kiválasztott térképelem forgatása STR_5804 :Hang némítása @@ -3073,7 +3118,7 @@ STR_6060 :Vendégek vásárlásainak animálása STR_6061 :{SMALLFONT}{BLACK}Animált pénzhatás megjelenítése,{NEWLINE}mikor a vendégek vásárolnak valamit. STR_6062 :{OUTLINE}{GREEN}+ {CURRENCY2DP} STR_6063 :{OUTLINE}{RED}- {CURRENCY2DP} -STR_6064 :Minden föld birtoklása +STR_6064 :Minden föld a tiéd STR_6065 :Felhasználói tevékenységek naplózása STR_6066 :{SMALLFONT}{BLACK}Minden felhasználói tevékenységet naplóz a felhasználói mappádban lévő fájlokba STR_6067 :Szerver elindítva. @@ -3113,6 +3158,7 @@ STR_6140 :Változási napló... STR_6141 :RCT1 alsó eszköztár STR_6142 :{WINDOW_COLOUR_2}Pálya neve: {BLACK}{STRING} STR_6143 :{WINDOW_COLOUR_2}Játék típusa: {BLACK}{STRINGID} +STR_6145 :{SMALLFONT}{BLACK}Sebességlimit beállítása a gyorsítók számára STR_6146 :Minden rajzolható pályaelem engedélyezése STR_6148 :Csatlakozás a főszerverhez... STR_6149 :Nem sikerült csatlakozni a főszerverhez @@ -3269,6 +3315,8 @@ STR_6303 :Objektum letöltése ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Díszletválasztó megnyitása STR_6305 :Többszálúság STR_6306 :{SMALLFONT}{BLACK}Kísérleti beállítás, mellyel bekapcsolható a több szálon történő megjelenítés, instabilitást okozhat. +STR_6307 :Színséma: {BLACK}{STRINGID} +STR_6308 :„{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 251396fe3f..247308ffd0 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -552,8 +552,8 @@ STR_1167 :이곳의 물을 올릴 수 없습니다... STR_1168 :설정 STR_1169 :(없음) STR_1170 :{STRING} -STR_1171 :{RED}닫힘 - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}닫힘 +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}보도와 대기 줄을 만듭니다 STR_1174 :전광판 사인이 있습니다 STR_1175 :경사진 보도 위에 건설할 수 없습니다 @@ -1110,7 +1110,7 @@ STR_1726 :판매 중인 땅이 아닙니다! STR_1727 :판매 중인 건설권이 아닙니다! STR_1728 :이곳의 건설권을 살 수 없습니다... STR_1729 :공원 소유의 땅이 아닙니다! -STR_1730 :{RED}닫힘 - - +STR_1730 :{RED}닫힘 STR_1731 :{WHITE}{STRINGID} - - STR_1732 :건설 STR_1733 :모드 @@ -2241,7 +2241,7 @@ STR_2977 :직원 이름 STR_2978 :새 직원 이름을 입력하세요: STR_2979 :직원 이름을 바꿀 수 없습니다... STR_2980 :게임에 전광판이 너무 많습니다 -STR_2981 :{RED}출입 금지 - - +STR_2981 :{RED}출입 금지 STR_2982 :전광판 내용 STR_2983 :이 전광판의 문구를 입력하세요: STR_2984 :전광판의 내용을 바꿀 수 없습니다... @@ -3762,6 +3762,8 @@ STR_6303 :오브젝트 다운로드 중 ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :오브젝트 스포이드 STR_6305 :멀티스레딩 STR_6306 :{SMALLFONT}{BLACK}렌더링을 하기 위해 여러 개의 스레드를 사용합니다. 실험적인 기능이므로 불안정할 수 있습니다. +STR_6307 :색상 조합: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} ############# diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index 08736eaa11..0986395209 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -549,8 +549,8 @@ STR_1167 :Kan het waterniveau hier niet verhogen… STR_1168 :Opties STR_1169 :(Geen) STR_1170 :{STRING} -STR_1171 :{RED}Gesloten - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Gesloten +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Voetpaden en wachtrijen aanleggen STR_1174 :Lichtkrant in de weg STR_1175 :Kan dit niet op hellend voetpad neerzetten @@ -1107,7 +1107,7 @@ STR_1726 :Dit land is niet te koop! STR_1727 :Voor dit land zijn geen bouwrechten te koop! STR_1728 :Kan hier geen bouwrechten kopen… STR_1729 :Land is geen eigendom van het park! -STR_1730 :{RED}Gesloten - - +STR_1730 :{RED}Gesloten STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Bouwen STR_1733 :Modus @@ -2235,7 +2235,7 @@ STR_2977 :Naam werknemer STR_2978 :Voer een nieuwe naam in voor deze werknemer: STR_2979 :Kan de naam van deze werknemer niet veranderen… STR_2980 :Teveel lichtkranten in dit park -STR_2981 :{RED}Geen toegang - - +STR_2981 :{RED}Geen toegang STR_2982 :Lichtkranttekst STR_2983 :Voer een nieuwe tekst in voer deze lichtkrant: STR_2984 :Kan de tekst op deze lichtkrant niet veranderen… @@ -3767,6 +3767,10 @@ STR_6301 :{SMALLFONT}{BLACK}Kopieert de naam van het geselecteerde object naa STR_6302 :{SMALLFONT}{BLACK}Kopieert de lijst van ontbrekende objecten naar het klembord. STR_6303 :Bezig met downloaden van object ({COMMA16} van {COMMA16}): [{STRING}] STR_6304 :Decorselector openen +STR_6305 :Multithreading +STR_6306 :{SMALLFONT}{BLACK}Experimentele optie om met meerdere threads te renderen. Dit kan de snelheid verhogen, maar ook instabiliteit veroorzaken. +STR_6307 :Kleurenschema: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} ############# # Scenarios # diff --git a/data/language/sv-SE.txt b/data/language/sv-SE.txt index 3257ed5c64..8e365fddba 100644 --- a/data/language/sv-SE.txt +++ b/data/language/sv-SE.txt @@ -552,8 +552,8 @@ STR_1167 :Kan inte höja vattennivån... STR_1168 :Inställningar STR_1169 :(Inga) STR_1170 :{STRING} -STR_1171 :{RED}Stängd - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Stängd +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Bygg gångvägar och köer STR_1174 :En skylt är i vägen STR_1175 :Kan inte bygga på en sluttande gångväg @@ -1109,7 +1109,7 @@ STR_1726 :Marken är inte till salu! STR_1727 :Bygglov är inte till salu! STR_1728 :Kan inte få bygglov här... STR_1729 :Marken ägs inte av parken! -STR_1730 :{RED}Stängd - - +STR_1730 :{RED}Stängd STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Bygg STR_1733 :Läge @@ -2238,7 +2238,7 @@ STR_2977 :Personalnamn STR_2978 :Skriv in nytt namn på personal: STR_2979 :Kan inte namnge personal... STR_2980 :För många banderoller i spelet -STR_2981 :{RED}Tillträde förbjudet - - +STR_2981 :{RED}Tillträde förbjudet STR_2982 :Banderolltext STR_2983 :Skriv in ny text för denna banderoll: STR_2984 :Kan inte sätta ny text på banderollen... @@ -3736,6 +3736,9 @@ STR_6265 :{SMALLFONT}{BLACK}Om aktiverad kommer spelet använda filhanteraren STR_6266 :Öppna mappen för anpassat innehåll STR_6267 :Öppna rutinspekteraren +STR_6307 :Färgschema: {BLACK}{STRINGID} +STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} + ############# From c7afad7d49f9ba15887a0ea4019125a25d46c1dd Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sat, 4 May 2019 04:00:23 +0000 Subject: [PATCH 280/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 1 + data/language/sv-SE.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 247308ffd0..af1ec3a1fa 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3764,6 +3764,7 @@ STR_6305 :멀티스레딩 STR_6306 :{SMALLFONT}{BLACK}렌더링을 하기 위해 여러 개의 스레드를 사용합니다. 실험적인 기능이므로 불안정할 수 있습니다. STR_6307 :색상 조합: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :재접속 ############# diff --git a/data/language/sv-SE.txt b/data/language/sv-SE.txt index 8e365fddba..e321ff9868 100644 --- a/data/language/sv-SE.txt +++ b/data/language/sv-SE.txt @@ -3738,6 +3738,7 @@ STR_6267 :Öppna rutinspekteraren STR_6307 :Färgschema: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Återanslut From 5e9e7bcbe524e990ab10741644af7f3640c72dbf Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Sat, 4 May 2019 12:31:10 +0200 Subject: [PATCH 281/506] Fix: artifacts when changing ride type as client or using the in-game console (#9202) --- src/openrct2-ui/windows/Ride.cpp | 1 - src/openrct2/actions/RideSetSetting.hpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 9cd7ccd341..ef509a7884 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2435,7 +2435,6 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex { set_operating_setting(w->number, RideSetSetting::RideType, rideType); } - window_invalidate_all(); } } } diff --git a/src/openrct2/actions/RideSetSetting.hpp b/src/openrct2/actions/RideSetSetting.hpp index 6efead8af8..ade1fcb5a4 100644 --- a/src/openrct2/actions/RideSetSetting.hpp +++ b/src/openrct2/actions/RideSetSetting.hpp @@ -243,6 +243,7 @@ public: break; case RideSetSetting::RideType: ride->type = _value; + gfx_invalidate_screen(); break; } From bf50d98e4225404262144b54991fe3bbf2da649e Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 11:33:14 +0000 Subject: [PATCH 282/506] Update changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 70f1619b78..acf10d0277 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -33,6 +33,7 @@ - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. - Fix: [#9152] Spectators can modify ride colours. +- Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. - Improved: Allow the use of numpad enter key for console and chat. From e84631c27358025af4fc116e624f9b4d83d62d23 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 13:22:01 +0000 Subject: [PATCH 283/506] Fix #9204: Making screenshots from command-line is broken (#9206) --- src/openrct2/interface/Screenshot.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 0075b9340b..2c413fa52a 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -594,6 +594,7 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption dpi.pitch = 0; dpi.zoom_level = 0; dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); + dpi.DrawingEngine = context->GetDrawingEngine(); if (options->hide_guests) { From cd8c67ddac5b4969311692e420ae8af39ffdee8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 4 May 2019 15:28:38 +0200 Subject: [PATCH 284/506] Implement SetCheatAction. (#8990) * Implement SetCheatAction. * Bump up network version --- src/openrct2-ui/windows/Cheats.cpp | 252 ++-- src/openrct2-ui/windows/TopToolbar.cpp | 10 +- src/openrct2/Cheats.cpp | 1019 ++--------------- src/openrct2/Cheats.h | 110 +- src/openrct2/Game.cpp | 15 +- src/openrct2/ReplayManager.cpp | 11 + .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/SetCheatAction.hpp | 792 +++++++++++++ src/openrct2/core/DataSerialiserTraits.h | 21 + src/openrct2/interface/InteractiveConsole.cpp | 101 +- src/openrct2/interface/Screenshot.cpp | 11 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkTypes.h | 1 + src/openrct2/peep/Peep.h | 4 + 14 files changed, 1158 insertions(+), 1193 deletions(-) create mode 100644 src/openrct2/actions/SetCheatAction.hpp diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 4755f98376..e21ce7a0ba 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,10 @@ static utf8 _moneySpinnerText[MONEY_STRING_MAXLENGTH]; static money32 _moneySpinnerValue = CHEATS_MONEY_DEFAULT; static int32_t _selectedStaffSpeed = 1; +static int32_t _parkRatingSpinnerValue; +static int32_t _yearSpinnerValue = 1; +static int32_t _monthSpinnerValue = 1; +static int32_t _daySpinnerValue = 1; // clang-format off enum @@ -613,7 +618,7 @@ rct_window* window_cheats_open() window->hold_down_widgets = window_cheats_page_hold_down_widgets[0]; window_init_scroll_widgets(window); window_cheats_set_page(window, WINDOW_CHEATS_PAGE_MONEY); - park_rating_spinner_value = get_forced_park_rating() >= 0 ? get_forced_park_rating() : 999; + _parkRatingSpinnerValue = get_forced_park_rating() >= 0 ? get_forced_park_rating() : 999; return window; } @@ -633,45 +638,45 @@ static void window_cheats_money_mousedown(rct_window* w, rct_widgetindex widgetI widget_invalidate_by_class(WC_CHEATS, WIDX_MONEY_SPINNER); break; case WIDX_ADD_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_ADDMONEY, _moneySpinnerValue, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::AddMoney, _moneySpinnerValue); break; case WIDX_YEAR_UP: - year_spinner_value++; - year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); + _yearSpinnerValue++; + _yearSpinnerValue = std::clamp(_yearSpinnerValue, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_YEAR_DOWN: - year_spinner_value--; - year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); + _yearSpinnerValue--; + _yearSpinnerValue = std::clamp(_yearSpinnerValue, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_MONTH_UP: - month_spinner_value++; - month_spinner_value = std::clamp(month_spinner_value, 1, (int)MONTH_COUNT); - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _monthSpinnerValue++; + _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, (int)MONTH_COUNT); + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_MONTH_BOX); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_MONTH_DOWN: - month_spinner_value--; - month_spinner_value = std::clamp(month_spinner_value, 1, (int)MONTH_COUNT); - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _monthSpinnerValue--; + _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, (int)MONTH_COUNT); + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_MONTH_BOX); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DAY_UP: - day_spinner_value++; - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _daySpinnerValue++; + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DAY_DOWN: - day_spinner_value--; - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _daySpinnerValue--; + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DATE_SET: { - auto setDateAction = ParkSetDateAction(year_spinner_value, month_spinner_value, day_spinner_value); + auto setDateAction = ParkSetDateAction(_yearSpinnerValue, _monthSpinnerValue, _daySpinnerValue); GameActions::Execute(&setDateAction); window_invalidate_by_class(WC_BOTTOM_TOOLBAR); break; @@ -694,18 +699,21 @@ static void window_cheats_misc_mousedown(rct_window* w, rct_widgetindex widgetIn switch (widgetIndex) { case WIDX_INCREASE_PARK_RATING: - park_rating_spinner_value = std::min(999, 10 * (park_rating_spinner_value / 10 + 1)); + _parkRatingSpinnerValue = std::min(999, 10 * (_parkRatingSpinnerValue / 10 + 1)); widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); if (get_forced_park_rating() >= 0) - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + { + auto setCheatAction = SetCheatAction(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); + GameActions::Execute(&setCheatAction); + } break; case WIDX_DECREASE_PARK_RATING: - park_rating_spinner_value = std::max(0, 10 * (park_rating_spinner_value / 10 - 1)); + _parkRatingSpinnerValue = std::max(0, 10 * (_parkRatingSpinnerValue / 10 - 1)); widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); if (get_forced_park_rating() >= 0) - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + { + CheatsSet(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); + } break; case WIDX_WEATHER_DROPDOWN_BUTTON: { @@ -755,7 +763,7 @@ static void window_cheats_misc_dropdown([[maybe_unused]] rct_window* w, rct_widg } else if (widgetIndex == WIDX_WEATHER_DROPDOWN_BUTTON) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FORCEWEATHER, dropdownIndex, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ForceWeather, dropdownIndex); } else if (widgetIndex == WIDX_STAFF_SPEED_DROPDOWN_BUTTON) { @@ -769,7 +777,7 @@ static void window_cheats_misc_dropdown([[maybe_unused]] rct_window* w, rct_widg speed = CHEATS_STAFF_NORMAL_SPEED; } - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETSTAFFSPEED, speed, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetStaffSpeed, speed); _selectedStaffSpeed = dropdownIndex; } } @@ -788,8 +796,7 @@ static void window_cheats_money_mouseup(rct_window* w, rct_widgetindex widgetInd window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_NO_MONEY: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_NOMONEY, gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : 1, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::NoMoney, gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : 1); break; case WIDX_MONEY_SPINNER: money_to_string(_moneySpinnerValue, _moneySpinnerText, MONEY_STRING_MAXLENGTH, false); @@ -797,10 +804,10 @@ static void window_cheats_money_mouseup(rct_window* w, rct_widgetindex widgetInd w, WIDX_MONEY_SPINNER, STR_ENTER_NEW_VALUE, STR_ENTER_NEW_VALUE, _moneySpinnerText, MONEY_STRING_MAXLENGTH); break; case WIDX_SET_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETMONEY, _moneySpinnerValue, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetMoney, _moneySpinnerValue); break; case WIDX_CLEAR_LOAN: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_CLEARLOAN, CHEATS_MONEY_DEFAULT, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ClearLoan, CHEATS_MONEY_DEFAULT); break; } } @@ -819,108 +826,82 @@ static void window_cheats_guests_mouseup(rct_window* w, rct_widgetindex widgetIn window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GUEST_HAPPINESS_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HAPPINESS, GAME_COMMAND_CHEAT, - PEEP_MAX_HAPPINESS, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HAPPINESS, PEEP_MAX_HAPPINESS); break; case WIDX_GUEST_HAPPINESS_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HAPPINESS, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HAPPINESS, 0); break; case WIDX_GUEST_ENERGY_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_ENERGY, GAME_COMMAND_CHEAT, - PEEP_MAX_ENERGY, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_ENERGY, PEEP_MAX_ENERGY); break; case WIDX_GUEST_ENERGY_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_ENERGY, GAME_COMMAND_CHEAT, - PEEP_MIN_ENERGY, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_ENERGY, PEEP_MIN_ENERGY); break; case WIDX_GUEST_HUNGER_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HUNGER, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HUNGER, 0); break; case WIDX_GUEST_HUNGER_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HUNGER, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HUNGER, PEEP_MAX_HUNGER); break; case WIDX_GUEST_THIRST_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_THIRST, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_THIRST, 0); break; case WIDX_GUEST_THIRST_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_THIRST, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_THIRST, PEEP_MAX_THIRST); break; case WIDX_GUEST_NAUSEA_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA, PEEP_MAX_NAUSEA); break; case WIDX_GUEST_NAUSEA_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA, 0); break; case WIDX_GUEST_NAUSEA_TOLERANCE_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA_TOLERANCE, GAME_COMMAND_CHEAT, - PEEP_NAUSEA_TOLERANCE_HIGH, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA_TOLERANCE, PEEP_NAUSEA_TOLERANCE_HIGH); break; case WIDX_GUEST_NAUSEA_TOLERANCE_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA_TOLERANCE, GAME_COMMAND_CHEAT, - PEEP_NAUSEA_TOLERANCE_NONE, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA_TOLERANCE, PEEP_NAUSEA_TOLERANCE_NONE); break; case WIDX_GUEST_BATHROOM_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_BATHROOM, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_BATHROOM, PEEP_MAX_BATHROOM); break; case WIDX_GUEST_BATHROOM_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_BATHROOM, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_BATHROOM, 0); break; case WIDX_GUEST_RIDE_INTENSITY_MORE_THAN_1: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, - GAME_COMMAND_CHEAT, 1, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, 1); break; case WIDX_GUEST_RIDE_INTENSITY_LESS_THAN_15: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, 0); break; case WIDX_TRAM_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GENERATEGUESTS, CHEATS_TRAM_INCREMENT, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GenerateGuests, CHEATS_TRAM_INCREMENT); break; case WIDX_REMOVE_ALL_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVEALLGUESTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveAllGuests); break; case WIDX_EXPLODE_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_EXPLODEGUESTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ExplodeGuests); break; case WIDX_GIVE_GUESTS_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_MONEY, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_MONEY); break; case WIDX_GIVE_GUESTS_PARK_MAPS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_PARK_MAP, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_PARK_MAP); break; case WIDX_GIVE_GUESTS_BALLOONS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_BALLOON, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_BALLOON); break; case WIDX_GIVE_GUESTS_UMBRELLAS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_UMBRELLA, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_UMBRELLA); break; case WIDX_GUEST_IGNORE_RIDE_INTENSITY: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_IGNORERIDEINTENSITY, !gCheatsIgnoreRideIntensity, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::IgnoreRideIntensity, !gCheatsIgnoreRideIntensity); break; case WIDX_DISABLE_VANDALISM: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEVANDALISM, !gCheatsDisableVandalism, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableVandalism, !gCheatsDisableVandalism); break; case WIDX_DISABLE_LITTERING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLELITTERING, !gCheatsDisableLittering, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableLittering, !gCheatsDisableLittering); break; } } @@ -939,42 +920,40 @@ static void window_cheats_misc_mouseup(rct_window* w, rct_widgetindex widgetInde window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_FREEZE_WEATHER: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FREEZEWEATHER, !gCheatsFreezeWeather, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FreezeWeather, !gCheatsFreezeWeather); break; case WIDX_OPEN_CLOSE_PARK: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_OPENCLOSEPARK, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::OpenClosePark); break; case WIDX_CLEAR_GRASS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_CLEAR_0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); break; case WIDX_MOWED_GRASS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_MOWED, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); break; case WIDX_WATER_PLANTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WATERPLANTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WaterPlants); break; case WIDX_FIX_VANDALISM: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXVANDALISM, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixVandalism); break; case WIDX_REMOVE_LITTER: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVELITTER, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveLitter); break; case WIDX_DISABLE_PLANT_AGING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEPLANTAGING, !gCheatsDisablePlantAging, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisablePlantAging, !gCheatsDisablePlantAging); break; case WIDX_WIN_SCENARIO: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WINSCENARIO, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WinScenario); break; case WIDX_HAVE_FUN: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_HAVEFUN, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::HaveFun); break; case WIDX_OWN_ALL_LAND: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_OWNALLLAND, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::OwnAllLand); break; case WIDX_NEVERENDING_MARKETING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_NEVERENDINGMARKETING, !gCheatsNeverendingMarketing, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::NeverEndingMarketing, !gCheatsNeverendingMarketing); break; case WIDX_PARK_PARAMETERS: context_open_window(WC_EDITOR_SCENARIO_OPTIONS); @@ -982,12 +961,11 @@ static void window_cheats_misc_mouseup(rct_window* w, rct_widgetindex widgetInde case WIDX_FORCE_PARK_RATING: if (get_forced_park_rating() >= 0) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, -1, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetForcedParkRating, -1); } else { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); } break; } @@ -1007,89 +985,80 @@ static void window_cheats_rides_mouseup(rct_window* w, rct_widgetindex widgetInd window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_RENEW_RIDES: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_RENEWRIDES, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RenewRides); break; case WIDX_MAKE_DESTRUCTIBLE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_MAKEDESTRUCTIBLE, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::MakeDestructible); break; case WIDX_FIX_ALL: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXRIDES, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixRides); break; case WIDX_FAST_LIFT_HILL: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FASTLIFTHILL, !gCheatsFastLiftHill, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FastLiftHill, !gCheatsFastLiftHill); + break; case WIDX_DISABLE_BRAKES_FAILURE: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEBRAKESFAILURE, !gCheatsDisableBrakesFailure, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableBrakesFailure, !gCheatsDisableBrakesFailure); break; case WIDX_DISABLE_ALL_BREAKDOWNS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEALLBREAKDOWNS, !gCheatsDisableAllBreakdowns, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableAllBreakdowns, !gCheatsDisableAllBreakdowns); break; case WIDX_BUILD_IN_PAUSE_MODE: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_BUILDINPAUSEMODE, !gCheatsBuildInPauseMode, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::BuildInPauseMode, !gCheatsBuildInPauseMode); break; case WIDX_RESET_CRASH_STATUS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_RESETCRASHSTATUS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ResetCrashStatus); break; case WIDX_10_MINUTE_INSPECTIONS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_10MINUTEINSPECTIONS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::TenMinuteInspections); break; case WIDX_SHOW_ALL_OPERATING_MODES: + { if (!gCheatsShowAllOperatingModes) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SHOWALLOPERATINGMODES, !gCheatsShowAllOperatingModes, GAME_COMMAND_CHEAT, 0, - 0); - break; + CheatsSet(CheatType::ShowAllOperatingModes, !gCheatsShowAllOperatingModes); + } + break; case WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES: + { if (!gCheatsShowVehiclesFromOtherTrackTypes) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES, !gCheatsShowVehiclesFromOtherTrackTypes, - GAME_COMMAND_CHEAT, 0, 0); - break; + CheatsSet(CheatType::ShowVehiclesFromOtherTrackTypes, !gCheatsShowVehiclesFromOtherTrackTypes); + } + break; case WIDX_DISABLE_TRAIN_LENGTH_LIMITS: + { if (!gCheatsDisableTrainLengthLimit) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLETRAINLENGTHLIMIT, !gCheatsDisableTrainLengthLimit, GAME_COMMAND_CHEAT, - 0, 0); - break; + CheatsSet(CheatType::DisableTrainLengthLimit, !gCheatsDisableTrainLengthLimit); + } + break; case WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ENABLECHAINLIFTONALLTRACK, !gCheatsEnableChainLiftOnAllTrack, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::EnableChainLiftOnAllTrack, !gCheatsEnableChainLiftOnAllTrack); break; case WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES: + { if (!gCheatsAllowArbitraryRideTypeChanges) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES, !gCheatsAllowArbitraryRideTypeChanges, - GAME_COMMAND_CHEAT, 0, 0); - break; + CheatsSet(CheatType::AllowArbitraryRideTypeChanges, !gCheatsAllowArbitraryRideTypeChanges); + } + break; case WIDX_DISABLE_RIDE_VALUE_AGING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLERIDEVALUEAGING, !gCheatsDisableRideValueAging, GAME_COMMAND_CHEAT, 0, - 0); + CheatsSet(CheatType::DisableRideValueAging, !gCheatsDisableRideValueAging); break; case WIDX_IGNORE_RESEARCH_STATUS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_IGNORERESEARCHSTATUS, !gCheatsIgnoreResearchStatus, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::IgnoreResearchStatus, !gCheatsIgnoreResearchStatus); break; case WIDX_ENABLE_ALL_DRAWABLE_TRACK_PIECES: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ENABLEALLDRAWABLETRACKPIECES, !gCheatsEnableAllDrawableTrackPieces, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::EnableAllDrawableTrackPieces, !gCheatsEnableAllDrawableTrackPieces); break; } } @@ -1207,26 +1176,25 @@ static void window_cheats_paint(rct_window* w, rct_drawpixelinfo* dpi) { colour |= COLOUR_FLAG_INSET; } - int32_t actual_month = month_spinner_value - 1; + int32_t actual_month = _monthSpinnerValue - 1; gfx_draw_string_left( dpi, STR_BOTTOM_TOOLBAR_CASH, gCommonFormatArgs, colour, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO); gfx_draw_string_left(dpi, STR_YEAR, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(7) + TXTO); gfx_draw_string_left(dpi, STR_MONTH, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(8) + TXTO); gfx_draw_string_left(dpi, STR_DAY, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(9) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &year_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(7) + TXTO); + dpi, STR_FORMAT_INTEGER, &_yearSpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(7) + TXTO); gfx_draw_string_right( dpi, STR_FORMAT_MONTH, &actual_month, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(8) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &day_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(9) + TXTO); + dpi, STR_FORMAT_INTEGER, &_daySpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(9) + TXTO); } else if (w->page == WINDOW_CHEATS_PAGE_MISC) { gfx_draw_string_left(dpi, STR_CHEAT_STAFF_SPEED, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(17) + TXTO); gfx_draw_string_left(dpi, STR_FORCE_WEATHER, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(10) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &park_rating_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, - w->y + YPL(5) + TXTO); + dpi, STR_FORMAT_INTEGER, &_parkRatingSpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(5) + TXTO); } else if (w->page == WINDOW_CHEATS_PAGE_GUESTS) { diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 25595f9da5..dadbdc6735 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -3421,16 +3422,13 @@ static void top_toolbar_cheats_menu_dropdown(int16_t dropdownIndex) context_open_window(WC_EDITOR_SCENARIO_OPTIONS); break; case DDIDX_ENABLE_SANDBOX_MODE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, !gCheatsSandboxMode, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SandboxMode, !gCheatsSandboxMode); break; case DDIDX_DISABLE_CLEARANCE_CHECKS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, !gCheatsDisableClearanceChecks, GAME_COMMAND_CHEAT, 0, - 0); + CheatsSet(CheatType::DisableClearanceChecks, !gCheatsDisableClearanceChecks); break; case DDIDX_DISABLE_SUPPORT_LIMITS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, !gCheatsDisableSupportLimits, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableSupportLimits, !gCheatsDisableSupportLimits); break; } } diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index d1b1025e61..a7758e77d7 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -11,6 +11,7 @@ #include "GameState.h" #include "actions/ParkSetLoanAction.hpp" +#include "actions/SetCheatAction.hpp" #include "config/Config.h" #include "localisation/Localisation.h" #include "network/network.h" @@ -49,616 +50,7 @@ bool gCheatsDisableRideValueAging = false; bool gCheatsIgnoreResearchStatus = false; bool gCheatsEnableAllDrawableTrackPieces = false; -int32_t park_rating_spinner_value; -int32_t year_spinner_value = 1; -int32_t month_spinner_value = 1; -int32_t day_spinner_value = 1; - -#pragma region Cheat functions - -static void cheat_set_grass_length(int32_t length) -{ - int32_t x, y; - - for (y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++) - { - for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++) - { - auto surfaceElement = map_get_surface_element_at(x, y)->AsSurface(); - if (surfaceElement != nullptr && (surfaceElement->GetOwnership() & OWNERSHIP_OWNED) - && surfaceElement->GetWaterHeight() == 0 && surfaceElement->CanGrassGrow()) - { - surfaceElement->SetGrassLength(length); - } - } - } - - gfx_invalidate_screen(); -} - -static void cheat_water_plants() -{ - tile_element_iterator it; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() == TILE_ELEMENT_TYPE_SMALL_SCENERY) - { - it.element->AsSmallScenery()->SetAge(0); - } - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_fix_vandalism() -{ - tile_element_iterator it; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - - if (!(it.element)->AsPath()->HasAddition()) - continue; - - it.element->AsPath()->SetIsBroken(false); - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_remove_litter() -{ - rct_litter* litter; - uint16_t spriteIndex, nextSpriteIndex; - - for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) - { - litter = &(get_sprite(spriteIndex)->litter); - nextSpriteIndex = litter->next; - sprite_remove((rct_sprite*)litter); - } - - tile_element_iterator it; - rct_scenery_entry* sceneryEntry; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - - if (!(it.element)->AsPath()->HasAddition()) - continue; - - sceneryEntry = it.element->AsPath()->GetAdditionEntry(); - if (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN) - it.element->AsPath()->SetAdditionStatus(0xFF); - - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_fix_rides() -{ - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) - { - if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) - && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) - { - auto mechanic = ride_get_assigned_mechanic(ride); - if (mechanic != nullptr) - { - mechanic->RemoveFromRide(); - } - - ride_fix_breakdown(ride, 0); - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - } - } -} - -static void cheat_renew_rides() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - ride->Renew(); - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_make_destructible() -{ - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) - { - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_reset_crash_status() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - // Reset crash status - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; - // Reset crash history - ride->last_crash_type = RIDE_CRASH_TYPE_NONE; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_10_minute_inspections() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - // Set inspection interval to 10 minutes - ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_no_money(bool enabled) -{ - if (enabled) - { - gParkFlags |= PARK_FLAGS_NO_MONEY; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY; - } - // Invalidate all windows that have anything to do with finance - window_invalidate_by_class(WC_RIDE); - window_invalidate_by_class(WC_PEEP); - window_invalidate_by_class(WC_PARK_INFORMATION); - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); - window_invalidate_by_class(WC_TOP_TOOLBAR); - window_invalidate_by_class(WC_CHEATS); -} - -static void cheat_set_money(money32 amount) -{ - gCash = amount; - - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_add_money(money32 amount) -{ - gCash = add_clamp_money32(gCash, amount); - - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_clear_loan() -{ - // First give money - cheat_add_money(gBankLoan); - - // Then pay the loan - auto gameAction = ParkSetLoanAction(MONEY(0, 00)); - GameActions::Execute(&gameAction); -} - -static void cheat_generate_guests(int32_t count) -{ - auto& park = GetContext()->GetGameState()->GetPark(); - for (int32_t i = 0; i < count; i++) - { - park.GenerateGuest(); - } - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_set_guest_parameter(int32_t parameter, int32_t value) -{ - int32_t spriteIndex; - Peep* p; - FOR_ALL_GUESTS (spriteIndex, p) - { - auto peep = p->AsGuest(); - assert(peep != nullptr); - switch (parameter) - { - case GUEST_PARAMETER_HAPPINESS: - peep->happiness = value; - peep->happiness_target = value; - // Clear the 'red-faced with anger' status if we're making the guest happy - if (value > 0) - { - peep->peep_flags &= ~PEEP_FLAGS_ANGRY; - peep->angriness = 0; - } - break; - case GUEST_PARAMETER_ENERGY: - peep->energy = value; - peep->energy_target = value; - break; - case GUEST_PARAMETER_HUNGER: - peep->hunger = value; - break; - case GUEST_PARAMETER_THIRST: - peep->thirst = value; - break; - case GUEST_PARAMETER_NAUSEA: - peep->nausea = value; - peep->nausea_target = value; - break; - case GUEST_PARAMETER_NAUSEA_TOLERANCE: - peep->nausea_tolerance = value; - break; - case GUEST_PARAMETER_BATHROOM: - peep->toilet = value; - break; - case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: - peep->intensity = (15 << 4) | value; - break; - } - peep->UpdateSpriteType(); - } -} - -static void cheat_give_all_guests(int32_t object) -{ - int32_t spriteIndex; - Peep* p; - FOR_ALL_GUESTS (spriteIndex, p) - { - auto peep = p->AsGuest(); - assert(peep != nullptr); - switch (object) - { - case OBJECT_MONEY: - peep->cash_in_pocket = MONEY(1000, 00); - break; - case OBJECT_PARK_MAP: - peep->item_standard_flags |= PEEP_ITEM_MAP; - break; - case OBJECT_BALLOON: - peep->item_standard_flags |= PEEP_ITEM_BALLOON; - peep->balloon_colour = scenario_rand_max(COLOUR_COUNT - 1); - peep->UpdateSpriteType(); - break; - case OBJECT_UMBRELLA: - peep->item_standard_flags |= PEEP_ITEM_UMBRELLA; - peep->umbrella_colour = scenario_rand_max(COLOUR_COUNT - 1); - peep->UpdateSpriteType(); - break; - } - } - window_invalidate_by_class(WC_PEEP); -} - -static void cheat_remove_all_guests() -{ - Peep* peep; - rct_vehicle* vehicle; - uint16_t spriteIndex, nextSpriteIndex; - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) - { - ride->num_riders = 0; - - for (size_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) - { - ride->stations[stationIndex].QueueLength = 0; - ride->stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; - } - - for (auto trainIndex : ride->vehicles) - { - spriteIndex = trainIndex; - while (spriteIndex != SPRITE_INDEX_NULL) - { - vehicle = GET_VEHICLE(spriteIndex); - for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++) - { - while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL) - { - offset++; - } - peep = GET_PEEP(vehicle->peep[i + offset]); - vehicle->mass -= peep->mass; - } - - for (auto& peepInTrainIndex : vehicle->peep) - { - peepInTrainIndex = SPRITE_INDEX_NULL; - } - - vehicle->num_peeps = 0; - vehicle->next_free_seat = 0; - - spriteIndex = vehicle->next_vehicle_on_train; - } - } - } - - for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) - { - peep = &(get_sprite(spriteIndex)->peep); - nextSpriteIndex = peep->next; - if (peep->type == PEEP_TYPE_GUEST) - { - peep->Remove(); - } - } - - window_invalidate_by_class(WC_RIDE); - gfx_invalidate_screen(); -} - -static void cheat_explode_guests() -{ - int32_t sprite_index; - Peep* peep; - - FOR_ALL_GUESTS (sprite_index, peep) - { - if (scenario_rand_max(6) == 0) - { - peep->peep_flags |= PEEP_FLAGS_EXPLODE; - } - } -} - -static void cheat_set_staff_speed(uint8_t value) -{ - uint16_t spriteIndex; - Peep* peep; - - FOR_ALL_STAFF (spriteIndex, peep) - { - peep->energy = value; - peep->energy_target = value; - } -} - -static void cheat_own_all_land() -{ - const int32_t min = 32; - const int32_t max = gMapSizeUnits - 32; - - for (CoordsXY coords = { min, min }; coords.y <= max; coords.y += 32) - { - for (coords.x = min; coords.x <= max; coords.x += 32) - { - TileElement* surfaceElement = map_get_surface_element_at(coords); - if (surfaceElement == nullptr) - continue; - - // Ignore already owned tiles. - if (surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) - continue; - - int32_t base_z = surfaceElement->base_height; - int32_t destOwnership = check_max_allowable_land_rights_for_tile(coords.x >> 5, coords.y >> 5, base_z); - - // only own tiles that were not set to 0 - if (destOwnership != OWNERSHIP_UNOWNED) - { - surfaceElement->AsSurface()->SetOwnership(destOwnership); - update_park_fences_around_tile(coords); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(coords.x, coords.y, baseHeight, baseHeight + 16); - } - } - } - - // Completely unown peep spawn points - for (const auto& spawn : gPeepSpawns) - { - int32_t x = spawn.x; - int32_t y = spawn.y; - if (x != PEEP_SPAWN_UNDEFINED) - { - TileElement* surfaceElement = map_get_surface_element_at({ x, y }); - surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); - update_park_fences_around_tile({ x, y }); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - } - - map_count_remaining_land_rights(); -} - -#pragma endregion - -void game_command_cheat( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - int32_t cheat = *ecx; - if (*ebx & GAME_COMMAND_FLAG_APPLY) - { - switch (cheat) - { - case CHEAT_SANDBOXMODE: - gCheatsSandboxMode = *edx != 0; - window_invalidate_by_class(WC_MAP); - window_invalidate_by_class(WC_FOOTPATH); - break; - case CHEAT_DISABLECLEARANCECHECKS: - gCheatsDisableClearanceChecks = *edx != 0; - break; - case CHEAT_DISABLESUPPORTLIMITS: - gCheatsDisableSupportLimits = *edx != 0; - break; - case CHEAT_SHOWALLOPERATINGMODES: - gCheatsShowAllOperatingModes = *edx != 0; - break; - case CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES: - gCheatsShowVehiclesFromOtherTrackTypes = *edx != 0; - break; - case CHEAT_FASTLIFTHILL: - gCheatsFastLiftHill = *edx != 0; - break; - case CHEAT_DISABLEBRAKESFAILURE: - gCheatsDisableBrakesFailure = *edx != 0; - break; - case CHEAT_DISABLEALLBREAKDOWNS: - gCheatsDisableAllBreakdowns = *edx != 0; - break; - case CHEAT_DISABLETRAINLENGTHLIMIT: - gCheatsDisableTrainLengthLimit = *edx != 0; - break; - case CHEAT_ENABLECHAINLIFTONALLTRACK: - gCheatsEnableChainLiftOnAllTrack = *edx != 0; - break; - case CHEAT_BUILDINPAUSEMODE: - gCheatsBuildInPauseMode = *edx != 0; - break; - case CHEAT_IGNORERIDEINTENSITY: - gCheatsIgnoreRideIntensity = *edx != 0; - break; - case CHEAT_DISABLEVANDALISM: - gCheatsDisableVandalism = *edx != 0; - break; - case CHEAT_DISABLELITTERING: - gCheatsDisableLittering = *edx != 0; - break; - case CHEAT_NOMONEY: - cheat_no_money(*edx != 0); - break; - case CHEAT_ADDMONEY: - cheat_add_money(*edx); - break; - case CHEAT_SETMONEY: - cheat_set_money(*edx); - break; - case CHEAT_CLEARLOAN: - cheat_clear_loan(); - break; - case CHEAT_SETGUESTPARAMETER: - cheat_set_guest_parameter(*edx, *edi); - break; - case CHEAT_GENERATEGUESTS: - cheat_generate_guests(*edx); - break; - case CHEAT_REMOVEALLGUESTS: - cheat_remove_all_guests(); - break; - case CHEAT_EXPLODEGUESTS: - cheat_explode_guests(); - break; - case CHEAT_GIVEALLGUESTS: - cheat_give_all_guests(*edx); - break; - case CHEAT_SETGRASSLENGTH: - cheat_set_grass_length(*edx); - break; - case CHEAT_WATERPLANTS: - cheat_water_plants(); - break; - case CHEAT_FIXVANDALISM: - cheat_fix_vandalism(); - break; - case CHEAT_REMOVELITTER: - cheat_remove_litter(); - break; - case CHEAT_DISABLEPLANTAGING: - gCheatsDisablePlantAging = *edx != 0; - break; - case CHEAT_SETSTAFFSPEED: - cheat_set_staff_speed(*edx); - break; - case CHEAT_RENEWRIDES: - cheat_renew_rides(); - break; - case CHEAT_MAKEDESTRUCTIBLE: - cheat_make_destructible(); - break; - case CHEAT_FIXRIDES: - cheat_fix_rides(); - break; - case CHEAT_RESETCRASHSTATUS: - cheat_reset_crash_status(); - break; - case CHEAT_10MINUTEINSPECTIONS: - cheat_10_minute_inspections(); - break; - case CHEAT_WINSCENARIO: - scenario_success(); - break; - case CHEAT_FORCEWEATHER: - climate_force_weather(*edx); - break; - case CHEAT_FREEZEWEATHER: - gCheatsFreezeWeather = *edx != 0; - break; - case CHEAT_NEVERENDINGMARKETING: - gCheatsNeverendingMarketing = *edx != 0; - break; - case CHEAT_OPENCLOSEPARK: - park_set_open(!park_is_open()); - break; - case CHEAT_HAVEFUN: - gScenarioObjectiveType = OBJECTIVE_HAVE_FUN; - break; - case CHEAT_SETFORCEDPARKRATING: - if (*edx > -1) - { - park_rating_spinner_value = *edx; - } - set_forced_park_rating(*edx); - break; - case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: - gCheatsAllowArbitraryRideTypeChanges = *edx != 0; - window_invalidate_by_class(WC_RIDE); - break; - case CHEAT_OWNALLLAND: - cheat_own_all_land(); - break; - case CHEAT_DISABLERIDEVALUEAGING: - gCheatsDisableRideValueAging = *edx != 0; - break; - case CHEAT_IGNORERESEARCHSTATUS: - gCheatsIgnoreResearchStatus = *edx != 0; - break; - case CHEAT_ENABLEALLDRAWABLETRACKPIECES: - gCheatsEnableAllDrawableTrackPieces = *edx != 0; - break; - } - if (network_get_mode() == NETWORK_MODE_NONE) - { - config_save_default(); - } - window_invalidate_by_class(WC_CHEATS); - } - *ebx = 0; -} - -void cheats_reset() +void CheatsReset() { gCheatsSandboxMode = false; gCheatsDisableClearanceChecks = false; @@ -682,308 +74,109 @@ void cheats_reset() gCheatsIgnoreResearchStatus = false; } -// Generates the string to print for the server log when a cheat is used. -const char* cheats_get_cheat_string(int cheat, int edx, int edi) +void CheatsSet(CheatType cheatType, int32_t param1 /* = 0*/, int32_t param2 /* = 0*/) { - switch (cheat) - { - case CHEAT_SANDBOXMODE: - if (gCheatsSandboxMode) - { - return language_get_string(STR_CHEAT_SANDBOX_MODE_DISABLE); - } - else - { - return language_get_string(STR_CHEAT_SANDBOX_MODE); - } - case CHEAT_DISABLECLEARANCECHECKS: - return language_get_string(STR_DISABLE_CLEARANCE_CHECKS); - case CHEAT_DISABLESUPPORTLIMITS: - return language_get_string(STR_DISABLE_SUPPORT_LIMITS); - case CHEAT_SHOWALLOPERATINGMODES: - return language_get_string(STR_CHEAT_SHOW_ALL_OPERATING_MODES); - case CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES: - return language_get_string(STR_CHEAT_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES); - case CHEAT_FASTLIFTHILL: - return language_get_string(STR_CHEAT_UNLOCK_OPERATING_LIMITS); - case CHEAT_DISABLEBRAKESFAILURE: - return language_get_string(STR_CHEAT_DISABLE_BRAKES_FAILURE); - case CHEAT_DISABLEALLBREAKDOWNS: - return language_get_string(STR_CHEAT_DISABLE_BREAKDOWNS); - case CHEAT_DISABLETRAINLENGTHLIMIT: - return language_get_string(STR_CHEAT_DISABLE_TRAIN_LENGTH_LIMIT); - case CHEAT_ENABLECHAINLIFTONALLTRACK: - return language_get_string(STR_CHEAT_ENABLE_CHAIN_LIFT_ON_ALL_TRACK); - case CHEAT_BUILDINPAUSEMODE: - return language_get_string(STR_CHEAT_BUILD_IN_PAUSE_MODE); - case CHEAT_IGNORERIDEINTENSITY: - return language_get_string(STR_CHEAT_IGNORE_INTENSITY); - case CHEAT_DISABLEVANDALISM: - return language_get_string(STR_CHEAT_DISABLE_VANDALISM); - case CHEAT_DISABLELITTERING: - return language_get_string(STR_CHEAT_DISABLE_LITTERING); - case CHEAT_NOMONEY: - return language_get_string(STR_MAKE_PARK_NO_MONEY); - case CHEAT_ADDMONEY: - return language_get_string(STR_LOG_CHEAT_ADD_MONEY); - case CHEAT_CLEARLOAN: - return language_get_string(STR_CHEAT_CLEAR_LOAN); - case CHEAT_SETGUESTPARAMETER: - { - static char cheat_string[128]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_SET_GUESTS_PARAMETERS), 128); - safe_strcat(cheat_string, " ", 128); - switch (edx) - { - case GUEST_PARAMETER_HAPPINESS: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_HAPPINESS), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_ENERGY: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_ENERGY), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 127) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_HUNGER: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_HUNGER), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - break; - case GUEST_PARAMETER_THIRST: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_THIRST), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - break; - case GUEST_PARAMETER_NAUSEA: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_NAUSEA), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_NAUSEA_TOLERANCE: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_NAUSEA_TOLERANCE), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == PEEP_NAUSEA_TOLERANCE_HIGH) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == PEEP_NAUSEA_TOLERANCE_NONE) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_BATHROOM: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_BATHROOM), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_PREFERRED_INTENSITY), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 1) - { - safe_strcat(cheat_string, language_get_string(STR_CHEAT_MORE_THAN_1), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_CHEAT_LESS_THAN_15), 128); - } - break; - } - return cheat_string; - } - case CHEAT_GENERATEGUESTS: - return language_get_string(STR_CHEAT_LARGE_TRAM_GUESTS); - case CHEAT_REMOVEALLGUESTS: - return language_get_string(STR_CHEAT_REMOVE_ALL_GUESTS); - case CHEAT_EXPLODEGUESTS: - return language_get_string(STR_CHEAT_EXPLODE); - case CHEAT_GIVEALLGUESTS: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_GIVE_ALL_GUESTS), 64); - safe_strcat(cheat_string, " ", 64); - switch (edx) - { - case OBJECT_MONEY: - { - char money[16]; - set_format_arg(0, money32, CHEATS_GIVE_GUESTS_MONEY); - format_string(money, 16, STR_CHEAT_CURRENCY_FORMAT, gCommonFormatArgs); - safe_strcat(cheat_string, money, 64); - break; - } - case OBJECT_PARK_MAP: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_PARK_MAP), 64); - break; - case OBJECT_BALLOON: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_BALLOON), 64); - break; - case OBJECT_UMBRELLA: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_UMBRELLA), 64); - break; - } - return cheat_string; - } - case CHEAT_SETGRASSLENGTH: - if (edx == 0) - { - return language_get_string(STR_CHEAT_MOWED_GRASS); - } - return language_get_string(STR_CHEAT_CLEAR_GRASS); - case CHEAT_WATERPLANTS: - return language_get_string(STR_CHEAT_WATER_PLANTS); - case CHEAT_FIXVANDALISM: - return language_get_string(STR_CHEAT_FIX_VANDALISM); - case CHEAT_REMOVELITTER: - return language_get_string(STR_CHEAT_REMOVE_LITTER); - case CHEAT_DISABLEPLANTAGING: - return language_get_string(STR_CHEAT_DISABLE_PLANT_AGING); - case CHEAT_SETSTAFFSPEED: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_STAFF_SPEED), 64); - safe_strcat(cheat_string, " ", 64); - if (edx == CHEATS_STAFF_FAST_SPEED) - { - safe_strcat(cheat_string, language_get_string(STR_FAST), 64); - } - else if (edx == CHEATS_STAFF_NORMAL_SPEED) - { - safe_strcat(cheat_string, language_get_string(STR_NORMAL), 64); - } - return cheat_string; - } - case CHEAT_RENEWRIDES: - return language_get_string(STR_CHEAT_RENEW_RIDES); - case CHEAT_MAKEDESTRUCTIBLE: - return language_get_string(STR_CHEAT_MAKE_DESTRUCTABLE); - case CHEAT_FIXRIDES: - return language_get_string(STR_CHEAT_FIX_ALL_RIDES); - case CHEAT_RESETCRASHSTATUS: - return language_get_string(STR_CHEAT_RESET_CRASH_STATUS); - case CHEAT_10MINUTEINSPECTIONS: - return language_get_string(STR_CHEAT_10_MINUTE_INSPECTIONS); - case CHEAT_WINSCENARIO: - return language_get_string(STR_CHEAT_WIN_SCENARIO); - case CHEAT_FORCEWEATHER: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_FORCE_WEATHER), 64); - safe_strcat(cheat_string, " ", 64); - switch (edx) - { - case 0: - safe_strcat(cheat_string, language_get_string(STR_SUNNY), 64); - break; - case 1: - safe_strcat(cheat_string, language_get_string(STR_PARTIALLY_CLOUDY), 64); - break; - case 2: - safe_strcat(cheat_string, language_get_string(STR_CLOUDY), 64); - break; - case 3: - safe_strcat(cheat_string, language_get_string(STR_RAIN), 64); - break; - case 4: - safe_strcat(cheat_string, language_get_string(STR_HEAVY_RAIN), 64); - break; - case 5: - safe_strcat(cheat_string, language_get_string(STR_THUNDERSTORM), 64); - break; - } - return cheat_string; - } - case CHEAT_FREEZEWEATHER: - if (gCheatsFreezeWeather) - { - return language_get_string(STR_CHEAT_UNFREEZE_WEATHER); - } - else - { - return language_get_string(STR_CHEAT_FREEZE_WEATHER); - } - case CHEAT_NEVERENDINGMARKETING: - return language_get_string(STR_CHEAT_NEVERENDING_MARKETING); - case CHEAT_OPENCLOSEPARK: - if (park_is_open()) - { - return language_get_string(STR_CHEAT_CLOSE_PARK); - } - else - { - return language_get_string(STR_CHEAT_OPEN_PARK); - } - case CHEAT_HAVEFUN: - return language_get_string(STR_CHEAT_HAVE_FUN); - case CHEAT_SETFORCEDPARKRATING: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_FORCE_PARK_RATING), 64); - safe_strcat(cheat_string, " ", 64); - - char buffer[8]; - snprintf(buffer, sizeof(buffer), "%d", park_rating_spinner_value); - char* park_rating = buffer; - safe_strcat(cheat_string, park_rating, 64); - - return cheat_string; - } - case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: - return language_get_string(STR_CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES); - case CHEAT_SETMONEY: - return language_get_string(STR_SET_MONEY); - case CHEAT_OWNALLLAND: - return language_get_string(STR_CHEAT_OWN_ALL_LAND); - case CHEAT_DISABLERIDEVALUEAGING: - return language_get_string(STR_CHEAT_DISABLE_RIDE_VALUE_AGING); - case CHEAT_IGNORERESEARCHSTATUS: - return language_get_string(STR_CHEAT_IGNORE_RESEARCH_STATUS); - case CHEAT_ENABLEALLDRAWABLETRACKPIECES: - return language_get_string(STR_CHEAT_ENABLE_ALL_DRAWABLE_TRACK_PIECES); - } - - return ""; + auto setCheatAction = SetCheatAction(cheatType, param1, param2); + GameActions::Execute(&setCheatAction); +} + +const char* CheatsGetName(CheatType cheatType) +{ + switch (cheatType) + { + case CheatType::SandboxMode: + return language_get_string(STR_CHEAT_SANDBOX_MODE); + case CheatType::DisableClearanceChecks: + return language_get_string(STR_DISABLE_CLEARANCE_CHECKS); + case CheatType::DisableSupportLimits: + return language_get_string(STR_DISABLE_SUPPORT_LIMITS); + case CheatType::ShowAllOperatingModes: + return language_get_string(STR_CHEAT_SHOW_ALL_OPERATING_MODES); + case CheatType::ShowVehiclesFromOtherTrackTypes: + return language_get_string(STR_CHEAT_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES); + case CheatType::FastLiftHill: + return language_get_string(STR_CHEAT_UNLOCK_OPERATING_LIMITS); + case CheatType::DisableBrakesFailure: + return language_get_string(STR_CHEAT_DISABLE_BRAKES_FAILURE); + case CheatType::DisableAllBreakdowns: + return language_get_string(STR_CHEAT_DISABLE_BREAKDOWNS); + case CheatType::DisableTrainLengthLimit: + return language_get_string(STR_CHEAT_DISABLE_TRAIN_LENGTH_LIMIT); + case CheatType::EnableChainLiftOnAllTrack: + return language_get_string(STR_CHEAT_ENABLE_CHAIN_LIFT_ON_ALL_TRACK); + case CheatType::BuildInPauseMode: + return language_get_string(STR_CHEAT_BUILD_IN_PAUSE_MODE); + case CheatType::IgnoreRideIntensity: + return language_get_string(STR_CHEAT_IGNORE_INTENSITY); + case CheatType::DisableVandalism: + return language_get_string(STR_CHEAT_DISABLE_VANDALISM); + case CheatType::DisableLittering: + return language_get_string(STR_CHEAT_DISABLE_LITTERING); + case CheatType::NoMoney: + return language_get_string(STR_MAKE_PARK_NO_MONEY); + case CheatType::AddMoney: + return language_get_string(STR_LOG_CHEAT_ADD_MONEY); + case CheatType::ClearLoan: + return language_get_string(STR_CHEAT_CLEAR_LOAN); + case CheatType::SetGuestParameter: + return language_get_string(STR_CHEAT_SET_GUESTS_PARAMETERS); + case CheatType::GenerateGuests: + return language_get_string(STR_CHEAT_LARGE_TRAM_GUESTS); + case CheatType::RemoveAllGuests: + return language_get_string(STR_CHEAT_REMOVE_ALL_GUESTS); + case CheatType::ExplodeGuests: + return language_get_string(STR_CHEAT_EXPLODE); + case CheatType::GiveAllGuests: + return language_get_string(STR_CHEAT_GIVE_ALL_GUESTS); + case CheatType::SetGrassLength: + return language_get_string(STR_CHEAT_CLEAR_GRASS); + case CheatType::WaterPlants: + return language_get_string(STR_CHEAT_WATER_PLANTS); + case CheatType::FixVandalism: + return language_get_string(STR_CHEAT_FIX_VANDALISM); + case CheatType::RemoveLitter: + return language_get_string(STR_CHEAT_REMOVE_LITTER); + case CheatType::DisablePlantAging: + return language_get_string(STR_CHEAT_DISABLE_PLANT_AGING); + case CheatType::SetStaffSpeed: + return language_get_string(STR_CHEAT_STAFF_SPEED); + case CheatType::RenewRides: + return language_get_string(STR_CHEAT_RENEW_RIDES); + case CheatType::MakeDestructible: + return language_get_string(STR_CHEAT_MAKE_DESTRUCTABLE); + case CheatType::FixRides: + return language_get_string(STR_CHEAT_FIX_ALL_RIDES); + case CheatType::ResetCrashStatus: + return language_get_string(STR_CHEAT_RESET_CRASH_STATUS); + case CheatType::TenMinuteInspections: + return language_get_string(STR_CHEAT_10_MINUTE_INSPECTIONS); + case CheatType::WinScenario: + return language_get_string(STR_CHEAT_WIN_SCENARIO); + case CheatType::ForceWeather: + return language_get_string(STR_FORCE_WEATHER); + case CheatType::FreezeWeather: + return language_get_string(STR_CHEAT_FREEZE_WEATHER); + case CheatType::NeverEndingMarketing: + return language_get_string(STR_CHEAT_NEVERENDING_MARKETING); + case CheatType::OpenClosePark: + return language_get_string(STR_CHEAT_OPEN_PARK); + case CheatType::HaveFun: + return language_get_string(STR_CHEAT_HAVE_FUN); + case CheatType::SetForcedParkRating: + return language_get_string(STR_FORCE_PARK_RATING); + case CheatType::AllowArbitraryRideTypeChanges: + return language_get_string(STR_CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES); + case CheatType::SetMoney: + return language_get_string(STR_SET_MONEY); + case CheatType::OwnAllLand: + return language_get_string(STR_CHEAT_OWN_ALL_LAND); + case CheatType::DisableRideValueAging: + return language_get_string(STR_CHEAT_DISABLE_RIDE_VALUE_AGING); + case CheatType::IgnoreResearchStatus: + return language_get_string(STR_CHEAT_IGNORE_RESEARCH_STATUS); + case CheatType::EnableAllDrawableTrackPieces: + return language_get_string(STR_CHEAT_ENABLE_ALL_DRAWABLE_TRACK_PIECES); + default: + return "Unknown Cheat"; + } } diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index b690ba18c1..a582b98c1e 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -34,55 +34,56 @@ extern bool gCheatsAllowArbitraryRideTypeChanges; extern bool gCheatsIgnoreResearchStatus; extern bool gCheatsEnableAllDrawableTrackPieces; -enum +enum class CheatType : int32_t { - CHEAT_SANDBOXMODE, - CHEAT_DISABLECLEARANCECHECKS, - CHEAT_DISABLESUPPORTLIMITS, - CHEAT_SHOWALLOPERATINGMODES, - CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES, - CHEAT_DISABLETRAINLENGTHLIMIT, - CHEAT_ENABLECHAINLIFTONALLTRACK, - CHEAT_FASTLIFTHILL, - CHEAT_DISABLEBRAKESFAILURE, - CHEAT_DISABLEALLBREAKDOWNS, - CHEAT_UNLOCKALLPRICES, - CHEAT_BUILDINPAUSEMODE, - CHEAT_IGNORERIDEINTENSITY, - CHEAT_DISABLEVANDALISM, - CHEAT_DISABLELITTERING, - CHEAT_NOMONEY, - CHEAT_ADDMONEY, - CHEAT_SETMONEY, - CHEAT_CLEARLOAN, - CHEAT_SETGUESTPARAMETER, - CHEAT_GENERATEGUESTS, - CHEAT_REMOVEALLGUESTS, - CHEAT_EXPLODEGUESTS, - CHEAT_GIVEALLGUESTS, - CHEAT_SETGRASSLENGTH, - CHEAT_WATERPLANTS, - CHEAT_DISABLEPLANTAGING, - CHEAT_FIXVANDALISM, - CHEAT_REMOVELITTER, - CHEAT_SETSTAFFSPEED, - CHEAT_RENEWRIDES, - CHEAT_MAKEDESTRUCTIBLE, - CHEAT_FIXRIDES, - CHEAT_RESETCRASHSTATUS, - CHEAT_10MINUTEINSPECTIONS, - CHEAT_WINSCENARIO, - CHEAT_FORCEWEATHER, - CHEAT_FREEZEWEATHER, - CHEAT_OPENCLOSEPARK, - CHEAT_HAVEFUN, - CHEAT_SETFORCEDPARKRATING, - CHEAT_NEVERENDINGMARKETING, - CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES, - CHEAT_OWNALLLAND, - CHEAT_DISABLERIDEVALUEAGING, - CHEAT_IGNORERESEARCHSTATUS, - CHEAT_ENABLEALLDRAWABLETRACKPIECES, + SandboxMode, + DisableClearanceChecks, + DisableSupportLimits, + ShowAllOperatingModes, + ShowVehiclesFromOtherTrackTypes, + DisableTrainLengthLimit, + EnableChainLiftOnAllTrack, + FastLiftHill, + DisableBrakesFailure, + DisableAllBreakdowns, + UnlockAllPrices, + BuildInPauseMode, + IgnoreRideIntensity, + DisableVandalism, + DisableLittering, + NoMoney, + AddMoney, + SetMoney, + ClearLoan, + SetGuestParameter, + GenerateGuests, + RemoveAllGuests, + ExplodeGuests, + GiveAllGuests, + SetGrassLength, + WaterPlants, + DisablePlantAging, + FixVandalism, + RemoveLitter, + SetStaffSpeed, + RenewRides, + MakeDestructible, + FixRides, + ResetCrashStatus, + TenMinuteInspections, + WinScenario, + ForceWeather, + FreezeWeather, + OpenClosePark, + HaveFun, + SetForcedParkRating, + NeverEndingMarketing, + AllowArbitraryRideTypeChanges, + OwnAllLand, + DisableRideValueAging, + IgnoreResearchStatus, + EnableAllDrawableTrackPieces, + Count, }; enum @@ -111,15 +112,8 @@ enum #define CHEATS_STAFF_NORMAL_SPEED 0x60 #define CHEATS_STAFF_FREEZE_SPEED 0 -extern int32_t park_rating_spinner_value; -extern int32_t year_spinner_value; -extern int32_t month_spinner_value; -extern int32_t day_spinner_value; - -void game_command_cheat(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - -void cheats_reset(); - -const char* cheats_get_cheat_string(int cheat, int edx, int edi); +void CheatsReset(); +const char* CheatsGetName(CheatType cheatType); +void CheatsSet(CheatType cheatType, int32_t param1 = 0, int32_t param2 = 0); #endif diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index d211f75eae..0901871363 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -577,18 +577,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c } char log_msg[256]; - if (command == GAME_COMMAND_CHEAT) - { - // Get cheat name - const char* cheat = cheats_get_cheat_string(*ecx, *edx, *edi); - char* args[2] = { - (char*)player_name, - (char*)cheat, - }; - format_string(log_msg, 256, STR_LOG_CHEAT_USED, args); - network_append_server_log(log_msg); - } - else if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0)) + if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0)) { // ebp is 1 if command comes from ride window prompt, so we don't log "demolishing" ride previews // Get ride name Ride* ride = get_ride(*edx); @@ -1228,7 +1217,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, game_command_modify_groups, game_command_kick_player, - game_command_cheat, + nullptr, game_command_pickup_guest, game_command_pickup_staff, game_command_balloon_press, diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index 456948824f..baafa4c97c 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -18,6 +18,7 @@ #include "actions/GameAction.h" #include "actions/RideEntranceExitPlaceAction.hpp" #include "actions/RideSetSetting.hpp" +#include "actions/SetCheatAction.hpp" #include "actions/TrackPlaceAction.hpp" #include "config/Config.h" #include "core/DataSerialiser.h" @@ -526,6 +527,16 @@ namespace OpenRCT2 result.action->SetFlags(command.ebx & 0xFF); break; } + case GAME_COMMAND_CHEAT: + { + int32_t param1 = command.edx; + int32_t param2 = command.edi; + CheatType cheatType = static_cast(command.ecx); + + result.action = std::make_unique(cheatType, param1, param2); + result.action->SetFlags(command.ebx & 0xFF); + break; + } default: throw std::runtime_error("Deprecated game command requires replay translation."); } diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index e43fd171c7..67fe2817c6 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -53,6 +53,7 @@ #include "RideSetSetting.hpp" #include "RideSetStatus.hpp" #include "RideSetVehiclesAction.hpp" +#include "SetCheatAction.hpp" #include "SetParkEntranceFeeAction.hpp" #include "SignSetNameAction.hpp" #include "SignSetStyleAction.hpp" @@ -149,5 +150,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp new file mode 100644 index 0000000000..06ed56b4f3 --- /dev/null +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -0,0 +1,792 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../Context.h" +#include "../GameState.h" +#include "../config/Config.h" +#include "../core/String.hpp" +#include "../drawing/Drawing.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../network/network.h" +#include "../ride/Ride.h" +#include "../scenario/Scenario.h" +#include "../ui/UiContext.h" +#include "../util/Util.h" +#include "../windows/Intent.h" +#include "../world/Banner.h" +#include "../world/Climate.h" +#include "../world/Footpath.h" +#include "../world/Map.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" +#include "ParkSetLoanAction.hpp" +#include "ParkSetParameterAction.hpp" + +DEFINE_GAME_ACTION(SetCheatAction, GAME_COMMAND_CHEAT, GameActionResult) +{ + using ParametersRange = std::pair, std::pair>; + +private: + NetworkCheatType_t _cheatType; + int32_t _param1 = 0; + int32_t _param2 = 0; + +public: + SetCheatAction() = default; + SetCheatAction(CheatType cheatType, int32_t param1 = 0, int32_t param2 = 0) + : _cheatType(static_cast(cheatType)) + , _param1(param1) + , _param2(param2) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_cheatType) << DS_TAG(_param1) << DS_TAG(_param2); + } + + GameActionResult::Ptr Query() const override + { + if (static_cast(_cheatType) >= static_cast(CheatType::Count)) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + ParametersRange validRange = GetParameterRange(static_cast(_cheatType.id)); + + if (_param1 < validRange.first.first || _param1 > validRange.first.second) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + if (_param2 < validRange.second.first || _param2 > validRange.second.second) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + switch (static_cast(_cheatType.id)) + { + case CheatType::SandboxMode: + gCheatsSandboxMode = _param1 != 0; + window_invalidate_by_class(WC_MAP); + window_invalidate_by_class(WC_FOOTPATH); + break; + case CheatType::DisableClearanceChecks: + gCheatsDisableClearanceChecks = _param1 != 0; + break; + case CheatType::DisableSupportLimits: + gCheatsDisableSupportLimits = _param1 != 0; + break; + case CheatType::ShowAllOperatingModes: + gCheatsShowAllOperatingModes = _param1 != 0; + break; + case CheatType::ShowVehiclesFromOtherTrackTypes: + gCheatsShowVehiclesFromOtherTrackTypes = _param1 != 0; + break; + case CheatType::FastLiftHill: + gCheatsFastLiftHill = _param1 != 0; + break; + case CheatType::DisableBrakesFailure: + gCheatsDisableBrakesFailure = _param1 != 0; + break; + case CheatType::DisableAllBreakdowns: + gCheatsDisableAllBreakdowns = _param1 != 0; + break; + case CheatType::DisableTrainLengthLimit: + gCheatsDisableTrainLengthLimit = _param1 != 0; + break; + case CheatType::EnableChainLiftOnAllTrack: + gCheatsEnableChainLiftOnAllTrack = _param1 != 0; + break; + case CheatType::BuildInPauseMode: + gCheatsBuildInPauseMode = _param1 != 0; + break; + case CheatType::IgnoreRideIntensity: + gCheatsIgnoreRideIntensity = _param1 != 0; + break; + case CheatType::DisableVandalism: + gCheatsDisableVandalism = _param1 != 0; + break; + case CheatType::DisableLittering: + gCheatsDisableLittering = _param1 != 0; + break; + case CheatType::NoMoney: + SetScenarioNoMoney(_param1 != 0); + break; + case CheatType::AddMoney: + AddMoney(_param1); + break; + case CheatType::SetMoney: + SetMoney(_param1); + break; + case CheatType::ClearLoan: + ClearLoan(); + break; + case CheatType::SetGuestParameter: + SetGuestParameter(_param1, _param2); + break; + case CheatType::GenerateGuests: + GenerateGuests(_param1); + break; + case CheatType::RemoveAllGuests: + RemoveAllGuests(); + break; + case CheatType::ExplodeGuests: + ExplodeGuests(); + break; + case CheatType::GiveAllGuests: + GiveObjectToGuests(_param1); + break; + case CheatType::SetGrassLength: + SetGrassLength(_param1); + break; + case CheatType::WaterPlants: + WaterPlants(); + break; + case CheatType::FixVandalism: + FixVandalism(); + break; + case CheatType::RemoveLitter: + RemoveLitter(); + break; + case CheatType::DisablePlantAging: + gCheatsDisablePlantAging = _param1 != 0; + break; + case CheatType::SetStaffSpeed: + SetStaffSpeed(_param1); + break; + case CheatType::RenewRides: + RenewRides(); + break; + case CheatType::MakeDestructible: + MakeDestructible(); + break; + case CheatType::FixRides: + FixBrokenRides(); + break; + case CheatType::ResetCrashStatus: + ResetRideCrashStatus(); + break; + case CheatType::TenMinuteInspections: + Set10MinuteInspection(); + break; + case CheatType::WinScenario: + scenario_success(); + break; + case CheatType::ForceWeather: + climate_force_weather(_param1); + break; + case CheatType::FreezeWeather: + gCheatsFreezeWeather = _param1 != 0; + break; + case CheatType::NeverEndingMarketing: + gCheatsNeverendingMarketing = _param1 != 0; + break; + case CheatType::OpenClosePark: + ParkSetOpen(!park_is_open()); + break; + case CheatType::HaveFun: + gScenarioObjectiveType = OBJECTIVE_HAVE_FUN; + break; + case CheatType::SetForcedParkRating: + set_forced_park_rating(_param1); + break; + case CheatType::AllowArbitraryRideTypeChanges: + gCheatsAllowArbitraryRideTypeChanges = _param1 != 0; + window_invalidate_by_class(WC_RIDE); + break; + case CheatType::OwnAllLand: + OwnAllLand(); + break; + case CheatType::DisableRideValueAging: + gCheatsDisableRideValueAging = _param1 != 0; + break; + case CheatType::IgnoreResearchStatus: + gCheatsIgnoreResearchStatus = _param1 != 0; + break; + case CheatType::EnableAllDrawableTrackPieces: + gCheatsEnableAllDrawableTrackPieces = _param1 != 0; + break; + default: + { + log_error("Unabled cheat: %d", _cheatType.id); + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + break; + } + + if (network_get_mode() == NETWORK_MODE_NONE) + { + config_save_default(); + } + + window_invalidate_by_class(WC_CHEATS); + return MakeResult(); + } + +private: + ParametersRange GetParameterRange(CheatType cheatType) const + { + switch (static_cast(_cheatType.id)) + { + case CheatType::SandboxMode: + [[fallthrough]]; + case CheatType::DisableClearanceChecks: + [[fallthrough]]; + case CheatType::DisableSupportLimits: + [[fallthrough]]; + case CheatType::ShowAllOperatingModes: + [[fallthrough]]; + case CheatType::ShowVehiclesFromOtherTrackTypes: + [[fallthrough]]; + case CheatType::FastLiftHill: + [[fallthrough]]; + case CheatType::DisableBrakesFailure: + [[fallthrough]]; + case CheatType::DisableAllBreakdowns: + [[fallthrough]]; + case CheatType::DisableTrainLengthLimit: + [[fallthrough]]; + case CheatType::EnableChainLiftOnAllTrack: + [[fallthrough]]; + case CheatType::BuildInPauseMode: + [[fallthrough]]; + case CheatType::IgnoreRideIntensity: + [[fallthrough]]; + case CheatType::DisableVandalism: + [[fallthrough]]; + case CheatType::DisableLittering: + [[fallthrough]]; + case CheatType::NoMoney: + [[fallthrough]]; + case CheatType::DisablePlantAging: + [[fallthrough]]; + case CheatType::FreezeWeather: + [[fallthrough]]; + case CheatType::NeverEndingMarketing: + [[fallthrough]]; + case CheatType::AllowArbitraryRideTypeChanges: + [[fallthrough]]; + case CheatType::DisableRideValueAging: + [[fallthrough]]; + case CheatType::IgnoreResearchStatus: + [[fallthrough]]; + case CheatType::EnableAllDrawableTrackPieces: + [[fallthrough]]; + case CheatType::OpenClosePark: + return { { 0, 1 }, { 0, 0 } }; + case CheatType::AddMoney: + [[fallthrough]]; + case CheatType::SetMoney: + return { { std::numeric_limits::min(), std::numeric_limits::max() }, { 0, 0 } }; + case CheatType::SetGuestParameter: + switch (_param1) + { + case GUEST_PARAMETER_HAPPINESS: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_HAPPINESS } }; + case GUEST_PARAMETER_ENERGY: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { PEEP_MIN_ENERGY, PEEP_MAX_ENERGY } }; + case GUEST_PARAMETER_HUNGER: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_HUNGER } }; + case GUEST_PARAMETER_THIRST: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_THIRST } }; + case GUEST_PARAMETER_NAUSEA: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_NAUSEA } }; + case GUEST_PARAMETER_NAUSEA_TOLERANCE: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { PEEP_NAUSEA_TOLERANCE_NONE, PEEP_NAUSEA_TOLERANCE_HIGH } }; + case GUEST_PARAMETER_BATHROOM: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_BATHROOM } }; + case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, { 0, 255 } }; + default: + return { { 0, 0 }, { 0, 0 } }; + } + case CheatType::GenerateGuests: + return { { 1, 10000 }, { 0, 0 } }; + case CheatType::GiveAllGuests: + return { { OBJECT_MONEY, OBJECT_UMBRELLA }, { 0, 0 } }; + case CheatType::SetGrassLength: + return { { 0, 7 }, { 0, 0 } }; + case CheatType::SetStaffSpeed: + return { { 0, 255 }, { 0, 0 } }; + case CheatType::ForceWeather: + return { { 0, 5 }, { 0, 0 } }; + case CheatType::SetForcedParkRating: + return { { 0, 999 }, { 0, 0 } }; + default: + return { { 0, 0 }, { 0, 0 } }; + } + } + + void SetGrassLength(int32_t length) const + { + int32_t x, y; + + for (y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++) + { + for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++) + { + auto surfaceElement = map_get_surface_element_at(x, y)->AsSurface(); + if (surfaceElement != nullptr && (surfaceElement->GetOwnership() & OWNERSHIP_OWNED) + && surfaceElement->GetWaterHeight() == 0 && surfaceElement->CanGrassGrow()) + { + surfaceElement->SetGrassLength(length); + } + } + } + + gfx_invalidate_screen(); + } + + void WaterPlants() const + { + tile_element_iterator it; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() == TILE_ELEMENT_TYPE_SMALL_SCENERY) + { + it.element->AsSmallScenery()->SetAge(0); + } + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void FixVandalism() const + { + tile_element_iterator it; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + + if (!(it.element)->AsPath()->HasAddition()) + continue; + + it.element->AsPath()->SetIsBroken(false); + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void RemoveLitter() const + { + rct_litter* litter; + uint16_t spriteIndex, nextSpriteIndex; + + for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) + { + litter = &(get_sprite(spriteIndex)->litter); + nextSpriteIndex = litter->next; + sprite_remove((rct_sprite*)litter); + } + + tile_element_iterator it; + rct_scenery_entry* sceneryEntry; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + + if (!(it.element)->AsPath()->HasAddition()) + continue; + + sceneryEntry = it.element->AsPath()->GetAdditionEntry(); + if (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN) + it.element->AsPath()->SetAdditionStatus(0xFF); + + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void FixBrokenRides() const + { + ride_id_t rideIndex; + Ride* ride; + + FOR_ALL_RIDES (rideIndex, ride) + { + if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) + && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) + { + auto mechanic = ride_get_assigned_mechanic(ride); + if (mechanic != nullptr) + { + mechanic->RemoveFromRide(); + } + + ride_fix_breakdown(ride, 0); + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + } + } + } + + void RenewRides() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + ride->Renew(); + } + window_invalidate_by_class(WC_RIDE); + } + + void MakeDestructible() const + { + int32_t i; + Ride* ride; + FOR_ALL_RIDES (i, ride) + { + if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; + if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + } + window_invalidate_by_class(WC_RIDE); + } + + void ResetRideCrashStatus() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + // Reset crash status + if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; + // Reset crash history + ride->last_crash_type = RIDE_CRASH_TYPE_NONE; + } + window_invalidate_by_class(WC_RIDE); + } + + void Set10MinuteInspection() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + // Set inspection interval to 10 minutes + ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; + } + window_invalidate_by_class(WC_RIDE); + } + + void SetScenarioNoMoney(bool enabled) const + { + if (enabled) + { + gParkFlags |= PARK_FLAGS_NO_MONEY; + } + else + { + gParkFlags &= ~PARK_FLAGS_NO_MONEY; + } + // Invalidate all windows that have anything to do with finance + window_invalidate_by_class(WC_RIDE); + window_invalidate_by_class(WC_PEEP); + window_invalidate_by_class(WC_PARK_INFORMATION); + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + window_invalidate_by_class(WC_TOP_TOOLBAR); + window_invalidate_by_class(WC_CHEATS); + } + + void SetMoney(money32 amount) const + { + gCash = amount; + + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void AddMoney(money32 amount) const + { + gCash = add_clamp_money32(gCash, amount); + + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void ClearLoan() const + { + // First give money + AddMoney(gBankLoan); + + // Then pay the loan + auto gameAction = ParkSetLoanAction(MONEY(0, 00)); + GameActions::ExecuteNested(&gameAction); + } + + void GenerateGuests(int32_t count) const + { + auto& park = OpenRCT2::GetContext()->GetGameState()->GetPark(); + for (int32_t i = 0; i < count; i++) + { + park.GenerateGuest(); + } + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void SetGuestParameter(int32_t parameter, int32_t value) const + { + int32_t spriteIndex; + Peep* p; + FOR_ALL_GUESTS (spriteIndex, p) + { + auto peep = p->AsGuest(); + assert(peep != nullptr); + switch (parameter) + { + case GUEST_PARAMETER_HAPPINESS: + peep->happiness = value; + peep->happiness_target = value; + // Clear the 'red-faced with anger' status if we're making the guest happy + if (value > 0) + { + peep->peep_flags &= ~PEEP_FLAGS_ANGRY; + peep->angriness = 0; + } + break; + case GUEST_PARAMETER_ENERGY: + peep->energy = value; + peep->energy_target = value; + break; + case GUEST_PARAMETER_HUNGER: + peep->hunger = value; + break; + case GUEST_PARAMETER_THIRST: + peep->thirst = value; + break; + case GUEST_PARAMETER_NAUSEA: + peep->nausea = value; + peep->nausea_target = value; + break; + case GUEST_PARAMETER_NAUSEA_TOLERANCE: + peep->nausea_tolerance = value; + break; + case GUEST_PARAMETER_BATHROOM: + peep->toilet = value; + break; + case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: + peep->intensity = (15 << 4) | value; + break; + } + peep->UpdateSpriteType(); + } + } + + void GiveObjectToGuests(int32_t object) const + { + int32_t spriteIndex; + Peep* p; + FOR_ALL_GUESTS (spriteIndex, p) + { + auto peep = p->AsGuest(); + assert(peep != nullptr); + switch (object) + { + case OBJECT_MONEY: + peep->cash_in_pocket = MONEY(1000, 00); + break; + case OBJECT_PARK_MAP: + peep->item_standard_flags |= PEEP_ITEM_MAP; + break; + case OBJECT_BALLOON: + peep->item_standard_flags |= PEEP_ITEM_BALLOON; + peep->balloon_colour = scenario_rand_max(COLOUR_COUNT - 1); + peep->UpdateSpriteType(); + break; + case OBJECT_UMBRELLA: + peep->item_standard_flags |= PEEP_ITEM_UMBRELLA; + peep->umbrella_colour = scenario_rand_max(COLOUR_COUNT - 1); + peep->UpdateSpriteType(); + break; + } + } + window_invalidate_by_class(WC_PEEP); + } + + void RemoveAllGuests() const + { + Peep* peep; + rct_vehicle* vehicle; + uint16_t spriteIndex, nextSpriteIndex; + ride_id_t rideIndex; + Ride* ride; + + FOR_ALL_RIDES (rideIndex, ride) + { + ride->num_riders = 0; + + for (size_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) + { + ride->stations[stationIndex].QueueLength = 0; + ride->stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; + } + + for (auto trainIndex : ride->vehicles) + { + spriteIndex = trainIndex; + while (spriteIndex != SPRITE_INDEX_NULL) + { + vehicle = GET_VEHICLE(spriteIndex); + for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++) + { + while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL) + { + offset++; + } + peep = GET_PEEP(vehicle->peep[i + offset]); + vehicle->mass -= peep->mass; + } + + for (auto& peepInTrainIndex : vehicle->peep) + { + peepInTrainIndex = SPRITE_INDEX_NULL; + } + + vehicle->num_peeps = 0; + vehicle->next_free_seat = 0; + + spriteIndex = vehicle->next_vehicle_on_train; + } + } + } + + for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) + { + peep = &(get_sprite(spriteIndex)->peep); + nextSpriteIndex = peep->next; + if (peep->type == PEEP_TYPE_GUEST) + { + peep->Remove(); + } + } + + window_invalidate_by_class(WC_RIDE); + gfx_invalidate_screen(); + } + + void ExplodeGuests() const + { + int32_t sprite_index; + Peep* peep; + + FOR_ALL_GUESTS (sprite_index, peep) + { + if (scenario_rand_max(6) == 0) + { + peep->peep_flags |= PEEP_FLAGS_EXPLODE; + } + } + } + + void SetStaffSpeed(uint8_t value) const + { + uint16_t spriteIndex; + Peep* peep; + + FOR_ALL_STAFF (spriteIndex, peep) + { + peep->energy = value; + peep->energy_target = value; + } + } + + void OwnAllLand() const + { + const int32_t min = 32; + const int32_t max = gMapSizeUnits - 32; + + for (CoordsXY coords = { min, min }; coords.y <= max; coords.y += 32) + { + for (coords.x = min; coords.x <= max; coords.x += 32) + { + TileElement* surfaceElement = map_get_surface_element_at(coords); + if (surfaceElement == nullptr) + continue; + + // Ignore already owned tiles. + if (surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) + continue; + + int32_t base_z = surfaceElement->base_height; + int32_t destOwnership = check_max_allowable_land_rights_for_tile(coords.x >> 5, coords.y >> 5, base_z); + + // only own tiles that were not set to 0 + if (destOwnership != OWNERSHIP_UNOWNED) + { + surfaceElement->AsSurface()->SetOwnership(destOwnership); + update_park_fences_around_tile(coords); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(coords.x, coords.y, baseHeight, baseHeight + 16); + } + } + } + + // Completely unown peep spawn points + for (const auto& spawn : gPeepSpawns) + { + int32_t x = spawn.x; + int32_t y = spawn.y; + if (x != PEEP_SPAWN_UNDEFINED) + { + TileElement* surfaceElement = map_get_surface_element_at({ x, y }); + surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); + update_park_fences_around_tile({ x, y }); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(x, y, baseHeight, baseHeight + 16); + } + } + + map_count_remaining_land_rights(); + } + + void ParkSetOpen(bool isOpen) const + { + auto parkSetParameter = ParkSetParameterAction(isOpen ? ParkParameter::Open : ParkParameter::Close); + GameActions::ExecuteNested(&parkSetParameter); + } +}; diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index dde2c7b75c..a55bdf8aa5 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -9,6 +9,7 @@ #pragma once +#include "../Cheats.h" #include "../core/MemoryStream.h" #include "../localisation/Localisation.h" #include "../network/NetworkTypes.h" @@ -395,3 +396,23 @@ template<> struct DataSerializerTraits stream->Write(msg, strlen(msg)); } }; + +template<> struct DataSerializerTraits +{ + static void encode(IStream* stream, const NetworkCheatType_t& val) + { + uint32_t temp = ByteSwapBE(val.id); + stream->Write(&temp); + } + static void decode(IStream* stream, NetworkCheatType_t& val) + { + uint32_t temp; + stream->Read(&temp); + val.id = ByteSwapBE(temp); + } + static void log(IStream* stream, const NetworkCheatType_t& val) + { + const char* cheatName = CheatsGetName(static_cast(val.id)); + stream->Write(cheatName, strlen(cheatName)); + } +}; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 8471897f1a..ecb41e51ed 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -18,6 +18,7 @@ #include "../actions/ClimateSetAction.hpp" #include "../actions/RideSetPriceAction.hpp" #include "../actions/RideSetSetting.hpp" +#include "../actions/SetCheatAction.hpp" #include "../actions/StaffSetCostumeAction.hpp" #include "../config/Config.h" #include "../core/Guard.hpp" @@ -753,26 +754,18 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) if (argv[0] == "money" && invalidArguments(&invalidArgs, double_valid[0])) { money32 money = MONEY((int32_t)double_val[0], ((int32_t)(double_val[0] * 100)) % 100); - bool run_get_money = true; if (gCash != money) { - if (game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETMONEY, money, GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // When in networked client mode, console.Execute("get money") - // does not print value accurately. Instead, print the argument. - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - run_get_money = false; - console.WriteFormatLine("money %d.%d0", money / 10, money % 10); - } - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::SetMoney, money); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get money"); + }); + GameActions::Execute(&setCheatAction); } - if (run_get_money) + else { console.Execute("get money"); } @@ -979,57 +972,55 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) { if (gCheatsSandboxMode != (int_val[0] != 0)) { - if (game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_sandbox_mode")" line when in networked client mode - gCheatsSandboxMode = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::SandboxMode, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_sandbox_mode"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_sandbox_mode"); } - console.Execute("get cheat_sandbox_mode"); } else if (argv[0] == "cheat_disable_clearance_checks" && invalidArguments(&invalidArgs, int_valid[0])) { if (gCheatsDisableClearanceChecks != (int_val[0] != 0)) { - if (game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_disable_clearance_checks")" line when in networked client mode - gCheatsDisableClearanceChecks = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::DisableClearanceChecks, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_disable_clearance_checks"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_disable_clearance_checks"); } - console.Execute("get cheat_disable_clearance_checks"); } else if (argv[0] == "cheat_disable_support_limits" && invalidArguments(&invalidArgs, int_valid[0])) { if (gCheatsDisableSupportLimits != (int_val[0] != 0)) { - if (game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_disable_support_limits")" line when in networked client mode - gCheatsDisableSupportLimits = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::DisableSupportLimits, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_disable_support_limits"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_disable_support_limits"); } - console.Execute("get cheat_disable_support_limits"); } else if (argv[0] == "current_rotation" && invalidArguments(&invalidArgs, int_valid[0])) { diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 2c413fa52a..b64b5989bb 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -13,6 +13,7 @@ #include "../Game.h" #include "../Intro.h" #include "../OpenRCT2.h" +#include "../actions/SetCheatAction.hpp" #include "../audio/audio.h" #include "../core/Console.hpp" #include "../core/Imaging.h" @@ -608,27 +609,27 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption if (options->mowed_grass) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_MOWED, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); } if (options->clear_grass || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_CLEAR_0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); } if (options->water_plants || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WATERPLANTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WaterPlants); } if (options->fix_vandalism || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXVANDALISM, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixVandalism); } if (options->remove_litter || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVELITTER, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveLitter); } viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 47448a8558..cced3af44f 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -639,7 +639,7 @@ bool Network::BeginServer(uint16_t port, const std::string& address) ServerProviderEmail = gConfigNetwork.provider_email; ServerProviderWebsite = gConfigNetwork.provider_website; - cheats_reset(); + CheatsReset(); LoadGroups(); BeginChatLog(); BeginServerLog(); diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index 2308662055..2fd6d588e2 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -98,6 +98,7 @@ template struct NetworkObjectId_t // there is no way to specialize templates if they have the exact symbol. using NetworkPlayerId_t = NetworkObjectId_t; using NetworkRideId_t = NetworkObjectId_t; +using NetworkCheatType_t = NetworkObjectId_t; enum NetworkStatisticsGroup { diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index ecebd78f3f..4900cbc203 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -35,6 +35,10 @@ #define PEEP_MIN_ENERGY 32 #define PEEP_MAX_ENERGY 128 #define PEEP_MAX_ENERGY_TARGET 255 // Oddly, this differs from max energy! +#define PEEP_MAX_HUNGER 255 +#define PEEP_MAX_BATHROOM 255 +#define PEEP_MAX_NAUSEA 255 +#define PEEP_MAX_THIRST 255 struct TileElement; struct Ride; From aaebb109e1818f5821d199e5aad291586582440a Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 14:04:20 +0000 Subject: [PATCH 285/506] Update vscode config [ci skip] --- .vscode/c_cpp_properties.json | 3 ++- .vscode/launch.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 807a3b4217..b5a05960bb 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -32,7 +32,8 @@ "/usr/include", "/usr/local/include", "${workspaceRoot}", - "${workspaceRoot}/src" + "${workspaceRoot}/src", + "${workspaceRoot}/bin/googletest-distribution-prefix/src/googletest-distribution/googletest/include/gtest" ], "defines": [], "intelliSenseMode": "clang-x64", diff --git a/.vscode/launch.json b/.vscode/launch.json index d3df614e53..70b2a2c016 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}/bin", "environment": [], - "externalConsole": true, + "externalConsole": false, "setupCommands": [ { "description": "Enable pretty-printing for gdb", From c4a449f47dc4a01fd4eba041f5e8617b05b220bf Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 19:13:18 +0000 Subject: [PATCH 286/506] Add new debugging tab to the Guest window Add a new tab to the Guest window which we can use to display debug information and tools for guests. At the moment it's blank and always visible; next step is to make it only show up when debugging tools are enabled. --- src/openrct2-ui/windows/Guest.cpp | 179 +++++++++++++++++++++++++++--- src/openrct2/interface/Window.h | 3 +- 2 files changed, 165 insertions(+), 17 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 5db28abccf..9c0f2dfbd4 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -36,7 +36,8 @@ enum WINDOW_GUEST_PAGE { WINDOW_GUEST_RIDES, WINDOW_GUEST_FINANCE, WINDOW_GUEST_THOUGHTS, - WINDOW_GUEST_INVENTORY + WINDOW_GUEST_INVENTORY, + WINDOW_GUEST_DEBUG }; enum WINDOW_GUEST_WIDGET_IDX { @@ -50,8 +51,9 @@ enum WINDOW_GUEST_WIDGET_IDX { WIDX_TAB_4, WIDX_TAB_5, WIDX_TAB_6, + WIDX_TAB_7, - WIDX_MARQUEE = 10, + WIDX_MARQUEE = 11, WIDX_VIEWPORT, WIDX_ACTION_LBL, WIDX_PICKUP, @@ -59,7 +61,7 @@ enum WINDOW_GUEST_WIDGET_IDX { WIDX_LOCATE, WIDX_TRACK, - WIDX_RIDE_SCROLL = 10 + WIDX_RIDE_SCROLL = 11 }; validate_global_widx(WC_PEEP, WIDX_PICKUP); @@ -75,6 +77,7 @@ static rct_widget window_guest_overview_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, // Tab 4 {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, // Tab 5 {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, // Tab 6 + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, // Tab 7 {WWT_LABEL_CENTRED, 1, 3, 166, 45, 56, 0xFFFFFFFF, STR_NONE}, // Label Thought marquee {WWT_VIEWPORT, 1, 3, 166, 57, 143, 0xFFFFFFFF, STR_NONE}, // Viewport {WWT_LABEL_CENTRED, 1, 3, 166, 144, 154, 0xFFFFFFFF, STR_NONE}, // Label Action @@ -96,6 +99,7 @@ static rct_widget window_guest_stats_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -110,6 +114,7 @@ static rct_widget window_guest_rides_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WWT_SCROLL, 1, 3, 188, 57, 143, SCROLL_VERTICAL, STR_NONE}, {WIDGETS_END}, }; @@ -125,6 +130,7 @@ static rct_widget window_guest_finance_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -139,6 +145,7 @@ static rct_widget window_guest_thoughts_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -153,6 +160,22 @@ static rct_widget window_guest_inventory_widgets[] = { {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WIDGETS_END}, +}; + +static rct_widget window_guest_debug_widgets[] = { + {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, + {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, + {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, + {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, + {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -163,7 +186,8 @@ static rct_widget *window_guest_page_widgets[] = { window_guest_rides_widgets, window_guest_finance_widgets, window_guest_thoughts_widgets, - window_guest_inventory_widgets + window_guest_inventory_widgets, + window_guest_debug_widgets }; static void window_guest_set_page(rct_window* w, int32_t page); @@ -214,6 +238,10 @@ static void window_guest_inventory_update(rct_window *w); static void window_guest_inventory_invalidate(rct_window *w); static void window_guest_inventory_paint(rct_window *w, rct_drawpixelinfo *dpi); +static void window_guest_debug_resize(rct_window *w); +static void window_guest_debug_invalidate(rct_window *w); +static void window_guest_debug_paint(rct_window *w, rct_drawpixelinfo* dpi); + static rct_window_event_list window_guest_overview_events = { window_guest_overview_close, window_guest_overview_mouse_up, @@ -400,6 +428,37 @@ static rct_window_event_list window_guest_inventory_events = { nullptr }; +static rct_window_event_list window_guest_debug_events = { + nullptr, // void (*close)(struct rct_window*); + window_guest_mouse_up, // void (*mouse_up)(struct rct_window*, rct_widgetindex); + window_guest_debug_resize, // void (*resize)(struct rct_window*); + nullptr, // void (*mouse_down)(struct rct_window*, rct_widgetindex, rct_widget*); + nullptr, // void (*dropdown)(struct rct_window*, rct_widgetindex, int32_t); + window_guest_unknown_05, // void (*unknown_05)(struct rct_window*); + nullptr, // void (*update)(struct rct_window*); + nullptr, // void (*unknown_07)(struct rct_window*); + nullptr, // void (*unknown_08)(struct rct_window*); + nullptr, // void (*tool_update)(struct rct_window*, rct_widgetindex, int32_t, int32_t); + nullptr, // void (*tool_down)(struct rct_window*, rct_widgetindex, int32_t, int32_t); + nullptr, // void (*tool_drag)(struct rct_window*, rct_widgetindex, int32_t, int32_t); + nullptr, // void (*tool_up)(struct rct_window*, rct_widgetindex, int32_t, int32_t); + nullptr, // void (*tool_abort)(struct rct_window*, rct_widgetindex); + nullptr, // void (*unknown_0E)(struct rct_window*); + nullptr, // void (*get_scroll_size)(struct rct_window*, int32_t, int32_t*, int32_t*); + nullptr, // void (*scroll_mousedown)(struct rct_window*, int32_t, int32_t, int32_t); + nullptr, // void (*scroll_mousedrag)(struct rct_window*, int32_t, int32_t, int32_t); + nullptr, // void (*scroll_mouseover)(struct rct_window*, int32_t, int32_t, int32_t); + nullptr, // void (*text_input)(struct rct_window*, rct_widgetindex, char*); + nullptr, // void (*viewport_rotate)(struct rct_window*); + nullptr, // void (*unknown_15)(struct rct_window*, int32_t, int32_t); + nullptr, // void (*tooltip)(struct rct_window*, rct_widgetindex, rct_string_id*); + nullptr, // void (*cursor)(struct rct_window*, rct_widgetindex, int32_t, int32_t, int32_t*); + nullptr, // void (*moved)(struct rct_window*, int32_t, int32_t); + window_guest_debug_invalidate, // void (*invalidate)(struct rct_window*); + window_guest_debug_paint, // void (*paint)(struct rct_window*, rct_drawpixelinfo*); + nullptr // void (*scroll_paint)(struct rct_window*, rct_drawpixelinfo*, int32_t); +}; + // 0x981D24 static rct_window_event_list *window_guest_page_events[] = { &window_guest_overview_events, @@ -407,7 +466,8 @@ static rct_window_event_list *window_guest_page_events[] = { &window_guest_rides_events, &window_guest_finance_events, &window_guest_thoughts_events, - &window_guest_inventory_events + &window_guest_inventory_events, + &window_guest_debug_events }; void window_guest_set_colours(); @@ -421,6 +481,7 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7) | (1 << WIDX_RENAME)| (1 << WIDX_PICKUP)| (1 << WIDX_LOCATE)| @@ -432,7 +493,8 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | - (1 << WIDX_TAB_6), + (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | @@ -441,6 +503,7 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7) | (1 << WIDX_RIDE_SCROLL), (1 << WIDX_CLOSE) | @@ -449,7 +512,8 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | - (1 << WIDX_TAB_6), + (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | @@ -457,7 +521,8 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | - (1 << WIDX_TAB_6), + (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | @@ -465,7 +530,17 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_TAB_5) | - (1 << WIDX_TAB_6) + (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6) | + (1 << WIDX_TAB_7) }; // clang-format on @@ -617,6 +692,7 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex) case WIDX_TAB_4: case WIDX_TAB_5: case WIDX_TAB_6: + case WIDX_TAB_7: window_guest_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_PICKUP: @@ -950,6 +1026,24 @@ static void window_guest_inventory_tab_paint(rct_window* w, rct_drawpixelinfo* d gfx_draw_sprite(dpi, image_id, x, y, 0); } +static void window_guest_debug_tab_paint(rct_window *w, rct_drawpixelinfo* dpi) +{ + if (w->disabled_widgets & (1 << WIDX_TAB_7)) + return; + + rct_widget* widget = &w->widgets[WIDX_TAB_7]; + int32_t x = widget->left + w->x; + int32_t y = widget->top + w->y; + + int32_t image_id = SPR_TAB_GEARS_0; + if (w->page == WINDOW_GUEST_DEBUG) + { + image_id += (w->frame_no / 2) & 0x3; + } + + gfx_draw_sprite(dpi, image_id, x, y, 0); +} + /** * * rct2: 0x696887 @@ -963,6 +1057,7 @@ void window_guest_overview_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); // Draw the viewport no sound sprite if (w->viewport) @@ -1037,7 +1132,7 @@ void window_guest_overview_invalidate(rct_window* w) w->pressed_widgets &= ~( (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_TAB_5) - | (1ULL << WIDX_TAB_6)); + | (1ULL << WIDX_TAB_6) | (1ULL << WIDX_TAB_7)); w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); Peep* peep = GET_PEEP(w->number); @@ -1080,7 +1175,7 @@ void window_guest_overview_invalidate(rct_window* w) window_guest_overview_widgets[WIDX_LOCATE].left = w->width - 25; window_guest_overview_widgets[WIDX_TRACK].left = w->width - 25; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1242,6 +1337,7 @@ void window_guest_mouse_up(rct_window* w, rct_widgetindex widgetIndex) case WIDX_TAB_4: case WIDX_TAB_5: case WIDX_TAB_6: + case WIDX_TAB_7: window_guest_set_page(w, widgetIndex - WIDX_TAB_1); break; } @@ -1307,7 +1403,7 @@ void window_guest_stats_invalidate(rct_window* w) window_guest_stats_widgets[WIDX_CLOSE].left = w->width - 13; window_guest_stats_widgets[WIDX_CLOSE].right = w->width - 3; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1354,6 +1450,7 @@ void window_guest_stats_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); // ebx Peep* peep = GET_PEEP(w->number); @@ -1666,7 +1763,7 @@ void window_guest_rides_invalidate(rct_window* w) window_guest_rides_widgets[WIDX_RIDE_SCROLL].right = w->width - 4; window_guest_rides_widgets[WIDX_RIDE_SCROLL].bottom = w->height - 15; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1682,6 +1779,7 @@ void window_guest_rides_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); Peep* peep = GET_PEEP(w->number); @@ -1796,7 +1894,7 @@ void window_guest_finance_invalidate(rct_window* w) window_guest_finance_widgets[WIDX_CLOSE].left = w->width - 13; window_guest_finance_widgets[WIDX_CLOSE].right = w->width - 3; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1812,6 +1910,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); Peep* peep = GET_PEEP(w->number); @@ -1947,7 +2046,7 @@ void window_guest_thoughts_invalidate(rct_window* w) window_guest_thoughts_widgets[WIDX_CLOSE].left = w->width - 13; window_guest_thoughts_widgets[WIDX_CLOSE].right = w->width - 3; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1963,6 +2062,7 @@ void window_guest_thoughts_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); Peep* peep = GET_PEEP(w->number); @@ -2051,7 +2151,7 @@ void window_guest_inventory_invalidate(rct_window* w) window_guest_inventory_widgets[WIDX_CLOSE].left = w->width - 13; window_guest_inventory_widgets[WIDX_CLOSE].right = w->width - 3; - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_6); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item) @@ -2142,6 +2242,7 @@ void window_guest_inventory_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_finance_tab_paint(w, dpi); window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); const auto guest = (GET_PEEP(w->number))->AsGuest(); if (guest != nullptr) @@ -2175,3 +2276,49 @@ void window_guest_inventory_paint(rct_window* w, rct_drawpixelinfo* dpi) } } } + +void window_guest_debug_resize(rct_window* w) +{ + window_set_resize(w, 192, 159, 500, 450); +} + +void window_guest_debug_invalidate(rct_window* w) +{ + if (window_guest_page_widgets[w->page] != w->widgets) + { + w->widgets = window_guest_page_widgets[w->page]; + window_init_scroll_widgets(w); + } + + w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); + + rct_peep* peep = GET_PEEP(w->number); + + set_format_arg(0, rct_string_id, peep->name_string_idx); + set_format_arg(2, uint32_t, peep->id); + + window_guest_debug_widgets[WIDX_BACKGROUND].right = w->width - 1; + window_guest_debug_widgets[WIDX_BACKGROUND].bottom = w->height - 1; + + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; + + window_guest_debug_widgets[WIDX_TITLE].right = w->width - 2; + + window_guest_debug_widgets[WIDX_CLOSE].left = w->width - 13; + window_guest_debug_widgets[WIDX_CLOSE].right = w->width - 3; + + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); +} + +void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) +{ + window_draw_widgets(w, dpi); + window_guest_overview_tab_paint(w, dpi); + window_guest_stats_tab_paint(w, dpi); + window_guest_rides_tab_paint(w, dpi); + window_guest_finance_tab_paint(w, dpi); + window_guest_thoughts_tab_paint(w, dpi); + window_guest_inventory_tab_paint(w, dpi); + window_guest_debug_tab_paint(w, dpi); +} diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 613109b785..b6a0e24ec8 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -489,7 +489,8 @@ enum #define WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON 25 #define WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON 30 #define WC_PEEP__WIDX_PATROL 11 -#define WC_PEEP__WIDX_PICKUP 13 +#define WC_PEEP__WIDX_ACTION_LBL 13 +#define WC_PEEP__WIDX_PICKUP 14 #define WC_TRACK_DESIGN_LIST__WIDX_ROTATE 8 #define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3 #define WC_MAP__WIDX_ROTATE_90 20 From fa63691d17f6336c82274bf199bda94324eae1b1 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 19:18:07 +0000 Subject: [PATCH 287/506] Disable guest debug tab when debug tools not turned on Disable the debug tab in the guest window when the debugging tools are not turned on, causing it to be completely hidden from view. --- src/openrct2-ui/windows/Guest.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 9c0f2dfbd4..f6933c4f2c 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -623,6 +623,10 @@ void window_guest_disable_widgets(rct_window* w) { disabled_widgets |= (1 << WIDX_TAB_4); // Disable finance tab if no money } + if (!gConfigGeneral.debugging_tools) + { + disabled_widgets |= (1 << WIDX_TAB_7); // Disable debug tab when debug tools not turned on + } w->disabled_widgets = disabled_widgets; } From 5ef07ab9360820ed6e2263c4bcd463beaed84ed4 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 19:18:14 +0000 Subject: [PATCH 288/506] Formatting --- src/openrct2-ui/windows/Guest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index f6933c4f2c..8d0310797d 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1030,7 +1030,7 @@ static void window_guest_inventory_tab_paint(rct_window* w, rct_drawpixelinfo* d gfx_draw_sprite(dpi, image_id, x, y, 0); } -static void window_guest_debug_tab_paint(rct_window *w, rct_drawpixelinfo* dpi) +static void window_guest_debug_tab_paint(rct_window* w, rct_drawpixelinfo* dpi) { if (w->disabled_widgets & (1 << WIDX_TAB_7)) return; From 70c61d5ac69cf793a63ca4c9a66c317fbd873e97 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 19:40:11 +0000 Subject: [PATCH 289/506] Fix guest window width for debugging tab Introduce a named constant for the width of a tab in the Guest window, and touch the places that set the window width to add it to the minimum window width when the debugging tab is enabled, so that the tab doesn't render off the side of the window. --- src/openrct2-ui/windows/Guest.cpp | 121 ++++++++++++++++-------------- 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 8d0310797d..1ee0d34c19 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -66,18 +66,20 @@ enum WINDOW_GUEST_WIDGET_IDX { validate_global_widx(WC_PEEP, WIDX_PICKUP); +static const int32_t TabWidth = 30; + static rct_widget window_guest_overview_widgets[] = { {WWT_FRAME, 0, 0, 191, 0, 156, 0xFFFFFFFF, STR_NONE}, // Panel / Background {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, // Title {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, // Close x button {WWT_RESIZE, 1, 0, 191, 43, 156, 0xFFFFFFFF, STR_NONE}, // Resize - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, // Tab 1 - {WWT_TAB, 1, 73, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, // Tab 2 - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, // Tab 3 - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, // Tab 4 - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, // Tab 5 - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, // Tab 6 - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, // Tab 7 + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, // Tab 1 + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, // Tab 2 + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, // Tab 3 + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, // Tab 4 + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, // Tab 5 + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, // Tab 6 + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, // Tab 7 {WWT_LABEL_CENTRED, 1, 3, 166, 45, 56, 0xFFFFFFFF, STR_NONE}, // Label Thought marquee {WWT_VIEWPORT, 1, 3, 166, 57, 143, 0xFFFFFFFF, STR_NONE}, // Viewport {WWT_LABEL_CENTRED, 1, 3, 166, 144, 154, 0xFFFFFFFF, STR_NONE}, // Label Action @@ -93,13 +95,13 @@ static rct_widget window_guest_stats_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -108,13 +110,13 @@ static rct_widget window_guest_rides_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WWT_SCROLL, 1, 3, 188, 57, 143, SCROLL_VERTICAL, STR_NONE}, {WIDGETS_END}, }; @@ -124,13 +126,13 @@ static rct_widget window_guest_finance_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -139,13 +141,13 @@ static rct_widget window_guest_thoughts_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -154,13 +156,13 @@ static rct_widget window_guest_inventory_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -169,13 +171,13 @@ static rct_widget window_guest_debug_widgets[] = { {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, + {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, + {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, + {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, + {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, + {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, + {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, + {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, {WIDGETS_END}, }; @@ -561,7 +563,8 @@ rct_window* window_guest_open(Peep* peep) window = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index); if (window == nullptr) { - window = window_create_auto_pos(192, 157, &window_guest_overview_events, WC_PEEP, WF_RESIZABLE); + window = window_create_auto_pos( + 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 157, &window_guest_overview_events, WC_PEEP, WF_RESIZABLE); window->widgets = window_guest_overview_widgets; window->enabled_widgets = window_guest_page_enabled_widgets[0]; window->number = peep->sprite_index; @@ -572,7 +575,7 @@ rct_window* window_guest_open(Peep* peep) window->picked_peep_frame = 0; window->highlighted_item = 0; window_guest_disable_widgets(window); - window->min_width = 192; + window->min_width = 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0); window->min_height = 157; window->max_width = 500; window->max_height = 450; @@ -654,7 +657,7 @@ void window_guest_overview_resize(rct_window* w) widget_invalidate(w, WIDX_MARQUEE); - window_set_resize(w, 192, 159, 500, 450); + window_set_resize(w, 192 + gConfigGeneral.debugging_tools ? TabWidth : 0, 159, 500, 450); rct_viewport* view = w->viewport; @@ -1353,7 +1356,8 @@ void window_guest_mouse_up(rct_window* w, rct_widgetindex widgetIndex) */ void window_guest_stats_resize(rct_window* w) { - window_set_resize(w, 192, 180, 192, 180); + const int32_t fixedWidth = 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0); + window_set_resize(w, fixedWidth, 180, fixedWidth, 180); } /** @@ -1627,7 +1631,7 @@ void window_guest_stats_paint(rct_window* w, rct_drawpixelinfo* dpi) */ void window_guest_rides_resize(rct_window* w) { - window_set_resize(w, 192, 128, 500, 400); + window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 128, 500, 400); } /** @@ -1853,7 +1857,8 @@ void window_guest_rides_scroll_paint(rct_window* w, rct_drawpixelinfo* dpi, int3 */ void window_guest_finance_resize(rct_window* w) { - window_set_resize(w, 210, 148, 210, 148); + int32_t fixedWidth = 210 + (gConfigGeneral.debugging_tools ? TabWidth : 0); + window_set_resize(w, fixedWidth, 148, fixedWidth, 148); } /** @@ -2005,7 +2010,7 @@ void window_guest_thoughts_resize(rct_window* w) window_invalidate(w); } - window_set_resize(w, 192, 159, 500, 450); + window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); } /** @@ -2110,7 +2115,7 @@ void window_guest_inventory_resize(rct_window* w) window_invalidate(w); } - window_set_resize(w, 192, 159, 500, 450); + window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); } /** @@ -2283,7 +2288,7 @@ void window_guest_inventory_paint(rct_window* w, rct_drawpixelinfo* dpi) void window_guest_debug_resize(rct_window* w) { - window_set_resize(w, 192, 159, 500, 450); + window_set_resize(w, 192 + TabWidth, 159, 500, 450); } void window_guest_debug_invalidate(rct_window* w) From 7300a38ce67a320ee0e21c985804c99b5a14acc2 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 19:58:23 +0000 Subject: [PATCH 290/506] Show peep coordinates in debug tab As a first debug stat to show, display a peep's current coordinates in the debug tab --- src/openrct2-ui/windows/Guest.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 1ee0d34c19..9f3b7c8054 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2330,4 +2330,16 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_thoughts_tab_paint(w, dpi); window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); + + rct_peep* peep = GET_PEEP(w->number); + + // cx + int32_t x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; + // dx + int32_t y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; + + char buffer[4096]; + snprintf(buffer, 4096, "Position: %i, %i, %i", peep->x, peep->y, peep->z); + gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; } From 8bf72ceadbb3820e8aaee947bf3cdb40f2f8bd05 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Tue, 1 Jan 2019 20:36:31 +0000 Subject: [PATCH 291/506] More peep pathing info Show more peep debug data in the Guest debug tab, mostly to help with understanding pathfinding behaviour. --- src/openrct2-ui/windows/Guest.cpp | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 9f3b7c8054..fe3d3c1d0b 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2342,4 +2342,37 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) snprintf(buffer, 4096, "Position: %i, %i, %i", peep->x, peep->y, peep->z); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; + + snprintf(buffer, 4096, "Next: %i, %i, %i", peep->next_x, peep->next_y, peep->next_z); + if (peep->GetNextIsSurface()) + strcat_s(buffer, " (surface)"); + if (peep->GetNextIsSloped()) + { + strcat_s(buffer, " (slope "); + char slopeDir[10]; + _itoa(peep->GetNextDirection(), slopeDir, 10); + strcat_s(buffer, slopeDir); + strcat_s(buffer, ")"); + } + gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; + + snprintf(buffer, 4096, "Dest: %i, %i, tolerance %i", peep->destination_x, peep->destination_y, peep->destination_tolerance); + gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; + + snprintf(buffer, 4096, "Pathfind Goal: %i, %i, %i dir %i", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, peep->pathfind_goal.direction); + gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; + + gfx_draw_string(dpi, "Pathfind history:", COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; + + x += 10; + for (auto& point : peep->pathfind_history) { + snprintf(buffer, 4096, "%i, %i, %i dir %i", point.x, point.y, point.z, point.direction); + gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + y += LIST_ROW_HEIGHT; + } + x -= 10; } From cfda3fb8f77b8564054ec2a8854e2e2db40b634d Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 12:50:43 +0000 Subject: [PATCH 292/506] Use sizeof(buffer) instead of hardcoded size Use sizeof(buffer) instead of repeating 4096 in a bunch of places. Also, 4096 was maybe a bit overkill, drop it down to 512 instead. --- src/openrct2-ui/windows/Guest.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index fe3d3c1d0b..1b0c637696 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2338,12 +2338,12 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) // dx int32_t y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; - char buffer[4096]; - snprintf(buffer, 4096, "Position: %i, %i, %i", peep->x, peep->y, peep->z); + char buffer[512]; + snprintf(buffer, sizeof(buffer), "Position: %i, %i, %i", peep->x, peep->y, peep->z); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; - snprintf(buffer, 4096, "Next: %i, %i, %i", peep->next_x, peep->next_y, peep->next_z); + snprintf(buffer, sizeof(buffer), "Next: %i, %i, %i", peep->next_x, peep->next_y, peep->next_z); if (peep->GetNextIsSurface()) strcat_s(buffer, " (surface)"); if (peep->GetNextIsSloped()) @@ -2357,11 +2357,15 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; - snprintf(buffer, 4096, "Dest: %i, %i, tolerance %i", peep->destination_x, peep->destination_y, peep->destination_tolerance); + snprintf( + buffer, sizeof(buffer), "Dest: %i, %i, tolerance %i", peep->destination_x, peep->destination_y, + peep->destination_tolerance); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; - snprintf(buffer, 4096, "Pathfind Goal: %i, %i, %i dir %i", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, peep->pathfind_goal.direction); + snprintf( + buffer, sizeof(buffer), "Pathfind Goal: %i, %i, %i dir %i", peep->pathfind_goal.x, peep->pathfind_goal.y, + peep->pathfind_goal.z, peep->pathfind_goal.direction); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; @@ -2370,7 +2374,7 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) x += 10; for (auto& point : peep->pathfind_history) { - snprintf(buffer, 4096, "%i, %i, %i dir %i", point.x, point.y, point.z, point.direction); + snprintf(buffer, sizeof(buffer), "%i, %i, %i dir %i", point.x, point.y, point.z, point.direction); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } From 397b0445887ce393ff7cc2f85f4951ed2da1b3a4 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 12:53:08 +0000 Subject: [PATCH 293/506] Use safe_strcat instead of strcat_s strcat_s is not available on all platforms, and we have a utility in the codebase that does basically the same thing already. --- src/openrct2-ui/windows/Guest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 1b0c637696..0e49738ab2 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2345,14 +2345,14 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) snprintf(buffer, sizeof(buffer), "Next: %i, %i, %i", peep->next_x, peep->next_y, peep->next_z); if (peep->GetNextIsSurface()) - strcat_s(buffer, " (surface)"); + safe_strcat(buffer, " (surface)", sizeof(buffer)); if (peep->GetNextIsSloped()) { - strcat_s(buffer, " (slope "); + safe_strcat(buffer, " (slope ", sizeof(buffer)); char slopeDir[10]; _itoa(peep->GetNextDirection(), slopeDir, 10); - strcat_s(buffer, slopeDir); - strcat_s(buffer, ")"); + safe_strcat(buffer, slopeDir, sizeof(buffer)); + safe_strcat(buffer, ")", sizeof(buffer)); } gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; From 97bcc53637f875d397d56781ed8178514bab432f Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 13:01:48 +0000 Subject: [PATCH 294/506] Eliminate itoa and use correct format specifiers Use snprintf instead of _itoa as it's not available on all platforms. Also change the format specifies for unsigned variables to %u instead of %i, to be more correct... --- src/openrct2-ui/windows/Guest.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 0e49738ab2..6067940399 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2343,28 +2343,26 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; - snprintf(buffer, sizeof(buffer), "Next: %i, %i, %i", peep->next_x, peep->next_y, peep->next_z); + snprintf(buffer, sizeof(buffer), "Next: %u, %u, %u", peep->next_x, peep->next_y, peep->next_z); if (peep->GetNextIsSurface()) safe_strcat(buffer, " (surface)", sizeof(buffer)); if (peep->GetNextIsSloped()) { - safe_strcat(buffer, " (slope ", sizeof(buffer)); - char slopeDir[10]; - _itoa(peep->GetNextDirection(), slopeDir, 10); - safe_strcat(buffer, slopeDir, sizeof(buffer)); - safe_strcat(buffer, ")", sizeof(buffer)); + char slopeBuf[32]; + snprintf(slopeBuf, sizeof(slopeBuf), " (slope %u)", peep->GetNextDirection()); + safe_strcat(buffer, slopeBuf, sizeof(buffer)); } gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "Dest: %i, %i, tolerance %i", peep->destination_x, peep->destination_y, + buffer, sizeof(buffer), "Dest: %u, %u, tolerance %u", peep->destination_x, peep->destination_y, peep->destination_tolerance); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "Pathfind Goal: %i, %i, %i dir %i", peep->pathfind_goal.x, peep->pathfind_goal.y, + buffer, sizeof(buffer), "Pathfind Goal: %u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, peep->pathfind_goal.direction); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; @@ -2373,8 +2371,9 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) y += LIST_ROW_HEIGHT; x += 10; - for (auto& point : peep->pathfind_history) { - snprintf(buffer, sizeof(buffer), "%i, %i, %i dir %i", point.x, point.y, point.z, point.direction); + for (auto& point : peep->pathfind_history) + { + snprintf(buffer, sizeof(buffer), "%u, %u, %u dir %u", point.x, point.y, point.z, point.direction); gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } From b714f7b0e2093369bbecc9b76ea6e92a2b889aa9 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 13:09:58 +0000 Subject: [PATCH 295/506] Use constexpr instead of const For a static constant integer value, it's stylistically clearer to use constexpr instead of const. The resulting variable is implicitly const, but is also guaranteed to have a compile-time-computable value. --- src/openrct2-ui/windows/Guest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 6067940399..df7bdef750 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -66,7 +66,7 @@ enum WINDOW_GUEST_WIDGET_IDX { validate_global_widx(WC_PEEP, WIDX_PICKUP); -static const int32_t TabWidth = 30; +static constexpr int32_t TabWidth = 30; static rct_widget window_guest_overview_widgets[] = { {WWT_FRAME, 0, 0, 191, 0, 156, 0xFFFFFFFF, STR_NONE}, // Panel / Background From 9bb68a715108feb78c859bd552f260eba0565214 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 13:14:57 +0000 Subject: [PATCH 296/506] Pull window width into temporary variable As suggested in review, it's a little easier to read this way. --- src/openrct2-ui/windows/Guest.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index df7bdef750..3ea426786e 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -563,8 +563,11 @@ rct_window* window_guest_open(Peep* peep) window = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index); if (window == nullptr) { - window = window_create_auto_pos( - 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 157, &window_guest_overview_events, WC_PEEP, WF_RESIZABLE); + int32_t windowWidth = 192; + if (gConfigGeneral.debugging_tools) + windowWidth += TabWidth; + + window = window_create_auto_pos(windowWidth, 157, &window_guest_overview_events, WC_PEEP, WF_RESIZABLE); window->widgets = window_guest_overview_widgets; window->enabled_widgets = window_guest_page_enabled_widgets[0]; window->number = peep->sprite_index; @@ -575,7 +578,7 @@ rct_window* window_guest_open(Peep* peep) window->picked_peep_frame = 0; window->highlighted_item = 0; window_guest_disable_widgets(window); - window->min_width = 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0); + window->min_width = windowWidth; window->min_height = 157; window->max_width = 500; window->max_height = 450; From 480f19c0c6d896130cb0ad0b56330a1383df633b Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 13:46:05 +0000 Subject: [PATCH 297/506] Add parens to fix operator precedence issue I missed one... thankfully the CI did not. --- src/openrct2-ui/windows/Guest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 3ea426786e..69377c1bb5 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -660,7 +660,7 @@ void window_guest_overview_resize(rct_window* w) widget_invalidate(w, WIDX_MARQUEE); - window_set_resize(w, 192 + gConfigGeneral.debugging_tools ? TabWidth : 0, 159, 500, 450); + window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); rct_viewport* view = w->viewport; From b4a2a94520a5e93c772b899d9aa59c395d4e3a78 Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 2 May 2019 20:56:03 +0000 Subject: [PATCH 298/506] Fix build --- src/openrct2-ui/windows/Guest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 69377c1bb5..be92edddb8 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2304,7 +2304,7 @@ void window_guest_debug_invalidate(rct_window* w) w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - rct_peep* peep = GET_PEEP(w->number); + auto peep = GET_PEEP(w->number); set_format_arg(0, rct_string_id, peep->name_string_idx); set_format_arg(2, uint32_t, peep->id); @@ -2334,7 +2334,7 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_inventory_tab_paint(w, dpi); window_guest_debug_tab_paint(w, dpi); - rct_peep* peep = GET_PEEP(w->number); + auto peep = GET_PEEP(w->number); // cx int32_t x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; From 1d296242b4665ba690fa3edb9cdd88b78a5a5033 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 3 May 2019 00:18:14 +0000 Subject: [PATCH 299/506] Improve text colour --- data/language/en-GB.txt | 1 + src/openrct2-ui/windows/Guest.cpp | 40 +++++++++++++++------------ src/openrct2/localisation/StringIds.h | 2 ++ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index f3a3f8b9f2..accce90de3 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3757,6 +3757,7 @@ STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to re STR_6307 :Colour scheme: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Reconnect +STR_6310 :{WINDOW_COLOUR_2}{STRING}: {BLACK}{STRING} ############# # Scenarios # diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index be92edddb8..5dbde18e6d 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2323,6 +2323,12 @@ void window_guest_debug_invalidate(rct_window* w) window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } +static void draw_debug_label(rct_drawpixelinfo* dpi, int32_t x, int32_t y, const char* label, const char* value) +{ + const char* args[2] = { label, value }; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_LABEL, args, 0, x, y); +} + void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) { window_draw_widgets(w, dpi); @@ -2335,49 +2341,47 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) window_guest_debug_tab_paint(w, dpi); auto peep = GET_PEEP(w->number); + auto x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; + auto y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; - // cx - int32_t x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; - // dx - int32_t y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; - - char buffer[512]; - snprintf(buffer, sizeof(buffer), "Position: %i, %i, %i", peep->x, peep->y, peep->z); - gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + char buffer[512]{}; + snprintf(buffer, sizeof(buffer), "%i, %i, %i", peep->x, peep->y, peep->z); + draw_debug_label(dpi, x, y, "Position", buffer); y += LIST_ROW_HEIGHT; - snprintf(buffer, sizeof(buffer), "Next: %u, %u, %u", peep->next_x, peep->next_y, peep->next_z); + snprintf(buffer, sizeof(buffer), "%u, %u, %u", peep->next_x, peep->next_y, peep->next_z); if (peep->GetNextIsSurface()) safe_strcat(buffer, " (surface)", sizeof(buffer)); if (peep->GetNextIsSloped()) { - char slopeBuf[32]; + char slopeBuf[32]{}; snprintf(slopeBuf, sizeof(slopeBuf), " (slope %u)", peep->GetNextDirection()); safe_strcat(buffer, slopeBuf, sizeof(buffer)); } - gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + draw_debug_label(dpi, x, y, "Next", buffer); y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "Dest: %u, %u, tolerance %u", peep->destination_x, peep->destination_y, + buffer, sizeof(buffer), "%u, %u, tolerance %u", peep->destination_x, peep->destination_y, peep->destination_tolerance); - gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + draw_debug_label(dpi, x, y, "Dest", buffer); y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "Pathfind Goal: %u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, + buffer, sizeof(buffer), "%u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, peep->pathfind_goal.direction); - gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + draw_debug_label(dpi, x, y, "Pathfind Goal", buffer); y += LIST_ROW_HEIGHT; - gfx_draw_string(dpi, "Pathfind history:", COLOUR_BLACK, x, y); + draw_debug_label(dpi, x, y, "Pathfind history", nullptr); y += LIST_ROW_HEIGHT; x += 10; for (auto& point : peep->pathfind_history) { - snprintf(buffer, sizeof(buffer), "%u, %u, %u dir %u", point.x, point.y, point.z, point.direction); - gfx_draw_string(dpi, buffer, COLOUR_BLACK, x, y); + auto o = utf8_insert_codepoint(buffer, FORMAT_BLACK); + snprintf(buffer + o, sizeof(buffer) - o, "%u, %u, %u dir %u", point.x, point.y, point.z, point.direction); + gfx_draw_string(dpi, buffer, PALETTE_INDEX_10, x, y); y += LIST_ROW_HEIGHT; } x -= 10; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 7c017ff11e..79d4a7f15b 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3943,6 +3943,8 @@ enum STR_MULTIPLAYER_RECONNECT = 6309, + STR_PEEP_DEBUG_LABEL = 6310, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; From c13bd049541cc6531d9949df10d4804822943fa3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 14:40:45 +0000 Subject: [PATCH 300/506] Refactor invalidate methods --- src/openrct2-ui/windows/Guest.cpp | 208 +++++------------------------- 1 file changed, 33 insertions(+), 175 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 5dbde18e6d..e896be8e48 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -604,6 +604,31 @@ rct_window* window_guest_open(Peep* peep) return window; } +static void window_guest_common_invalidate(rct_window* w) +{ + if (window_guest_page_widgets[w->page] != w->widgets) + { + w->widgets = window_guest_page_widgets[w->page]; + window_init_scroll_widgets(w); + } + + w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); + + auto peep = GET_PEEP(w->number); + set_format_arg(0, rct_string_id, peep->name_string_idx); + set_format_arg(2, uint32_t, peep->id); + + w->widgets[WIDX_BACKGROUND].right = w->width - 1; + w->widgets[WIDX_BACKGROUND].bottom = w->height - 1; + w->widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; + w->widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; + w->widgets[WIDX_TITLE].right = w->width - 2; + w->widgets[WIDX_CLOSE].left = w->width - 13; + w->widgets[WIDX_CLOSE].right = w->width - 3; + + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); +} + /** * Disables the finance tab when no money. * Disables peep pickup when in certain no pickup states. @@ -1134,38 +1159,15 @@ void window_guest_overview_paint(rct_window* w, rct_drawpixelinfo* dpi) */ void window_guest_overview_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets &= ~( - (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_TAB_5) - | (1ULL << WIDX_TAB_6) | (1ULL << WIDX_TAB_7)); - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); + window_guest_common_invalidate(w); + auto peep = GET_PEEP(w->number); w->pressed_widgets &= ~(1 << WIDX_TRACK); if (peep->peep_flags & PEEP_FLAGS_TRACKING) { w->pressed_widgets |= (1 << WIDX_TRACK); } - window_guest_overview_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_overview_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_overview_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_overview_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_overview_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_overview_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_overview_widgets[WIDX_CLOSE].right = w->width - 3; - window_guest_overview_widgets[WIDX_VIEWPORT].right = w->width - 26; window_guest_overview_widgets[WIDX_VIEWPORT].bottom = w->height - 14; @@ -1184,8 +1186,6 @@ void window_guest_overview_invalidate(rct_window* w) window_guest_overview_widgets[WIDX_RENAME].left = w->width - 25; window_guest_overview_widgets[WIDX_LOCATE].left = w->width - 25; window_guest_overview_widgets[WIDX_TRACK].left = w->width - 25; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1391,30 +1391,7 @@ void window_guest_stats_update(rct_window* w) */ void window_guest_stats_invalidate(rct_window* w) { - if (w->widgets != window_guest_page_widgets[w->page]) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_stats_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_stats_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_stats_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_stats_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_stats_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_stats_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_stats_widgets[WIDX_CLOSE].right = w->width - 3; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); + window_guest_common_invalidate(w); } /** @@ -1748,33 +1725,10 @@ void window_guest_rides_scroll_mouse_over(rct_window* w, int32_t scrollIndex, in */ void window_guest_rides_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - set_format_arg(0, uint16_t, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_rides_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_rides_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_rides_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_rides_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_rides_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_rides_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_rides_widgets[WIDX_CLOSE].right = w->width - 3; + window_guest_common_invalidate(w); window_guest_rides_widgets[WIDX_RIDE_SCROLL].right = w->width - 4; window_guest_rides_widgets[WIDX_RIDE_SCROLL].bottom = w->height - 15; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); } /** @@ -1882,31 +1836,7 @@ void window_guest_finance_update(rct_window* w) */ void window_guest_finance_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_finance_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_finance_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_finance_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_finance_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_finance_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_finance_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_finance_widgets[WIDX_CLOSE].right = w->width - 3; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); + window_guest_common_invalidate(w); } /** @@ -2034,31 +1964,7 @@ void window_guest_thoughts_update(rct_window* w) */ void window_guest_thoughts_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_thoughts_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_thoughts_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_thoughts_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_thoughts_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_thoughts_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_thoughts_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_thoughts_widgets[WIDX_CLOSE].right = w->width - 3; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); + window_guest_common_invalidate(w); } /** @@ -2139,31 +2045,7 @@ void window_guest_inventory_update(rct_window* w) */ void window_guest_inventory_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - Peep* peep = GET_PEEP(w->number); - - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_inventory_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_inventory_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_inventory_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_inventory_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_inventory_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_inventory_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_inventory_widgets[WIDX_CLOSE].right = w->width - 3; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); + window_guest_common_invalidate(w); } static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item) @@ -2296,31 +2178,7 @@ void window_guest_debug_resize(rct_window* w) void window_guest_debug_invalidate(rct_window* w) { - if (window_guest_page_widgets[w->page] != w->widgets) - { - w->widgets = window_guest_page_widgets[w->page]; - window_init_scroll_widgets(w); - } - - w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1); - - auto peep = GET_PEEP(w->number); - - set_format_arg(0, rct_string_id, peep->name_string_idx); - set_format_arg(2, uint32_t, peep->id); - - window_guest_debug_widgets[WIDX_BACKGROUND].right = w->width - 1; - window_guest_debug_widgets[WIDX_BACKGROUND].bottom = w->height - 1; - - window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; - window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; - - window_guest_debug_widgets[WIDX_TITLE].right = w->width - 2; - - window_guest_debug_widgets[WIDX_CLOSE].left = w->width - 13; - window_guest_debug_widgets[WIDX_CLOSE].right = w->width - 3; - - window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_7); + window_guest_common_invalidate(w); } static void draw_debug_label(rct_drawpixelinfo* dpi, int32_t x, int32_t y, const char* label, const char* value) From 7c2708746e18cb0790b1beffe8cf26c6a5edc210 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 14:53:25 +0000 Subject: [PATCH 301/506] Re-draw debug tab every tick --- src/openrct2-ui/windows/Guest.cpp | 87 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index e896be8e48..7f2d3672ed 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -209,7 +209,6 @@ static void window_guest_overview_tool_down(rct_window* w, rct_widgetindex widge static void window_guest_overview_tool_abort(rct_window *w, rct_widgetindex widgetIndex); static void window_guest_mouse_up(rct_window *w, rct_widgetindex widgetIndex); -static void window_guest_unknown_05(rct_window *w); static void window_guest_stats_resize(rct_window *w); static void window_guest_stats_update(rct_window *w); @@ -241,6 +240,7 @@ static void window_guest_inventory_invalidate(rct_window *w); static void window_guest_inventory_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_guest_debug_resize(rct_window *w); +static void window_guest_debug_update(rct_window *w); static void window_guest_debug_invalidate(rct_window *w); static void window_guest_debug_paint(rct_window *w, rct_drawpixelinfo* dpi); @@ -281,7 +281,7 @@ static rct_window_event_list window_guest_stats_events = { window_guest_stats_resize, nullptr, nullptr, - window_guest_unknown_05, + nullptr, window_guest_stats_update, nullptr, nullptr, @@ -312,7 +312,7 @@ static rct_window_event_list window_guest_rides_events = { window_guest_rides_resize, nullptr, nullptr, - window_guest_unknown_05, + nullptr, window_guest_rides_update, nullptr, nullptr, @@ -343,7 +343,7 @@ static rct_window_event_list window_guest_finance_events = { window_guest_finance_resize, nullptr, nullptr, - window_guest_unknown_05, + nullptr, window_guest_finance_update, nullptr, nullptr, @@ -374,7 +374,7 @@ static rct_window_event_list window_guest_thoughts_events = { window_guest_thoughts_resize, nullptr, nullptr, - window_guest_unknown_05, + nullptr, window_guest_thoughts_update, nullptr, nullptr, @@ -405,7 +405,7 @@ static rct_window_event_list window_guest_inventory_events = { window_guest_inventory_resize, nullptr, nullptr, - window_guest_unknown_05, + nullptr, window_guest_inventory_update, nullptr, nullptr, @@ -431,34 +431,34 @@ static rct_window_event_list window_guest_inventory_events = { }; static rct_window_event_list window_guest_debug_events = { - nullptr, // void (*close)(struct rct_window*); - window_guest_mouse_up, // void (*mouse_up)(struct rct_window*, rct_widgetindex); - window_guest_debug_resize, // void (*resize)(struct rct_window*); - nullptr, // void (*mouse_down)(struct rct_window*, rct_widgetindex, rct_widget*); - nullptr, // void (*dropdown)(struct rct_window*, rct_widgetindex, int32_t); - window_guest_unknown_05, // void (*unknown_05)(struct rct_window*); - nullptr, // void (*update)(struct rct_window*); - nullptr, // void (*unknown_07)(struct rct_window*); - nullptr, // void (*unknown_08)(struct rct_window*); - nullptr, // void (*tool_update)(struct rct_window*, rct_widgetindex, int32_t, int32_t); - nullptr, // void (*tool_down)(struct rct_window*, rct_widgetindex, int32_t, int32_t); - nullptr, // void (*tool_drag)(struct rct_window*, rct_widgetindex, int32_t, int32_t); - nullptr, // void (*tool_up)(struct rct_window*, rct_widgetindex, int32_t, int32_t); - nullptr, // void (*tool_abort)(struct rct_window*, rct_widgetindex); - nullptr, // void (*unknown_0E)(struct rct_window*); - nullptr, // void (*get_scroll_size)(struct rct_window*, int32_t, int32_t*, int32_t*); - nullptr, // void (*scroll_mousedown)(struct rct_window*, int32_t, int32_t, int32_t); - nullptr, // void (*scroll_mousedrag)(struct rct_window*, int32_t, int32_t, int32_t); - nullptr, // void (*scroll_mouseover)(struct rct_window*, int32_t, int32_t, int32_t); - nullptr, // void (*text_input)(struct rct_window*, rct_widgetindex, char*); - nullptr, // void (*viewport_rotate)(struct rct_window*); - nullptr, // void (*unknown_15)(struct rct_window*, int32_t, int32_t); - nullptr, // void (*tooltip)(struct rct_window*, rct_widgetindex, rct_string_id*); - nullptr, // void (*cursor)(struct rct_window*, rct_widgetindex, int32_t, int32_t, int32_t*); - nullptr, // void (*moved)(struct rct_window*, int32_t, int32_t); - window_guest_debug_invalidate, // void (*invalidate)(struct rct_window*); - window_guest_debug_paint, // void (*paint)(struct rct_window*, rct_drawpixelinfo*); - nullptr // void (*scroll_paint)(struct rct_window*, rct_drawpixelinfo*, int32_t); + nullptr, + window_guest_mouse_up, + window_guest_debug_resize, + nullptr, + nullptr, + nullptr, + window_guest_debug_update, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + window_guest_debug_invalidate, + window_guest_debug_paint, + nullptr }; // 0x981D24 @@ -1363,15 +1363,6 @@ void window_guest_stats_resize(rct_window* w) window_set_resize(w, fixedWidth, 180, fixedWidth, 180); } -/** - * This is a combination of 5 functions that were identical - * rct2: 0x6974ED, 0x00697959, 0x00697C7B, 0x00697ED2, 0x00698333 - */ -void window_guest_unknown_05(rct_window* w) -{ - widget_invalidate(w, WIDX_TAB_1); -} - /** * * rct2: 0x69746A @@ -2176,6 +2167,16 @@ void window_guest_debug_resize(rct_window* w) window_set_resize(w, 192 + TabWidth, 159, 500, 450); } +/** + * + * rct2: 0x00698315 + */ +void window_guest_debug_update(rct_window* w) +{ + w->frame_no++; + window_invalidate(w); +} + void window_guest_debug_invalidate(rct_window* w) { window_guest_common_invalidate(w); From a90a86562ddccf4198323e433c2e04abc86807b3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 15:01:51 +0000 Subject: [PATCH 302/506] Refactor guest widget lists --- src/openrct2-ui/windows/Guest.cpp | 132 +++++++++--------------------- 1 file changed, 37 insertions(+), 95 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 7f2d3672ed..607a79c84f 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -68,117 +68,60 @@ validate_global_widx(WC_PEEP, WIDX_PICKUP); static constexpr int32_t TabWidth = 30; +#define MAIN_GUEST_WIDGETS \ + { WWT_FRAME, 0, 0, 191, 0, 156, 0xFFFFFFFF, STR_NONE }, /* Panel / Background */ \ + { WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP }, /* Title */ \ + { WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, /* Close x button */ \ + { WWT_RESIZE, 1, 0, 191, 43, 156, 0xFFFFFFFF, STR_NONE }, /* Resize */ \ + { WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP }, /* Tab 1 */ \ + { WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP }, /* Tab 2 */ \ + { WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP }, /* Tab 3 */ \ + { WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP }, /* Tab 4 */ \ + { WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP }, /* Tab 5 */ \ + { WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP }, /* Tab 6 */ \ + { WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP } /* Tab 7 */ + static rct_widget window_guest_overview_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, 0xFFFFFFFF, STR_NONE}, // Panel / Background - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, // Title - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, // Close x button - {WWT_RESIZE, 1, 0, 191, 43, 156, 0xFFFFFFFF, STR_NONE}, // Resize - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, // Tab 1 - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, // Tab 2 - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, // Tab 3 - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, // Tab 4 - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, // Tab 5 - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, // Tab 6 - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, // Tab 7 - {WWT_LABEL_CENTRED, 1, 3, 166, 45, 56, 0xFFFFFFFF, STR_NONE}, // Label Thought marquee - {WWT_VIEWPORT, 1, 3, 166, 57, 143, 0xFFFFFFFF, STR_NONE}, // Viewport - {WWT_LABEL_CENTRED, 1, 3, 166, 144, 154, 0xFFFFFFFF, STR_NONE}, // Label Action - {WWT_FLATBTN, 1, 167, 190, 45, 68, SPR_PICKUP_BTN, STR_PICKUP_TIP}, // Pickup Button - {WWT_FLATBTN, 1, 167, 190, 69, 92, SPR_RENAME, STR_NAME_GUEST_TIP}, // Rename Button - {WWT_FLATBTN, 1, 167, 190, 93, 116, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP}, // Locate Button - {WWT_FLATBTN, 1, 167, 190, 117, 140, SPR_TRACK_PEEP, STR_TOGGLE_GUEST_TRACKING_TIP}, // Track Button + MAIN_GUEST_WIDGETS, + { WWT_LABEL_CENTRED, 1, 3, 166, 45, 56, 0xFFFFFFFF, STR_NONE }, // Label Thought marquee + { WWT_VIEWPORT, 1, 3, 166, 57, 143, 0xFFFFFFFF, STR_NONE }, // Viewport + { WWT_LABEL_CENTRED, 1, 3, 166, 144, 154, 0xFFFFFFFF, STR_NONE }, // Label Action + { WWT_FLATBTN, 1, 167, 190, 45, 68, SPR_PICKUP_BTN, STR_PICKUP_TIP }, // Pickup Button + { WWT_FLATBTN, 1, 167, 190, 69, 92, SPR_RENAME, STR_NAME_GUEST_TIP }, // Rename Button + { WWT_FLATBTN, 1, 167, 190, 93, 116, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP }, // Locate Button + { WWT_FLATBTN, 1, 167, 190, 117, 140, SPR_TRACK_PEEP, STR_TOGGLE_GUEST_TRACKING_TIP }, // Track Button { WIDGETS_END }, }; static rct_widget window_guest_stats_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WIDGETS_END }, }; static rct_widget window_guest_rides_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WWT_SCROLL, 1, 3, 188, 57, 143, SCROLL_VERTICAL, STR_NONE}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WWT_SCROLL, 1, 3, 188, 57, 143, SCROLL_VERTICAL, STR_NONE }, + { WIDGETS_END }, }; static rct_widget window_guest_finance_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WIDGETS_END }, }; static rct_widget window_guest_thoughts_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WIDGETS_END }, }; static rct_widget window_guest_inventory_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WIDGETS_END }, }; static rct_widget window_guest_debug_widgets[] = { - {WWT_FRAME, 0, 0, 191, 0, 156, STR_NONE, STR_NONE}, - {WWT_CAPTION, 0, 1, 190, 1, 14, STR_STRINGID, STR_WINDOW_TITLE_TIP}, - {WWT_CLOSEBOX, 0, 179, 189, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP}, - {WWT_RESIZE, 1, 0, 191, 43, 156, STR_NONE, STR_NONE}, - {WWT_TAB, 1, 3, TabWidth + 3, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VIEW_TIP}, - {WWT_TAB, 1, 34, TabWidth + 34, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_NEEDS_TIP}, - {WWT_TAB, 1, 65, TabWidth + 65, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_VISITED_RIDES_TIP}, - {WWT_TAB, 1, 96, TabWidth + 96, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_FINANCE_TIP}, - {WWT_TAB, 1, 127, TabWidth + 127, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_THOUGHTS_TIP}, - {WWT_TAB, 1, 158, TabWidth + 158, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOW_GUEST_ITEMS_TIP}, - {WWT_TAB, 1, 189, TabWidth + 189, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_DEBUG_TIP}, - {WIDGETS_END}, + MAIN_GUEST_WIDGETS, + { WIDGETS_END }, }; // 0x981D0C @@ -2221,14 +2164,13 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "%u, %u, tolerance %u", peep->destination_x, peep->destination_y, - peep->destination_tolerance); + buffer, sizeof(buffer), "%u, %u, tolerance %u", peep->destination_x, peep->destination_y, peep->destination_tolerance); draw_debug_label(dpi, x, y, "Dest", buffer); y += LIST_ROW_HEIGHT; snprintf( - buffer, sizeof(buffer), "%u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, - peep->pathfind_goal.z, peep->pathfind_goal.direction); + buffer, sizeof(buffer), "%u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, + peep->pathfind_goal.direction); draw_debug_label(dpi, x, y, "Pathfind Goal", buffer); y += LIST_ROW_HEIGHT; From f50695fc9b6ea6d8baecfa98dc1254c4ca17a92c Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 16:23:29 +0000 Subject: [PATCH 303/506] Refactor guest window resize --- src/openrct2-ui/windows/Guest.cpp | 209 ++++++++++-------------------- 1 file changed, 67 insertions(+), 142 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 607a79c84f..546b9a3d2d 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -138,6 +138,8 @@ static rct_widget *window_guest_page_widgets[] = { static void window_guest_set_page(rct_window* w, int32_t page); static void window_guest_disable_widgets(rct_window* w); static void window_guest_viewport_init(rct_window* w); +static void window_guest_common_resize(rct_window* w); +static void window_guest_common_invalidate(rct_window* w); static void window_guest_overview_close(rct_window *w); static void window_guest_overview_resize(rct_window *w); @@ -153,12 +155,9 @@ static void window_guest_overview_tool_abort(rct_window *w, rct_widgetindex widg static void window_guest_mouse_up(rct_window *w, rct_widgetindex widgetIndex); -static void window_guest_stats_resize(rct_window *w); static void window_guest_stats_update(rct_window *w); -static void window_guest_stats_invalidate(rct_window *w); static void window_guest_stats_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_guest_rides_resize(rct_window *w); static void window_guest_rides_update(rct_window *w); static void window_guest_rides_scroll_get_size(rct_window *w, int32_t scrollIndex, int32_t *width, int32_t *height); static void window_guest_rides_scroll_mouse_down(rct_window *w, int32_t scrollIndex, int32_t x, int32_t y); @@ -167,24 +166,16 @@ static void window_guest_rides_invalidate(rct_window *w); static void window_guest_rides_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_guest_rides_scroll_paint(rct_window *w, rct_drawpixelinfo *dpi, int32_t scrollIndex); -static void window_guest_finance_resize(rct_window *w); static void window_guest_finance_update(rct_window *w); -static void window_guest_finance_invalidate(rct_window *w); static void window_guest_finance_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_guest_thoughts_resize(rct_window *w); static void window_guest_thoughts_update(rct_window *w); -static void window_guest_thoughts_invalidate(rct_window *w); static void window_guest_thoughts_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_guest_inventory_resize(rct_window *w); static void window_guest_inventory_update(rct_window *w); -static void window_guest_inventory_invalidate(rct_window *w); static void window_guest_inventory_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_guest_debug_resize(rct_window *w); static void window_guest_debug_update(rct_window *w); -static void window_guest_debug_invalidate(rct_window *w); static void window_guest_debug_paint(rct_window *w, rct_drawpixelinfo* dpi); static rct_window_event_list window_guest_overview_events = { @@ -221,7 +212,7 @@ static rct_window_event_list window_guest_overview_events = { static rct_window_event_list window_guest_stats_events = { nullptr, window_guest_mouse_up, - window_guest_stats_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -244,7 +235,7 @@ static rct_window_event_list window_guest_stats_events = { nullptr, nullptr, nullptr, - window_guest_stats_invalidate, + window_guest_common_invalidate, window_guest_stats_paint, nullptr }; @@ -252,7 +243,7 @@ static rct_window_event_list window_guest_stats_events = { static rct_window_event_list window_guest_rides_events = { nullptr, window_guest_mouse_up, - window_guest_rides_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -283,7 +274,7 @@ static rct_window_event_list window_guest_rides_events = { static rct_window_event_list window_guest_finance_events = { nullptr, window_guest_mouse_up, - window_guest_finance_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -306,7 +297,7 @@ static rct_window_event_list window_guest_finance_events = { nullptr, nullptr, nullptr, - window_guest_finance_invalidate, + window_guest_common_invalidate, window_guest_finance_paint, nullptr }; @@ -314,7 +305,7 @@ static rct_window_event_list window_guest_finance_events = { static rct_window_event_list window_guest_thoughts_events = { nullptr, window_guest_mouse_up, - window_guest_thoughts_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -337,7 +328,7 @@ static rct_window_event_list window_guest_thoughts_events = { nullptr, nullptr, nullptr, - window_guest_thoughts_invalidate, + window_guest_common_invalidate, window_guest_thoughts_paint, nullptr }; @@ -345,7 +336,7 @@ static rct_window_event_list window_guest_thoughts_events = { static rct_window_event_list window_guest_inventory_events = { nullptr, window_guest_mouse_up, - window_guest_inventory_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -368,7 +359,7 @@ static rct_window_event_list window_guest_inventory_events = { nullptr, nullptr, nullptr, - window_guest_inventory_invalidate, + window_guest_common_invalidate, window_guest_inventory_paint, nullptr }; @@ -376,7 +367,7 @@ static rct_window_event_list window_guest_inventory_events = { static rct_window_event_list window_guest_debug_events = { nullptr, window_guest_mouse_up, - window_guest_debug_resize, + window_guest_common_resize, nullptr, nullptr, nullptr, @@ -399,7 +390,7 @@ static rct_window_event_list window_guest_debug_events = { nullptr, nullptr, nullptr, - window_guest_debug_invalidate, + window_guest_common_invalidate, window_guest_debug_paint, nullptr }; @@ -487,6 +478,16 @@ static constexpr const uint32_t window_guest_page_enabled_widgets[] = { (1 << WIDX_TAB_6) | (1 << WIDX_TAB_7) }; + +static constexpr const rct_size16 window_guest_page_sizes[][2] = { + { 192, 159, 500, 450 }, // WINDOW_GUEST_OVERVIEW + { 192, 180, 192, 180 }, // WINDOW_GUEST_STATS + { 192, 180, 500, 400 }, // WINDOW_GUEST_RIDES + { 210, 148, 210, 148 }, // WINDOW_GUEST_FINANCE + { 192, 159, 500, 450 }, // WINDOW_GUEST_THOUGHTS + { 192, 159, 500, 450 }, // WINDOW_GUEST_INVENTORY + { 192, 159, 192, 159 } // WINDOW_GUEST_DEBUG +}; // clang-format on /** @@ -547,6 +548,27 @@ rct_window* window_guest_open(Peep* peep) return window; } +static void window_guest_common_resize(rct_window* w) +{ + // Get page specific min and max size + int32_t minWidth = window_guest_page_sizes[w->page][0].width; + int32_t minHeight = window_guest_page_sizes[w->page][0].height; + int32_t maxWidth = window_guest_page_sizes[w->page][1].width; + int32_t maxHeight = window_guest_page_sizes[w->page][1].height; + + // Ensure min size is large enough for all tabs to fit + for (int32_t i = WIDX_TAB_1; i <= WIDX_TAB_7; i++) + { + if (!(w->disabled_widgets & (1ULL << i))) + { + minWidth = std::max(minWidth, w->widgets[i].right + 3); + } + } + maxWidth = std::max(minWidth, maxWidth); + + window_set_resize(w, minWidth, minHeight, maxWidth, maxHeight); +} + static void window_guest_common_invalidate(rct_window* w) { if (window_guest_page_widgets[w->page] != w->widgets) @@ -628,25 +650,21 @@ void window_guest_overview_resize(rct_window* w) widget_invalidate(w, WIDX_MARQUEE); - window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); + window_guest_common_resize(w); - rct_viewport* view = w->viewport; - - if (view) + auto viewport = w->viewport; + if (viewport != nullptr) { - if ((w->width - 30) == view->width) + auto reqViewportWidth = w->width - 30; + auto reqViewportHeight = w->height - 72; + if (viewport->width != reqViewportWidth || viewport->height != reqViewportHeight) { - if ((w->height - 72) == view->height) - { - window_guest_viewport_init(w); - return; - } + uint8_t zoom_amount = 1 << viewport->zoom; + viewport->width = reqViewportWidth; + viewport->height = reqViewportHeight; + viewport->view_width = viewport->width / zoom_amount; + viewport->view_height = viewport->height / zoom_amount; } - uint8_t zoom_amount = 1 << view->zoom; - view->width = w->width - 30; - view->height = w->height - 72; - view->view_width = view->width / zoom_amount; - view->view_height = view->height / zoom_amount; } window_guest_viewport_init(w); } @@ -1296,16 +1314,6 @@ void window_guest_mouse_up(rct_window* w, rct_widgetindex widgetIndex) } } -/** - * - * rct2: 0x697488 - */ -void window_guest_stats_resize(rct_window* w) -{ - const int32_t fixedWidth = 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0); - window_set_resize(w, fixedWidth, 180, fixedWidth, 180); -} - /** * * rct2: 0x69746A @@ -1319,15 +1327,6 @@ void window_guest_stats_update(rct_window* w) window_invalidate(w); } -/** - * - * rct2: 0x69707D - */ -void window_guest_stats_invalidate(rct_window* w) -{ - window_guest_common_invalidate(w); -} - /** * * rct2: 0x0066ECC1 @@ -1539,15 +1538,6 @@ void window_guest_stats_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string_left(dpi, STR_GUEST_STAT_NAUSEA_TOLERANCE, gCommonFormatArgs, COLOUR_BLACK, x, y); } -/** - * - * rct2: 0x006978F4 - */ -void window_guest_rides_resize(rct_window* w) -{ - window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 128, 500, 400); -} - /** * * rct2: 0x6977B0 @@ -1742,16 +1732,6 @@ void window_guest_rides_scroll_paint(rct_window* w, rct_drawpixelinfo* dpi, int3 } } -/** - * - * rct2: 0x00697C16 - */ -void window_guest_finance_resize(rct_window* w) -{ - int32_t fixedWidth = 210 + (gConfigGeneral.debugging_tools ? TabWidth : 0); - window_set_resize(w, fixedWidth, 148, fixedWidth, 148); -} - /** * * rct2: 0x00697BF8 @@ -1764,15 +1744,6 @@ void window_guest_finance_update(rct_window* w) widget_invalidate(w, WIDX_TAB_4); } -/** - * - * rct2: 0x00697968 - */ -void window_guest_finance_invalidate(rct_window* w) -{ - window_guest_common_invalidate(w); -} - /** * * rct2: 0x00697A08 @@ -1864,22 +1835,6 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi) } } -/** - * - * rct2: 0x00697E33 - */ -void window_guest_thoughts_resize(rct_window* w) -{ - Peep* peep = GET_PEEP(w->number); - if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_THOUGHTS) - { - peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_THOUGHTS; - window_invalidate(w); - } - - window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); -} - /** * * rct2: 0x00697EB4 @@ -1890,15 +1845,13 @@ void window_guest_thoughts_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_5); -} -/** - * - * rct2: 0x00697C8A - */ -void window_guest_thoughts_invalidate(rct_window* w) -{ - window_guest_common_invalidate(w); + auto peep = GET_PEEP(w->number); + if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_THOUGHTS) + { + peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_THOUGHTS; + window_invalidate(w); + } } /** @@ -1945,22 +1898,6 @@ void window_guest_thoughts_paint(rct_window* w, rct_drawpixelinfo* dpi) } } -/** - * - * rct2: 0x00698294 - */ -void window_guest_inventory_resize(rct_window* w) -{ - Peep* peep = GET_PEEP(w->number); - if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_INVENTORY) - { - peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_INVENTORY; - window_invalidate(w); - } - - window_set_resize(w, 192 + (gConfigGeneral.debugging_tools ? TabWidth : 0), 159, 500, 450); -} - /** * * rct2: 0x00698315 @@ -1971,15 +1908,13 @@ void window_guest_inventory_update(rct_window* w) widget_invalidate(w, WIDX_TAB_2); widget_invalidate(w, WIDX_TAB_6); -} -/** - * - * rct2: 0x00697EE1 - */ -void window_guest_inventory_invalidate(rct_window* w) -{ - window_guest_common_invalidate(w); + auto peep = GET_PEEP(w->number); + if (peep->window_invalidate_flags & PEEP_INVALIDATE_PEEP_INVENTORY) + { + peep->window_invalidate_flags &= ~PEEP_INVALIDATE_PEEP_INVENTORY; + window_invalidate(w); + } } static rct_string_id window_guest_inventory_format_item(Peep* peep, int32_t item) @@ -2105,11 +2040,6 @@ void window_guest_inventory_paint(rct_window* w, rct_drawpixelinfo* dpi) } } -void window_guest_debug_resize(rct_window* w) -{ - window_set_resize(w, 192 + TabWidth, 159, 500, 450); -} - /** * * rct2: 0x00698315 @@ -2120,11 +2050,6 @@ void window_guest_debug_update(rct_window* w) window_invalidate(w); } -void window_guest_debug_invalidate(rct_window* w) -{ - window_guest_common_invalidate(w); -} - static void draw_debug_label(rct_drawpixelinfo* dpi, int32_t x, int32_t y, const char* label, const char* value) { const char* args[2] = { label, value }; From a22f0a53fb9ae9487bb5739ec454145747f739dd Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 21:48:02 +0000 Subject: [PATCH 304/506] Use localised strings for guest debug tab --- data/language/en-GB.txt | 9 +++- src/openrct2-ui/windows/Guest.cpp | 67 +++++++++++++-------------- src/openrct2/localisation/StringIds.h | 9 +++- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index accce90de3..a6290f01b1 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3757,7 +3757,14 @@ STR_6306 :{SMALLFONT}{BLACK}Experimental option to use multiple threads to re STR_6307 :Colour scheme: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Reconnect -STR_6310 :{WINDOW_COLOUR_2}{STRING}: {BLACK}{STRING} +STR_6310 :{WINDOW_COLOUR_2}Position: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Next: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(surface) +STR_6313 :(slope {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Dest: {BLACK}{INT32}, {INT32} tolerance {INT32} +STR_6315 :{WINDOW_COLOUR_2}Pathfind Goal: {BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6316 :{WINDOW_COLOUR_2}Pathfind history: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} ############# # Scenarios # diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 546b9a3d2d..41bf1dbb3a 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -2050,14 +2050,11 @@ void window_guest_debug_update(rct_window* w) window_invalidate(w); } -static void draw_debug_label(rct_drawpixelinfo* dpi, int32_t x, int32_t y, const char* label, const char* value) -{ - const char* args[2] = { label, value }; - gfx_draw_string_left(dpi, STR_PEEP_DEBUG_LABEL, args, 0, x, y); -} - void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) { + char buffer[512]{}; + char buffer2[512]{}; + window_draw_widgets(w, dpi); window_guest_overview_tab_paint(w, dpi); window_guest_stats_tab_paint(w, dpi); @@ -2070,44 +2067,46 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) auto peep = GET_PEEP(w->number); auto x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; auto y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; - - char buffer[512]{}; - snprintf(buffer, sizeof(buffer), "%i, %i, %i", peep->x, peep->y, peep->z); - draw_debug_label(dpi, x, y, "Position", buffer); - y += LIST_ROW_HEIGHT; - - snprintf(buffer, sizeof(buffer), "%u, %u, %u", peep->next_x, peep->next_y, peep->next_z); - if (peep->GetNextIsSurface()) - safe_strcat(buffer, " (surface)", sizeof(buffer)); - if (peep->GetNextIsSloped()) { - char slopeBuf[32]{}; - snprintf(slopeBuf, sizeof(slopeBuf), " (slope %u)", peep->GetNextDirection()); - safe_strcat(buffer, slopeBuf, sizeof(buffer)); + int32_t args[] = { peep->x, peep->y, peep->x }; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_POSITION, args, 0, x, y); } - draw_debug_label(dpi, x, y, "Next", buffer); y += LIST_ROW_HEIGHT; - - snprintf( - buffer, sizeof(buffer), "%u, %u, tolerance %u", peep->destination_x, peep->destination_y, peep->destination_tolerance); - draw_debug_label(dpi, x, y, "Dest", buffer); + { + int32_t args[] = { peep->next_x, peep->next_y, peep->next_z }; + format_string(buffer, sizeof(buffer), STR_PEEP_DEBUG_NEXT, args); + if (peep->GetNextIsSurface()) + { + format_string(buffer2, sizeof(buffer2), STR_PEEP_DEBUG_NEXT_SURFACE, nullptr); + safe_strcat(buffer, buffer2, sizeof(buffer)); + } + if (peep->GetNextIsSloped()) + { + int32_t args2[1] = { peep->GetNextDirection() }; + format_string(buffer2, sizeof(buffer2), STR_PEEP_DEBUG_NEXT_SLOPE, args2); + safe_strcat(buffer, buffer2, sizeof(buffer)); + } + gfx_draw_string(dpi, buffer, 0, x, y); + } y += LIST_ROW_HEIGHT; - - snprintf( - buffer, sizeof(buffer), "%u, %u, %u dir %u", peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, - peep->pathfind_goal.direction); - draw_debug_label(dpi, x, y, "Pathfind Goal", buffer); + { + int32_t args[] = { peep->destination_x, peep->destination_y, peep->destination_tolerance }; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_DEST, args, 0, x, y); + } y += LIST_ROW_HEIGHT; - - draw_debug_label(dpi, x, y, "Pathfind history", nullptr); + { + int32_t args[] = { peep->pathfind_goal.x, peep->pathfind_goal.y, peep->pathfind_goal.z, peep->pathfind_goal.direction }; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_PATHFIND_GOAL, args, 0, x, y); + } + y += LIST_ROW_HEIGHT; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_PATHFIND_HISTORY, nullptr, 0, x, y); y += LIST_ROW_HEIGHT; x += 10; for (auto& point : peep->pathfind_history) { - auto o = utf8_insert_codepoint(buffer, FORMAT_BLACK); - snprintf(buffer + o, sizeof(buffer) - o, "%u, %u, %u dir %u", point.x, point.y, point.z, point.direction); - gfx_draw_string(dpi, buffer, PALETTE_INDEX_10, x, y); + int32_t args[] = { point.x, point.y, point.z, point.direction }; + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_PATHFIND_HISTORY_ITEM, args, 0, x, y); y += LIST_ROW_HEIGHT; } x -= 10; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 79d4a7f15b..0b31ebc581 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3943,7 +3943,14 @@ enum STR_MULTIPLAYER_RECONNECT = 6309, - STR_PEEP_DEBUG_LABEL = 6310, + STR_PEEP_DEBUG_POSITION = 6310, + STR_PEEP_DEBUG_NEXT = 6311, + STR_PEEP_DEBUG_NEXT_SURFACE = 6312, + STR_PEEP_DEBUG_NEXT_SLOPE = 6313, + STR_PEEP_DEBUG_DEST = 6314, + STR_PEEP_DEBUG_PATHFIND_GOAL = 6315, + STR_PEEP_DEBUG_PATHFIND_HISTORY = 6316, + STR_PEEP_DEBUG_PATHFIND_HISTORY_ITEM = 6317, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 From 107a93b2e79b8b90357bd2cbe3f1a46d0b5c6542 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sun, 5 May 2019 04:00:24 +0000 Subject: [PATCH 305/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 1 + data/language/da-DK.txt | 61 +++++++++++++++++++++-------------------- data/language/de-DE.txt | 11 +++++--- data/language/nl-NL.txt | 1 + 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 81cac805d6..9386e9781f 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3776,6 +3776,7 @@ STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimentální podpora více vláken pro vykreslování obrazu, může způsobit nestabilitu. STR_6307 :Barevné schéma: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Znovu připojit ############################################################################### ## RCT2 Scenarios diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 34b9968ff5..2ebd8fa9c2 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3779,6 +3779,7 @@ STR_6305 :Multi-tråde STR_6306 :{SMALLFONT}{BLACK}Eksperimentel indstilling, brug flere processor kerner til at gengive spillet, kan påvirke stabiliteten. STR_6307 :Farve tema: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Forbind igen ############# # Scenarios # @@ -3899,152 +3900,152 @@ STR_DTLS :Kun for sjov! STR_SCNR :Whispering Cliffs STR_PARK :Whispering Cliffs -STR_DTLS :Develop the seaside cliffs into a thriving amusement park +STR_DTLS :Udvikel denne klippe ud mod havet, til en blomstrende forlystelsespark STR_SCNR :Three Monkeys Park STR_PARK :Three Monkeys Park -STR_DTLS :Central to this large developing park is a giant triple-track racing/duelling steel coaster +STR_DTLS :Centralt i denne store udviklingspark, er en kæmpe tredobbelt-Track Racing/Duelling stål rutchebane STR_SCNR :Canary Mines STR_PARK :Canary Mines -STR_DTLS :This abandoned mine already has the makings of a tourist attraction with its miniature railway and a pair of vertical drop rutschebaner +STR_DTLS :Denne forladte mine er allerede en turistattraktion med sin miniature jernbane og et par lodrette fald rutschebaner STR_SCNR :Barony Bridge STR_PARK :Barony Bridge -STR_DTLS :An old redundant bridge is yours to develop into an amusement park +STR_DTLS :Få denne gamle udtjente bro, til at udvikle sig til en forlystelsespark STR_SCNR :Funtopia STR_PARK :Funtopia -STR_DTLS :Covering land both sides of a highway, this park has several forlystelser already operating +STR_DTLS :Med land begge sider af en motorvej, har denne park allerede flere fungerende forlystelser STR_SCNR :Haunted Harbour STR_PARK :Haunted Harbour -STR_DTLS :The local authority has agreed to sell nearby land cheaply to this small seaside park, on the condition that certain forlystelser are preserved +STR_DTLS :De lokale myndigheder har indvilliget i at sælge nærliggende land billigt, til denne lille kystpark, på betingelse af, at visse forlystelser bliver bevaret STR_SCNR :Fun Fortress STR_PARK :Fun Fortress -STR_DTLS :This castle is all yours to turn into a theme park +STR_DTLS :Denne borg, kan du forvandle til en forlystelspark STR_SCNR :Future World STR_PARK :Future World -STR_DTLS :This futuristic park has plenty of space for new forlystelser on its alien landscape +STR_DTLS :Denne futuristiske forlystelsespark, har masser af plads til nye forlystelser på sit fremmede landskab STR_SCNR :Gentle Glen STR_PARK :Gentle Glen -STR_DTLS :The local population prefer gentle and relaxing forlystelser, so it is your job to expand this park to suit their tastes +STR_DTLS :Den lokale befolkning foretrækker blide og afslappende forlystelser, så det er dit job at udvide denne forlystelsespark, så den passer til deres smag STR_SCNR :Jolly Jungle STR_PARK :Jolly Jungle -STR_DTLS :Deep in the jungle lies a large area of land ready to be turned into a theme park +STR_DTLS :Dybt inde i junglen ligger et stort landområde, klar til at blive omdannet til en forlystelsespark STR_SCNR :Hydro Hills STR_PARK :Hydro Hills -STR_DTLS :A series of stepped lakes form the basis for this new park +STR_DTLS :En række forskudte søer, danner grundlaget for denne nye forlystelsespark STR_SCNR :Sprightly Park STR_PARK :Sprightly Park -STR_DTLS :This elderly park has many historical forlystelser but is badly in debt +STR_DTLS :Denne aldrene Park har mange historiske forlystelser, men er forgældet STR_SCNR :Magic Quarters STR_PARK :Magic Quarters -STR_DTLS :A large area of land has been cleared and partially themed ready for you to develop into a landscaped theme park +STR_DTLS :Et stort område af jord er blevet ryddet og delvist tematiseret, klar til at udvikle sig til en anlagt forlystelsespark STR_SCNR :Fruit Farm STR_PARK :Fruit Farm -STR_DTLS :A thriving fruit farm has built a railroad to boost its income, your job is to develop it into a full-blown amusement park +STR_DTLS :En blomstrende frugt gård har bygget en jernbane for at øge sin indkomst, dit job er at udvikle det til en lækker forlystelsespark STR_SCNR :Butterfly Dam STR_PARK :Butterfly Dam -STR_DTLS :The area around a dam is available for you to develop into an amusement park +STR_DTLS :Området omkring en dæmning er til rådighed for dig, til at udvikle en forlystelsespark STR_SCNR :Coaster Canyon STR_PARK :Coaster Canyon -STR_DTLS :A vast canyon is yours to turn into a theme park +STR_DTLS En stor kløft er din, til at forvandle den til en forlystelsespark STR_SCNR :Thunderstorm Park STR_PARK :Thunderstorm Park -STR_DTLS :The weather is so wet here that a giant pyramid has been built to allow some forlystelser to be built under cover +STR_DTLS :Vejret er så vådt her, at der er bygget en gigantisk pyramide, for at nogle forlystelser kan blive bygget under den. STR_SCNR :Harmonic Hills STR_PARK :Harmonic Hills -STR_DTLS :The local authority won't allow you to build above tree height in this park +STR_DTLS :Den lokale myndighed vil ikke tillade dig at bygge over træ højde i denne forlystelsespark STR_SCNR :Roman Village STR_PARK :Roman Village -STR_DTLS :Develop this Roman-themed park by adding forlystelser and rutschebaner +STR_DTLS :Udvikl denne forlystelsespark med et romersk tema, ved at tilføje forlystelser og rutschebaner STR_SCNR :Swamp Cove STR_PARK :Swamp Cove -STR_DTLS :Built partly on a series of small islands, this park already has a pair of large rutschebaner as its centrepiece +STR_DTLS :Bygget delvist på en række små øer, har denne forlystelsespark allerede et par store rutschebaner som sit centrum STR_SCNR :Adrenaline Heights STR_PARK :Adrenaline Heights -STR_DTLS :Build a park to appeal to the high-intensity thrill-seeking local people +STR_DTLS :Byg en Park for at appellere til den højintensive, gys-søgende, lokale folk STR_SCNR :Utopia Park STR_PARK :Utopia Park -STR_DTLS :An oasis in the middle of the desert provides an unusual opportunity to build an amusement park +STR_DTLS :En oase midt i ørkenen giver en usædvanlig mulighed for at bygge en forlystelsespark STR_SCNR :Rotting Heights STR_PARK :Rotting Heights -STR_DTLS :Overgrown and dilapidated, can you resurrect this once-great amusement park? +STR_DTLS :Overgroet og nedslidt, kan du genoplive denne en gang store forlystelsespark? STR_SCNR :Fiasco Forest STR_PARK :Fiasco Forest -STR_DTLS :Full of badly designed and dangerous forlystelser, you have a very limited budget and time to fix the problems and turn the park around +STR_DTLS :Fuld af dårligt designede og farlige forlystelser, har du et meget begrænset budget og tid, til at løse problemerne og vende parken rundt STR_SCNR :Pickle Park STR_PARK :Pickle Park -STR_DTLS :The local authority will not allow any kind of advertising or promotion, so this park must succeed by reputation only +STR_DTLS :De lokale myndigheder vil ikke tillade nogen form for reklame eller forfremmelse, så denne forlystelsespark skal lykkes udelukkende på omdømme STR_SCNR :Giggle Downs STR_PARK :Giggle Downs -STR_DTLS :A four lane steeplechase ride is the centrepiece of this expanding park +STR_DTLS :En fire sporet hestevæddeløbs bane er kernen i denne ekspanderende forlystelsespark STR_SCNR :Mineral Park STR_PARK :Mineral Park -STR_DTLS :Turn this abandoned stone quarry into a place to attract thrill-seeking tourists +STR_DTLS :Forvandel dette forladte stenbrud, til et sted til at tiltrække gys-søgende turister STR_SCNR :Coaster Crazy STR_PARK :Coaster Crazy -STR_DTLS :You have limited funds but unlimited time to turn this mountainside area into a vast rutschebane park +STR_DTLS :YDu har begrænsede midler, men ubegrænset tid til at vende dette bjergområde til en stor rutschebane forlystelsespark STR_SCNR :Urban Park STR_PARK :Urban Park -STR_DTLS :A tiny park has done a deal with the nearby town to allow expansion through the town itself +STR_DTLS :En lille forlystelsespark har lavet en aftale, med den nærliggende by, for at tillade ekspansion, gennem selve byen STR_SCNR :Geoffrey Gardens STR_PARK :Geoffrey Gardens -STR_DTLS :A large garden park needs turning into a thriving theme park +STR_DTLS :En stor have park skal forvandles til en blomstrende forlystelsespark ## Loopy Landscapes diff --git a/data/language/de-DE.txt b/data/language/de-DE.txt index 43fc7deedd..1964b24c41 100644 --- a/data/language/de-DE.txt +++ b/data/language/de-DE.txt @@ -551,8 +551,8 @@ STR_1167 :Wasserspiegel kann hier nicht erhöht werden... STR_1168 :Optionen STR_1169 :(Keine) STR_1170 :{STRING} -STR_1171 :{RED}Geschlossen - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Geschlossen +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Fußwege und Warteschlangenreihen anlegen STR_1174 :Banner im Weg STR_1175 :Kann nicht auf Fußweg mit Neigung angelegt werden @@ -1109,7 +1109,7 @@ STR_1726 :Land nicht zum Verkauf! STR_1727 :Baurechte nicht zum Verkauf! STR_1728 :Erwerb von Baurechten hier nicht möglich... STR_1729 :Land gehört nicht dem Park! -STR_1730 :{RED}Geschlossen - - +STR_1730 :{RED}Geschlossen STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Bauen STR_1733 :Modus @@ -2239,7 +2239,7 @@ STR_2977 :Mitarbeitername STR_2978 :Neuen Namen für diesen Mitarbeiter eingeben: STR_2979 :Dieser Mitarbeiter kann nicht benannt werden... STR_2980 :Zu viele Banner im Spiel -STR_2981 :{RED}Kein Zutritt - - +STR_2981 :{RED}Kein Zutritt STR_2982 :Bannertext STR_2983 :Neuen Text für dieses Banner eingeben: STR_2984 :Neuer Text für das Banner kann nicht erstellt werden... @@ -3765,6 +3765,9 @@ STR_6303 :Lädt Objekt herunter ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Szeneriewähler öffnen STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimentelle Option, um mehrere Threads für das Rendern zu verwenden, kann Instabilität verursachen +STR_6307 :Farbschema: {BLACK}{STRINGID} +STR_6308 :„{STRINGID}{OUTLINE}{TOPAZ}“{NEWLINE}{STRINGID} +STR_6309 :Neu verbinden ############# # Scenarios # diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index 0986395209..de5155fcb3 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -3771,6 +3771,7 @@ STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Experimentele optie om met meerdere threads te renderen. Dit kan de snelheid verhogen, maar ook instabiliteit veroorzaken. STR_6307 :Kleurenschema: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Opnieuw verbinden ############# # Scenarios # From 66e49a1a4492c3acc4e38f5c659edccdfc8724c9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 May 2019 14:29:23 +0100 Subject: [PATCH 306/506] Update OPENRCT2_ORG_TOKEN for AppVeyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 5313baf79f..b22470d496 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ cache: - secure-file -> scripts\ps\appveyor_install.ps1 environment: OPENRCT2_ORG_TOKEN: - secure: leQX3xCQpmBLGuMqrxjFlzexDt96ypNRMM5TTRVHbGE8PwVg9crgeykLc2BIZU6HDHveJCHqh2cGMdHtHYJYcw== + secure: esyy5+5PRKZNYZ1hx1w/JpJGVwEC/YsJXnPp3cH98Yu7sW6/a03z/oJ1m9jhM/nDv5HL0swVK7pi9qQsN0utRg== BUILD_SERVER: AppVeyor PATH: C:\ProgramData\chocolatey\bin;$(PATH);C:\Program Files (x86)\Windows Kits\10\bin\x86;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin install: From 2368fea91e17fe8b51788fcbd68401f74874d918 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 6 May 2019 19:15:32 +0200 Subject: [PATCH 307/506] Bump 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 cced3af44f..9e525a359d 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 "22" +#define NETWORK_STREAM_VERSION "23" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From e6c88a05dbbc87f2c50375d0b6a3b7c75ffeccc9 Mon Sep 17 00:00:00 2001 From: NexGenration Date: Fri, 3 May 2019 03:15:29 -0400 Subject: [PATCH 308/506] Make peep generate a static member function --- src/openrct2/world/Park.cpp | 2 +- test/tests/Pathfinding.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 24ec7fa829..cd17e2ee26 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -949,7 +949,7 @@ Peep* Park::GenerateGuest() if (spawn != nullptr) { auto direction = direction_reverse(spawn->direction); - peep = peep_generate(spawn->x, spawn->y, spawn->z); + peep = Peep::Generate(spawn->x, spawn->y, spawn->z); if (peep != nullptr) { peep->sprite_direction = direction << 3; diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index 86140c7647..bdbc2d591c 100644 --- a/test/tests/Pathfinding.cpp +++ b/test/tests/Pathfinding.cpp @@ -69,7 +69,7 @@ protected: // Our start position is in tile coordinates, but we need to give the peep spawn // position in actual world coords (32 units per tile X/Y, 8 per Z level). // Add 16 so the peep spawns in the center of the tile. - Peep* peep = peep_generate(pos->x * 32 + 16, pos->y * 32 + 16, pos->z * 8); + Peep* peep = Peep::Generate(pos->x * 32 + 16, pos->y * 32 + 16, pos->z * 8); // Peeps that are outside of the park use specialized pathfinding which we don't want to // use here From 846011e21b06f86de80a8af63c67efe7c4621488 Mon Sep 17 00:00:00 2001 From: NexGenration Date: Fri, 3 May 2019 03:35:57 -0400 Subject: [PATCH 309/506] another message here --- src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/peep/Peep.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index dc1795b90b..75d6ebe37a 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1708,7 +1708,7 @@ static constexpr const uint8_t tshirt_colours[] = { * * rct2: 0x0069A05D */ -Peep* peep_generate(int32_t x, int32_t y, int32_t z) +Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) { if (gSpriteListCount[SPRITE_LIST_NULL] < 400) return nullptr; diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 4900cbc203..ecdecc9213 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -714,6 +714,7 @@ public: // Peep void Pickup(); void PickupAbort(int32_t old_x); bool Place(TileCoordsXYZ location, bool apply); + static Peep* Generate(int32_t x, int32_t y, int32_t z); void RemoveFromQueue(); void RemoveFromRide(); @@ -945,7 +946,6 @@ void peep_stop_crowd_noise(); void peep_update_crowd_noise(); void peep_update_days_in_queue(); void peep_applause(); -Peep* peep_generate(int32_t x, int32_t y, int32_t z); void get_arguments_from_action(Peep* peep, uint32_t* argument_1, uint32_t* argument_2); void peep_thought_set_format_args(rct_peep_thought* thought); int32_t get_peep_face_sprite_small(Peep* peep); From 212f425ff037ee548b1c14d76ddd834300d68ff2 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 7 May 2019 19:34:38 +0200 Subject: [PATCH 310/506] Rename variables, change signature --- src/openrct2/peep/Peep.cpp | 30 +++++++++++++++--------------- src/openrct2/peep/Peep.h | 2 +- src/openrct2/world/Park.cpp | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 75d6ebe37a..00d4f57665 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1708,7 +1708,7 @@ static constexpr const uint8_t tshirt_colours[] = { * * rct2: 0x0069A05D */ -Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) +Peep* Peep::Generate(const CoordsXYZ coords) { if (gSpriteListCount[SPRITE_LIST_NULL] < 400) return nullptr; @@ -1737,7 +1737,7 @@ Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) peep->sprite_direction = 0; - sprite_move(x, y, z, (rct_sprite*)peep); + sprite_move(coords.x, coords.y, coords.z, (rct_sprite*)peep); peep->Invalidate(); peep->mass = (scenario_rand() & 0x1F) + 45; @@ -1777,13 +1777,13 @@ Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) peep->intensity = (intensityHighest << 4) | intensityLowest; - uint8_t nausea_tolerance = scenario_rand() & 0x7; + uint8_t nauseaTolerance = scenario_rand() & 0x7; if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) { - nausea_tolerance += 4; + nauseaTolerance += 4; } - peep->nausea_tolerance = nausea_tolerance_distribution[nausea_tolerance]; + peep->nausea_tolerance = nausea_tolerance_distribution[nauseaTolerance]; /* Scenario editor limits initial guest happiness to between 37..253. * To be on the safe side, assume the value could have been hacked @@ -1794,9 +1794,9 @@ Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) if (gGuestInitialHappiness == 0) peep->happiness = 128; /* Initial value will vary by -15..16 */ - int8_t happiness_delta = (scenario_rand() & 0x1F) - 15; + int8_t happinessDelta = (scenario_rand() & 0x1F) - 15; /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->happiness = std::clamp(peep->happiness + happiness_delta, 0, PEEP_MAX_HAPPINESS); + peep->happiness = std::clamp(peep->happiness + happinessDelta, 0, PEEP_MAX_HAPPINESS); peep->happiness_target = peep->happiness; peep->nausea = 0; peep->nausea_target = 0; @@ -1806,18 +1806,18 @@ Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) * to any value 0..255. */ peep->hunger = gGuestInitialHunger; /* Initial value will vary by -15..16 */ - int8_t hunger_delta = (scenario_rand() & 0x1F) - 15; + int8_t hungerDelta = (scenario_rand() & 0x1F) - 15; /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->hunger = std::clamp(peep->hunger + hunger_delta, 0, 255); + peep->hunger = std::clamp(peep->hunger + hungerDelta, 0, 255); /* Scenario editor limits initial guest thirst to between 37..253. * To be on the safe side, assume the value could have been hacked * to any value 0..255. */ peep->thirst = gGuestInitialThirst; /* Initial value will vary by -15..16 */ - int8_t thirst_delta = (scenario_rand() & 0x1F) - 15; + int8_t thirstDelta = (scenario_rand() & 0x1F) - 15; /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->thirst = std::clamp(peep->thirst + thirst_delta, 0, 0xFF); + peep->thirst = std::clamp(peep->thirst + thirstDelta, 0, 0xFF); peep->toilet = 0; peep->time_to_consume = 0; @@ -1872,11 +1872,11 @@ Peep* Peep::Generate(int32_t x, int32_t y, int32_t z) peep->angriness = 0; peep->time_lost = 0; - uint8_t tshirt_colour = static_cast(scenario_rand() % std::size(tshirt_colours)); - peep->tshirt_colour = tshirt_colours[tshirt_colour]; + uint8_t tshirtColour = static_cast(scenario_rand() % std::size(tshirt_colours)); + peep->tshirt_colour = tshirt_colours[tshirtColour]; - uint8_t trousers_colour = static_cast(scenario_rand() % std::size(trouser_colours)); - peep->trousers_colour = trouser_colours[trousers_colour]; + uint8_t trousersColour = static_cast(scenario_rand() % std::size(trouser_colours)); + peep->trousers_colour = trouser_colours[trousersColour]; /* Minimum energy is capped at 32 and maximum at 128, so this initialises * a peep with approx 34%-100% energy. (65 - 32) / (128 - 32) ≈ 34% */ diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index ecdecc9213..ad23880ec5 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -714,7 +714,7 @@ public: // Peep void Pickup(); void PickupAbort(int32_t old_x); bool Place(TileCoordsXYZ location, bool apply); - static Peep* Generate(int32_t x, int32_t y, int32_t z); + static Peep* Generate(const CoordsXYZ coords); void RemoveFromQueue(); void RemoveFromRide(); diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index cd17e2ee26..cff319175c 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -949,7 +949,7 @@ Peep* Park::GenerateGuest() if (spawn != nullptr) { auto direction = direction_reverse(spawn->direction); - peep = Peep::Generate(spawn->x, spawn->y, spawn->z); + peep = Peep::Generate({spawn->x, spawn->y, spawn->z}); if (peep != nullptr) { peep->sprite_direction = direction << 3; From 916b8c27056f572610a8b3593429228a5a052435 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 7 May 2019 19:46:58 +0200 Subject: [PATCH 311/506] Use more constants --- src/openrct2/peep/Peep.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 00d4f57665..5309d04796 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1742,9 +1742,9 @@ Peep* Peep::Generate(const CoordsXYZ coords) peep->mass = (scenario_rand() & 0x1F) + 45; peep->path_check_optimisation = 0; - peep->interaction_ride_index = 0xFF; + peep->interaction_ride_index = RIDE_ID_NULL; peep->type = PEEP_TYPE_GUEST; - peep->previous_ride = 0xFF; + peep->previous_ride = RIDE_ID_NULL; peep->thoughts->type = PEEP_THOUGHT_TYPE_NONE; peep->window_invalidate_flags = 0; @@ -1808,7 +1808,7 @@ Peep* Peep::Generate(const CoordsXYZ coords) /* Initial value will vary by -15..16 */ int8_t hungerDelta = (scenario_rand() & 0x1F) - 15; /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->hunger = std::clamp(peep->hunger + hungerDelta, 0, 255); + peep->hunger = std::clamp(peep->hunger + hungerDelta, 0, PEEP_MAX_HUNGER); /* Scenario editor limits initial guest thirst to between 37..253. * To be on the safe side, assume the value could have been hacked @@ -1817,7 +1817,7 @@ Peep* Peep::Generate(const CoordsXYZ coords) /* Initial value will vary by -15..16 */ int8_t thirstDelta = (scenario_rand() & 0x1F) - 15; /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->thirst = std::clamp(peep->thirst + thirstDelta, 0, 0xFF); + peep->thirst = std::clamp(peep->thirst + thirstDelta, 0, PEEP_MAX_THIRST); peep->toilet = 0; peep->time_to_consume = 0; @@ -1842,7 +1842,7 @@ Peep* Peep::Generate(const CoordsXYZ coords) cash = 0; } - if (gGuestInitialCash == (money16)(uint16_t)0xFFFF) + if (gGuestInitialCash == MONEY16_UNDEFINED) { cash = 0; } @@ -1856,7 +1856,7 @@ Peep* Peep::Generate(const CoordsXYZ coords) peep->pathfind_goal.direction = 0xFF; peep->item_standard_flags = 0; peep->item_extra_flags = 0; - peep->guest_heading_to_ride_id = 0xFF; + peep->guest_heading_to_ride_id = RIDE_ID_NULL; peep->litter_count = 0; peep->disgusting_count = 0; peep->vandalism_seen = 0; From 17ddd451db16a6cad1d4c399bf08bddab990e09b Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 7 May 2019 20:04:07 +0200 Subject: [PATCH 312/506] Fix tests, fix formatting --- src/openrct2/world/Park.cpp | 2 +- test/tests/Pathfinding.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index cff319175c..39c17944df 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -949,7 +949,7 @@ Peep* Park::GenerateGuest() if (spawn != nullptr) { auto direction = direction_reverse(spawn->direction); - peep = Peep::Generate({spawn->x, spawn->y, spawn->z}); + peep = Peep::Generate({ spawn->x, spawn->y, spawn->z }); if (peep != nullptr) { peep->sprite_direction = direction << 3; diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index bdbc2d591c..1c0b6c2f3b 100644 --- a/test/tests/Pathfinding.cpp +++ b/test/tests/Pathfinding.cpp @@ -69,7 +69,7 @@ protected: // Our start position is in tile coordinates, but we need to give the peep spawn // position in actual world coords (32 units per tile X/Y, 8 per Z level). // Add 16 so the peep spawns in the center of the tile. - Peep* peep = Peep::Generate(pos->x * 32 + 16, pos->y * 32 + 16, pos->z * 8); + Peep* peep = Peep::Generate({ pos->x * 32 + 16, pos->y * 32 + 16, pos->z * 8 }); // Peeps that are outside of the park use specialized pathfinding which we don't want to // use here From 27a119069a0c4e13c032388d96ec20a3975df5fe Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 8 May 2019 04:00:26 +0000 Subject: [PATCH 313/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/nl-NL.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index de5155fcb3..449792d514 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -3772,6 +3772,14 @@ STR_6306 :{SMALLFONT}{BLACK}Experimentele optie om met meerdere threads te re STR_6307 :Kleurenschema: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Opnieuw verbinden +STR_6310 :{WINDOW_COLOUR_2}Positie: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Volgende: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(oppervlak) +STR_6313 :(helling {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Bestemming: {BLACK}{INT32}, {INT32} tolerantie {INT32} +STR_6315 :{WINDOW_COLOUR_2}Pathfind-doel: {BLACK}{INT32}, {INT32}, {INT32} richting {INT32} +STR_6316 :{WINDOW_COLOUR_2}Pathfind-geschiedenis: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} richting {INT32} ############# # Scenarios # From 7f5c9622c02c4e18be64219edbc3cea206c14160 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 8 May 2019 20:57:20 +0200 Subject: [PATCH 314/506] Fix guests eating popcorn being drawn eating pizza --- distribution/changelog.txt | 1 + src/openrct2/peep/Guest.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index acf10d0277..fc24e22025 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -34,6 +34,7 @@ - Fix: [#9000] Show correct error message if not enough money available. - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. +- Fix: Guests eating popcorn are drawn as if they're eating pizza. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. - Improved: Allow the use of numpad enter key for console and chat. diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 4676ab878b..ce1b11bb70 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -6671,7 +6671,7 @@ static item_pref_t item_order_preference[] = { { 0, PEEP_ITEM_CHICKEN, PEEP_SPRITE_TYPE_CHICKEN }, { 0, PEEP_ITEM_LEMONADE, PEEP_SPRITE_TYPE_LEMONADE }, { 0, PEEP_ITEM_CANDYFLOSS, PEEP_SPRITE_TYPE_CANDYFLOSS }, - { 0, PEEP_ITEM_POPCORN, PEEP_SPRITE_TYPE_PIZZA }, + { 0, PEEP_ITEM_POPCORN, PEEP_SPRITE_TYPE_POPCORN }, { 0, PEEP_ITEM_HOT_DOG, PEEP_SPRITE_TYPE_HOT_DOG }, { 0, PEEP_ITEM_TENTACLE, PEEP_SPRITE_TYPE_TENTACLE }, { 0, PEEP_ITEM_TOFFEE_APPLE, PEEP_SPRITE_TYPE_TOFFEE_APPLE }, From da6794ad9e12912243c57c36ddb63706e19aef4d Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 8 May 2019 22:11:51 +0200 Subject: [PATCH 315/506] Refactor second argument to move_sprite_to_list() --- src/openrct2/actions/StaffHireNewAction.hpp | 2 +- src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 8 ++++---- src/openrct2/ride/CableLift.cpp | 2 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/world/Sprite.cpp | 14 +++++++------- src/openrct2/world/Sprite.h | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index 3051ab21dd..d22de4bf08 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -164,7 +164,7 @@ private: } else { - move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP * 2); + move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP); newPeep->sprite_identifier = 1; newPeep->window_invalidate_flags = 0; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 5309d04796..9b40612da0 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1715,7 +1715,7 @@ Peep* Peep::Generate(const CoordsXYZ coords) Peep* peep = (Peep*)create_sprite(1); - move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP * 2); + move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP); peep->sprite_identifier = SPRITE_IDENTIFIER_PEEP; peep->sprite_type = PEEP_SPRITE_TYPE_NORMAL; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 65fb451999..277ac94919 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1157,7 +1157,7 @@ private: // If vehicle is the first car on a train add to train list if (vehicle->IsHead()) { - move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_TRAIN * 2); + move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_TRAIN); } } } @@ -1349,7 +1349,7 @@ private: { rct1_peep* srcPeep = &_s4.sprites[i].peep; Peep* peep = (Peep*)create_sprite(SPRITE_IDENTIFIER_PEEP); - move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP * 2); + move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP); spriteIndexMap[i] = peep->sprite_index; ImportPeep(peep, srcPeep); @@ -1665,7 +1665,7 @@ private: const auto* srcLitter = &sprite.litter; rct_litter* litter = (rct_litter*)create_sprite(SPRITE_IDENTIFIER_LITTER); - move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER * 2); + move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER); litter->sprite_identifier = srcLitter->sprite_identifier; litter->type = srcLitter->type; @@ -1692,7 +1692,7 @@ private: { rct1_unk_sprite* src = &sprite.unknown; rct_sprite_generic* dst = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC); - move_sprite_to_list((rct_sprite*)dst, SPRITE_LIST_MISC * 2); + move_sprite_to_list((rct_sprite*)dst, SPRITE_LIST_MISC); dst->sprite_identifier = src->sprite_identifier; dst->type = src->type; diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 9f670c498f..0767c17f56 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -36,7 +36,7 @@ rct_vehicle* cable_lift_segment_create( current->ride_subtype = RIDE_ENTRY_INDEX_NULL; if (head) { - move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_TRAIN * 2); + move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_TRAIN); ride->cable_lift = current->sprite_index; } current->type = head ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 730cadec6a..5cb6b78f63 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4857,7 +4857,7 @@ static void vehicle_create_trains(ride_id_t rideIndex, int32_t x, int32_t y, int lastTrain = train; // Add train to ride vehicle list - move_sprite_to_list((rct_sprite*)train.head, SPRITE_LIST_TRAIN * 2); + move_sprite_to_list((rct_sprite*)train.head, SPRITE_LIST_TRAIN); for (int32_t i = 0; i < MAX_VEHICLES_PER_RIDE; i++) { if (ride->vehicles[i] == SPRITE_INDEX_NULL) diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 08c7a02236..83be386cdf 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -346,7 +346,7 @@ void sprite_clear_all_unused() */ rct_sprite* create_sprite(uint8_t bl) { - size_t linkedListTypeOffset = SPRITE_LIST_UNKNOWN * 2; + SPRITE_LIST linkedListTypeOffset = SPRITE_LIST_UNKNOWN; if ((bl & 2) != 0) { // 69EC96; @@ -355,7 +355,7 @@ rct_sprite* create_sprite(uint8_t bl) { return nullptr; } - linkedListTypeOffset = SPRITE_LIST_MISC * 2; + linkedListTypeOffset = SPRITE_LIST_MISC; } else if (gSpriteListCount[SPRITE_LIST_NULL] == 0) { @@ -364,7 +364,7 @@ rct_sprite* create_sprite(uint8_t bl) rct_sprite_generic* sprite = &(get_sprite(gSpriteListHead[SPRITE_LIST_NULL]))->generic; - move_sprite_to_list((rct_sprite*)sprite, (uint8_t)linkedListTypeOffset); + move_sprite_to_list((rct_sprite*)sprite, linkedListTypeOffset); // Need to reset all sprite data, as the uninitialised values // may contain garbage and cause a desync later on. @@ -392,12 +392,12 @@ rct_sprite* create_sprite(uint8_t bl) * of the desired linked list in a uint16_t array. Known valid values are * 2, 4, 6, 8 or 10 (SPRITE_LIST_... * 2) */ -void move_sprite_to_list(rct_sprite* sprite, uint8_t newListOffset) +void move_sprite_to_list(rct_sprite* sprite, SPRITE_LIST newList) { rct_sprite_generic* unkSprite = &sprite->generic; uint8_t oldListOffset = unkSprite->linked_list_type_offset; int32_t oldList = oldListOffset >> 1; - int32_t newList = newListOffset >> 1; + int32_t newListOffset = newList * 2; // No need to move if the sprite is already in the desired list if (oldListOffset == newListOffset) @@ -684,7 +684,7 @@ void sprite_remove(rct_sprite* sprite) user_string_free(peep->name_string_idx); } - move_sprite_to_list(sprite, SPRITE_LIST_NULL * 2); + move_sprite_to_list(sprite, SPRITE_LIST_NULL); sprite->generic.sprite_identifier = SPRITE_IDENTIFIER_NULL; _spriteFlashingList[sprite->generic.sprite_index] = false; @@ -765,7 +765,7 @@ void litter_create(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t t if (litter == nullptr) return; - move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER * 2); + move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER); litter->sprite_direction = direction; litter->sprite_width = 6; litter->sprite_height_negative = 6; diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 55b1d2ebed..6662a7dd64 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -205,7 +205,7 @@ rct_sprite* create_sprite(uint8_t bl); void reset_sprite_list(); void reset_sprite_spatial_index(); void sprite_clear_all_unused(); -void move_sprite_to_list(rct_sprite* sprite, uint8_t cl); +void move_sprite_to_list(rct_sprite* sprite, SPRITE_LIST newList); void sprite_misc_update_all(); void sprite_move(int16_t x, int16_t y, int16_t z, rct_sprite* sprite); void sprite_set_coordinates(int16_t x, int16_t y, int16_t z, rct_sprite* sprite); From 80a9cf8670681ae6da653ab15da6b55a3f847bc3 Mon Sep 17 00:00:00 2001 From: Mikroscopic <21092080+Mikroscopic@users.noreply.github.com> Date: Wed, 12 Dec 2018 21:47:56 -0500 Subject: [PATCH 316/506] Fix ghost objects rendering on minimap --- src/openrct2-ui/windows/Map.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 2e70b6a74f..726bb36b1b 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1550,6 +1550,9 @@ static uint16_t map_window_get_pixel_colour_peep(CoordsXY c) const int32_t maxSupportedTileElementType = (int32_t)std::size(ElementTypeAddColour); while (!(tileElement++)->IsLastForTile()) { + if (tileElement->IsGhost()) + continue; + int32_t tileElementType = tileElement->GetType() >> 2; if (tileElementType >= maxSupportedTileElementType) { @@ -1565,6 +1568,7 @@ static uint16_t map_window_get_pixel_colour_peep(CoordsXY c) static uint16_t map_window_get_pixel_colour_ride(CoordsXY c) { Ride* ride; + // ~Mikroscopic: do we need two separate colour variables here? uint16_t colourA = 0; // highlight colour uint16_t colourB = MAP_COLOUR(PALETTE_INDEX_13); // surface colour (dark grey) @@ -1572,6 +1576,9 @@ static uint16_t map_window_get_pixel_colour_ride(CoordsXY c) TileElement* tileElement = map_get_surface_element_at(c); do { + if (tileElement->IsGhost()) + continue; + switch (tileElement->GetType()) { case TILE_ELEMENT_TYPE_SURFACE: From 710da039a4c2639620fcdc4fcd0cd20c413532fa Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 May 2019 21:33:56 +0100 Subject: [PATCH 317/506] Show ghost elements as white on mini-map Also fixes refresh of map when using OpenGL drawing engine --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/Map.cpp | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index fc24e22025..11192c9070 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -9,6 +9,7 @@ - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Feature: [#9154] Change map toolbar icon with current viewport rotation. - Change: [#7877] Files are now sorted in logical rather than dictionary order. +- Change: [#8427] Ghost elements now show up as white on the mini-map. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#5103] OpenGL: ride track preview not rendered. - Fix: [#5889] Giant screenshot does not work while using OpenGL renderer. diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 726bb36b1b..fa097269e3 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -877,6 +877,7 @@ static void window_map_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_ g1temp.x_offset = -8; g1temp.y_offset = -8; gfx_set_g1_element(SPR_TEMP, &g1temp); + drawing_engine_invalidate_image(SPR_TEMP); gfx_draw_sprite(dpi, SPR_TEMP, 0, 0, 0); if (w->selected_tab == PAGE_PEEPS) @@ -1551,7 +1552,10 @@ static uint16_t map_window_get_pixel_colour_peep(CoordsXY c) while (!(tileElement++)->IsLastForTile()) { if (tileElement->IsGhost()) - continue; + { + colour = MAP_COLOUR(PALETTE_INDEX_21); + break; + } int32_t tileElementType = tileElement->GetType() >> 2; if (tileElementType >= maxSupportedTileElementType) @@ -1568,7 +1572,6 @@ static uint16_t map_window_get_pixel_colour_peep(CoordsXY c) static uint16_t map_window_get_pixel_colour_ride(CoordsXY c) { Ride* ride; - // ~Mikroscopic: do we need two separate colour variables here? uint16_t colourA = 0; // highlight colour uint16_t colourB = MAP_COLOUR(PALETTE_INDEX_13); // surface colour (dark grey) @@ -1577,7 +1580,10 @@ static uint16_t map_window_get_pixel_colour_ride(CoordsXY c) do { if (tileElement->IsGhost()) - continue; + { + colourA = MAP_COLOUR(PALETTE_INDEX_21); + break; + } switch (tileElement->GetType()) { From 7b71fe8acd9d04989314978b07c552dbbb7674c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 8 May 2019 23:34:41 +0200 Subject: [PATCH 318/506] Fix error value checked from ride_get_smallest_station_length (#8719) ride_get_smallest_station_length returns the int32_t::max instead of -1 on error. --- src/openrct2/network/Network.cpp | 2 +- src/openrct2/ride/Ride.cpp | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 9e525a359d..cbc767b85c 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 "23" +#define NETWORK_STREAM_VERSION "24" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 5cb6b78f63..7bfe2d534f 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -24,6 +24,7 @@ #include "../common.h" #include "../config/Config.h" #include "../core/Guard.hpp" +#include "../core/Optional.hpp" #include "../interface/Window.h" #include "../localisation/Date.h" #include "../localisation/Localisation.h" @@ -6881,14 +6882,17 @@ uint64_t ride_entry_get_supported_track_pieces(const rct_ride_entry* rideEntry) return supportedPieces; } -static int32_t ride_get_smallest_station_length(Ride* ride) +static opt::optional ride_get_smallest_station_length(Ride* ride) { - auto result = std::numeric_limits::max(); - for (int32_t i = 0; i < MAX_STATIONS; i++) + opt::optional result; + for (const auto& station : ride->stations) { - if (ride->stations[i].Start.xy != RCT_XY8_UNDEFINED) + if (station.Start.xy != RCT_XY8_UNDEFINED) { - result = std::min(result, ride->stations[i].Length); + if (!result.has_value() || station.Length < *result) + { + result = station.Length; + } } } return result; @@ -6996,11 +7000,11 @@ void Ride::UpdateMaxVehicles() min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4); // Calculate maximum train length based on smallest station length - int32_t stationLength = ride_get_smallest_station_length(this); - if (stationLength == -1) + auto stationNumTiles = ride_get_smallest_station_length(this); + if (!stationNumTiles.has_value()) return; - stationLength = (stationLength * 0x44180) - 0x16B2A; + auto stationLength = (*stationNumTiles * 0x44180) - 0x16B2A; int32_t maxMass = RideData5[type].max_mass << 8; int32_t maxCarsPerTrain = 1; for (int32_t numCars = rideEntry->max_cars_in_train; numCars > 0; numCars--) From 8f64bef9c27f30ef54702a2eb560189f6ffc4204 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 9 May 2019 04:00:22 +0000 Subject: [PATCH 319/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 8 ++++++++ data/language/da-DK.txt | 8 ++++++++ data/language/ko-KR.txt | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 9386e9781f..02b2ce0799 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3777,6 +3777,14 @@ STR_6306 :{SMALLFONT}{BLACK}Experimentální podpora více vláken pro vykres STR_6307 :Barevné schéma: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Znovu připojit +STR_6310 :{WINDOW_COLOUR_2}Pozice: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Další: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(povrch) +STR_6313 :(sklon {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Cíl: {BLACK}{INT32}, {INT32} tolerance {INT32} +STR_6315 :{WINDOW_COLOUR_2}Cíl hledání cesty: {BLACK}{INT32}, {INT32}, {INT32} směr {INT32} +STR_6316 :{WINDOW_COLOUR_2}Historie hledání cest: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} směr {INT32} ############################################################################### ## RCT2 Scenarios diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 2ebd8fa9c2..aeb2da4688 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3780,6 +3780,14 @@ STR_6306 :{SMALLFONT}{BLACK}Eksperimentel indstilling, brug flere processor k STR_6307 :Farve tema: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Forbind igen +STR_6310 :{WINDOW_COLOUR_2}Position: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Næste: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(overflade) +STR_6313 :(skråning {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Dest: {BLACK}{INT32}, {INT32} tolerance {INT32} +STR_6315 :{WINDOW_COLOUR_2}Stisøger Goal: {BLACK}{INT32}, {INT32}, {INT32} ret {INT32} +STR_6316 :{WINDOW_COLOUR_2}Stisøger historie: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} ret {INT32} ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index af1ec3a1fa..bf7ce643a8 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3765,6 +3765,14 @@ STR_6306 :{SMALLFONT}{BLACK}렌더링을 하기 위해 여러 개의 스레 STR_6307 :색상 조합: {BLACK}{STRINGID} STR_6308 :“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :재접속 +STR_6310 :{WINDOW_COLOUR_2}현재 위치: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}다음 위치: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(지표면) +STR_6313 :(높이 {INT32}) +STR_6314 :{WINDOW_COLOUR_2}목표: {BLACK}{INT32}, {INT32} 인내심 {INT32} +STR_6315 :{WINDOW_COLOUR_2}경로탐색 목표: {BLACK}{INT32}, {INT32}, {INT32} 방향 {INT32} +STR_6316 :{WINDOW_COLOUR_2}경로탐색 기록: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} 방향 {INT32} ############# From 9af568d97c86c62e43d6250e84e26e0dc0f5d076 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Fri, 10 May 2019 04:00:24 +0000 Subject: [PATCH 320/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/fr-FR.txt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/data/language/fr-FR.txt b/data/language/fr-FR.txt index 0dd5747184..1a30b3b2f5 100644 --- a/data/language/fr-FR.txt +++ b/data/language/fr-FR.txt @@ -553,8 +553,8 @@ STR_1167 :Impossible de surélever le niveau de l'eau ici... STR_1168 :Options STR_1169 :(Aucun) STR_1170 :{STRING} -STR_1171 :{RED}Fermé - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED}Fermé +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK}Construire des allées et des files d'attentes STR_1174 :Panneau d'affichage sur le passage STR_1175 :Impossible de construire ceci sur une allée en pente @@ -1111,7 +1111,7 @@ STR_1726 :Ce terrain n'est pas a vendre ! STR_1727 :Les droits de construction ne sont pas à vendre ! STR_1728 :Impossible d'acheter les droits de construction ici... STR_1729 :Ce terrain n'appartient pas au parc ! -STR_1730 :{RED}Fermé - - +STR_1730 :{RED}Fermé STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Construction STR_1733 :Mode @@ -2241,7 +2241,7 @@ STR_2977 :Nom de l'employé STR_2978 :Entrer le nouveau nom de cet employé : STR_2979 :Impossible de renommer cet employé... STR_2980 :Trop de bannières dans cette partie -STR_2981 :{RED}Accès interdit - - +STR_2981 :{RED}Accès interdit STR_2982 :Texte bannière STR_2983 :Saisir nouveau texte pour cette bannière : STR_2984 :Impossible de placer nouveau texte pour la bannière... @@ -3768,6 +3768,17 @@ STR_6303 :Téléchargement de l'objet ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Ouvrir le sélecteur de paysage STR_6305 :Multithreading STR_6306 :{SMALLFONT}{BLACK}Option expérimentale pour utiliser plusieurs threads pour le rendu, peut causer des problèmes d'instabilité. +STR_6307 :Palette de couleurs : {BLACK}{STRINGID} +STR_6308 :"{STRINGID}{OUTLINE}{TOPAZ}"{NEWLINE}{STRINGID} +STR_6309 :Reconnecter +STR_6310 :{WINDOW_COLOUR_2}Position : {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Suivant : {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(surface) +STR_6313 :(slope {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Destination : {BLACK}{INT32}, {INT32} tolérance {INT32} +STR_6315 :{WINDOW_COLOUR_2}Objectif recherche chemin : {BLACK}{INT32}, {INT32}, {INT32} dir. {INT32} +STR_6316 :{WINDOW_COLOUR_2}Historique recherche chemin : +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} ############# # Scenarios # From 6833da77e3ecc2344ea2c27301563a33a07e1192 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Fri, 10 May 2019 22:00:38 +0200 Subject: [PATCH 321/506] Simplify boolean expresions --- .../windows/EditorObjectSelection.cpp | 5 +---- src/openrct2-ui/windows/RideConstruction.cpp | 4 ++-- src/openrct2-ui/windows/ServerList.cpp | 2 +- src/openrct2-ui/windows/Staff.cpp | 6 +++--- src/openrct2/ReplayManager.cpp | 11 ++++------- src/openrct2/actions/GameAction.cpp | 4 ++-- src/openrct2/actions/GameActionCompat.cpp | 9 +-------- src/openrct2/interface/InteractiveConsole.cpp | 2 +- src/openrct2/localisation/UTF8.cpp | 4 +--- src/openrct2/management/Finance.cpp | 8 +------- src/openrct2/network/Network.cpp | 6 +++--- .../network/NetworkServerAdvertiser.cpp | 2 +- src/openrct2/paint/Supports.cpp | 2 +- .../paint/tile_element/Paint.Surface.cpp | 2 +- src/openrct2/peep/Guest.cpp | 7 +------ src/openrct2/peep/GuestPathfinding.cpp | 2 +- src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/platform/Posix.cpp | 6 +----- src/openrct2/ride/Ride.cpp | 19 +++++-------------- src/openrct2/ride/Vehicle.cpp | 13 +++++-------- .../ride/transport/MiniatureRailway.cpp | 12 ++++++------ src/openrct2/util/SawyerCoding.cpp | 2 +- src/openrct2/world/Banner.cpp | 2 +- src/openrct2/world/Map.cpp | 15 ++++++--------- src/openrct2/world/Sprite.cpp | 5 +---- 25 files changed, 52 insertions(+), 100 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index d751d2b33f..9d61f7c1a8 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1460,10 +1460,7 @@ static bool filter_chunks(const ObjectRepositoryItem* item) break; } } - if (_filter_flags & (1 << (gRideCategories[rideType] + _numSourceGameItems))) - return true; - - return false; + return (_filter_flags & (1 << (gRideCategories[rideType] + _numSourceGameItems))) != 0; } return true; } diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 2c62047cc4..408d789a8c 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2449,14 +2449,14 @@ static void sub_6CBCE2( // Set the temporary track element _tempTrackTileElement.SetType(TILE_ELEMENT_TYPE_TRACK); _tempTrackTileElement.SetDirection(trackDirection); - _tempTrackTileElement.AsTrack()->SetHasChain((edx & 0x10000) ? true : false); + _tempTrackTileElement.AsTrack()->SetHasChain((edx & 0x10000) != 0); _tempTrackTileElement.flags = quarterTile.GetBaseQuarterOccupied() | TILE_ELEMENT_FLAG_LAST_TILE; _tempTrackTileElement.base_height = baseZ; _tempTrackTileElement.clearance_height = clearanceZ; _tempTrackTileElement.AsTrack()->SetTrackType(trackType); _tempTrackTileElement.AsTrack()->SetSequenceIndex(trackBlock->index); _tempTrackTileElement.AsTrack()->SetHasCableLift(false); - _tempTrackTileElement.AsTrack()->SetInverted((edx & 0x20000) ? true : false); + _tempTrackTileElement.AsTrack()->SetInverted((edx & 0x20000) != 0); _tempTrackTileElement.AsTrack()->SetColourScheme(RIDE_COLOUR_SCHEME_MAIN); // Skipping seat rotation, should not be necessary for a temporary piece. _tempTrackTileElement.AsTrack()->SetRideIndex(rideIndex); diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 4561afc690..16f665d7e8 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -639,7 +639,7 @@ static void join_server(std::string address) static void fetch_servers() { std::string masterServerUrl = OPENRCT2_MASTER_SERVER_URL; - if (gConfigNetwork.master_server_url.empty() == false) + if (!gConfigNetwork.master_server_url.empty()) { masterServerUrl = gConfigNetwork.master_server_url; } diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 6758034a3d..a6e47a306c 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -1211,7 +1211,7 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, return; rct_sprite* sprite = try_get_sprite(w->number); - if (sprite == nullptr || sprite->IsPeep() == false) + if (sprite == nullptr || !sprite->IsPeep()) return; Peep& peep = sprite->peep; @@ -1252,7 +1252,7 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex, return; rct_sprite* sprite = try_get_sprite(w->number); - if (sprite == nullptr || sprite->IsPeep() == false) + if (sprite == nullptr || !sprite->IsPeep()) return; Peep& peep = sprite->peep; @@ -1262,7 +1262,7 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex, bool patrolAreaValue = staff_is_patrol_area_set(peep.staff_id, dest_x, dest_y); if (_staffPatrolAreaPaintValue == PatrolAreaValue::SET && patrolAreaValue) return; // Since area is already the value we want, skip... - if (_staffPatrolAreaPaintValue == PatrolAreaValue::UNSET && patrolAreaValue == false) + if (_staffPatrolAreaPaintValue == PatrolAreaValue::UNSET && !patrolAreaValue) return; // Since area is already the value we want, skip... auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction(w->number, { dest_x, dest_y }); diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index baafa4c97c..157be538b0 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -443,12 +443,12 @@ namespace OpenRCT2 { _mode = ReplayMode::NORMALISATION; - if (StartPlayback(file) == false) + if (!StartPlayback(file)) { return false; } - if (StartRecording(outFile, k_MaxReplayTicks) == false) + if (!StartRecording(outFile, k_MaxReplayTicks)) { StopPlayback(); return false; @@ -621,7 +621,7 @@ namespace OpenRCT2 return false; char buffer[128]; - while (feof(fp) == false) + while (feof(fp) == 0) { size_t numBytesRead = fread(buffer, 1, 128, fp); if (numBytesRead == 0) @@ -785,10 +785,7 @@ namespace OpenRCT2 bool Compatible(ReplayRecordData& data) { - if (data.version == 1 && ReplayVersion == 2) - return true; - - return false; + return data.version == 1 && ReplayVersion == 2; } bool Serialise(DataSerialiser& serialiser, ReplayRecordData& data) diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index aab701bc92..731e4d59ae 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -154,7 +154,7 @@ namespace GameActions if (result->Error == GA_ERROR::OK) { - if (finance_check_affordability(result->Cost, action->GetFlags()) == false) + if (!finance_check_affordability(result->Cost, action->GetFlags())) { result->Error = GA_ERROR::INSUFFICIENT_FUNDS; result->ErrorMessage = STR_NOT_ENOUGH_CASH_REQUIRES; @@ -290,7 +290,7 @@ namespace GameActions LogActionFinish(logContext, action, result); // If not top level just give away the result. - if (topLevel == false) + if (!topLevel) return result; gCommandPosition.x = result->Position.x; diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index b30569dd0e..7d71693de3 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -252,14 +252,7 @@ bool place_peep_spawn(CoordsXYZD location) { auto gameAction = PlacePeepSpawnAction(location); auto result = GameActions::Execute(&gameAction); - if (result->Error == GA_ERROR::OK) - { - return true; - } - else - { - return false; - } + return result->Error == GA_ERROR::OK; } #pragma endregion diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index ecb41e51ed..eebeea7f4d 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1436,7 +1436,7 @@ static int32_t cc_replay_stoprecord(InteractiveConsole& console, const arguments } auto* replayManager = OpenRCT2::GetContext()->GetReplayManager(); - if (replayManager->IsRecording() == false && replayManager->IsNormalising() == false) + if (!replayManager->IsRecording() && !replayManager->IsNormalising()) { console.WriteFormatLine("Replay currently not recording"); return 0; diff --git a/src/openrct2/localisation/UTF8.cpp b/src/openrct2/localisation/UTF8.cpp index 6318b58b9c..708e8df85d 100644 --- a/src/openrct2/localisation/UTF8.cpp +++ b/src/openrct2/localisation/UTF8.cpp @@ -276,7 +276,5 @@ bool utf8_is_format_code(int32_t codepoint) bool utf8_is_colour_code(int32_t codepoint) { - if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) - return true; - return false; + return codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END; } diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index dcacab3d7f..9eedd38245 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -89,13 +89,7 @@ bool finance_check_money_required(uint32_t flags) */ bool finance_check_affordability(money32 cost, uint32_t flags) { - if (cost <= 0) - return true; - if (finance_check_money_required(flags) == false) - return true; - if (cost > gCash) - return false; - return true; + return cost <= 0 || !finance_check_money_required(flags) || cost <= gCash; } /** diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index cbc767b85c..314408b792 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -986,7 +986,7 @@ void Network::SendPacketToClients(NetworkPacket& packet, bool front, bool gameCm bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) { // We have to wait for the map to be loaded first, ticks may match current loaded map. - if (_clientMapLoaded == false) + if (!_clientMapLoaded) return true; auto itTickData = _serverTickData.find(tick); @@ -999,7 +999,7 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) if (storedTick.srand0 != srand0) return false; - if (storedTick.spriteHash.empty() == false) + if (!storedTick.spriteHash.empty()) { rct_sprite_checksum checksum = sprite_checksum(); std::string clientSpriteHash = checksum.ToString(); @@ -2198,7 +2198,7 @@ NetworkPlayer* Network::AddPlayer(const std::string& name, const std::string& ke if (networkUser == nullptr) { player->Group = GetDefaultGroup(); - if (name.empty() == false) + if (!name.empty()) { player->SetName(MakePlayerNameUnique(String::Trim(name))); } diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 84ee0c2934..1b8623bfb4 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -254,7 +254,7 @@ private: static std::string GetMasterServerUrl() { std::string result = OPENRCT2_MASTER_SERVER_URL; - if (gConfigNetwork.master_server_url.empty() == false) + if (!gConfigNetwork.master_server_url.empty()) { result = gConfigNetwork.master_server_url; } diff --git a/src/openrct2/paint/Supports.cpp b/src/openrct2/paint/Supports.cpp index 9818b68711..593e4e2370 100644 --- a/src/openrct2/paint/Supports.cpp +++ b/src/openrct2/paint/Supports.cpp @@ -1320,7 +1320,7 @@ bool path_b_supports_paint_setup( baseHeight += z; } - if (keepGoing == false) + if (!keepGoing) { break; } diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index b95667f9d9..27b7cba907 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -781,7 +781,7 @@ static void viewport_surface_draw_tile_side_top( return; } - if (isWater == false) + if (!isWater) dl = height; // save ecx diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index ce1b11bb70..3ea536e340 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -5884,12 +5884,7 @@ bool Guest::ShouldFindBench() return false; } - if (!GetNextIsSurface() && !GetNextIsSloped()) - { - return true; - } - - return false; + return !GetNextIsSurface() && !GetNextIsSloped(); } /** diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 90c96eb0fd..7837749dc4 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -1797,7 +1797,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc) } } while (!(tileElement++)->IsLastForTile()); - if (found == false) + if (!found) break; if (!tileElement->AsPath()->IsQueue()) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 362782a553..daaccae5dc 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -710,7 +710,7 @@ static uint8_t staff_direction_surface(Peep* peep, uint8_t initialDirection) LocationXY16 chosenTile = { static_cast(peep->next_x + CoordsDirectionDelta[direction].x), static_cast(peep->next_y + CoordsDirectionDelta[direction].y) }; - if (map_surface_is_blocked(chosenTile.x, chosenTile.y) == false) + if (!map_surface_is_blocked(chosenTile.x, chosenTile.y)) { return direction; } diff --git a/src/openrct2/platform/Posix.cpp b/src/openrct2/platform/Posix.cpp index d769268afa..733df1b6fc 100644 --- a/src/openrct2/platform/Posix.cpp +++ b/src/openrct2/platform/Posix.cpp @@ -130,11 +130,7 @@ bool platform_directory_exists(const utf8* path) struct stat dirinfo; int32_t result = stat(buffer, &dirinfo); log_verbose("checking dir %s, result = %d, is_dir = %d", buffer, result, S_ISDIR(dirinfo.st_mode)); - if ((result != 0) || !S_ISDIR(dirinfo.st_mode)) - { - return false; - } - return true; + return result == 0 && S_ISDIR(dirinfo.st_mode); } bool platform_original_game_data_exists(const utf8* path) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 7bfe2d534f..28c96ebe07 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -2570,12 +2570,7 @@ bool Ride::CanBreakDown() const } rct_ride_entry* entry = GetRideEntry(); - if (entry == nullptr || entry->flags & RIDE_ENTRY_FLAG_CANNOT_BREAK_DOWN) - { - return false; - } - - return true; + return entry != nullptr && !(entry->flags & RIDE_ENTRY_FLAG_CANNOT_BREAK_DOWN); } static void choose_random_train_to_breakdown_safe(Ride* ride) @@ -7197,7 +7192,7 @@ void sub_6CB945(Ride* ride) break; } while (!(tileElement++)->IsLastForTile()); - if (trackFound == false) + if (!trackFound) { break; } @@ -7212,7 +7207,7 @@ void sub_6CB945(Ride* ride) } } - if (specialTrack == false) + if (!specialTrack) { continue; } @@ -7782,13 +7777,9 @@ uint8_t ride_entry_get_first_non_null_ride_type(const rct_ride_entry* rideEntry) bool ride_type_supports_boosters(uint8_t rideType) { - if (rideType == RIDE_TYPE_LOOPING_ROLLER_COASTER || rideType == RIDE_TYPE_CORKSCREW_ROLLER_COASTER + return rideType == RIDE_TYPE_LOOPING_ROLLER_COASTER || rideType == RIDE_TYPE_CORKSCREW_ROLLER_COASTER || rideType == RIDE_TYPE_TWISTER_ROLLER_COASTER || rideType == RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER - || rideType == RIDE_TYPE_GIGA_COASTER || rideType == RIDE_TYPE_JUNIOR_ROLLER_COASTER) - { - return true; - } - return false; + || rideType == RIDE_TYPE_GIGA_COASTER || rideType == RIDE_TYPE_JUNIOR_ROLLER_COASTER; } int32_t get_booster_speed(uint8_t rideType, int32_t rawSpeed) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 1c52163f3f..81c4cb0dbe 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1862,7 +1862,7 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) // Iterate through each tile_element. } while (!(tile_element++)->IsLastForTile()); - if (cover_found == false) + if (!cover_found) { ride->testing_flags &= ~RIDE_TESTING_SHELTERED; return; @@ -2544,7 +2544,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) } } - if (skipCheck == false) + if (!skipCheck) { if (!(ride->stations[vehicle->current_station].Depart & STATION_DEPART_FLAG)) return; @@ -3414,7 +3414,7 @@ static void vehicle_update_departing(rct_vehicle* vehicle) } } - if (vehicle_current_tower_element_is_top(vehicle) == false) + if (!vehicle_current_tower_element_is_top(vehicle)) { if (ride->mode == RIDE_MODE_FREEFALL_DROP) vehicle_invalidate(vehicle); @@ -7669,10 +7669,7 @@ static bool vehicle_update_motion_collision_detection( return false; uint8_t direction = (vehicle->sprite_direction - collideVehicle->sprite_direction + 7) & 0x1F; - if (direction >= 0xF) - return false; - - return true; + return direction < 0xF; } LocationXY8 location = { static_cast(x / 32), static_cast(y / 32) }; @@ -7760,7 +7757,7 @@ static bool vehicle_update_motion_collision_detection( } } - if (mayCollide == false) + if (!mayCollide) { vehicle->var_C4 = 0; return false; diff --git a/src/openrct2/ride/transport/MiniatureRailway.cpp b/src/openrct2/ride/transport/MiniatureRailway.cpp index f0b3a8d829..7a34f54d73 100644 --- a/src/openrct2/ride/transport/MiniatureRailway.cpp +++ b/src/openrct2/ride/transport/MiniatureRailway.cpp @@ -927,7 +927,7 @@ static void paint_miniature_railway_track_right_quarter_turn_5_tiles( session, right_quarter_turn_5_supports_type[direction][trackSequence], 0, height, session->TrackColours[SCHEME_SUPPORTS], nullptr); - if (isSupported == false || (trackSequence == 3 && direction == 2)) + if (!isSupported || (trackSequence == 3 && direction == 2)) { track_paint_util_right_quarter_turn_5_tiles_paint( session, 2, height, direction, trackSequence, session->TrackColours[SCHEME_TRACK], @@ -1063,7 +1063,7 @@ static void paint_miniature_railway_track_s_bend_left( LocationXY16 offset = offsetList[trackSequence]; LocationXY16 bounds = boundsList[trackSequence]; - if (isSupported == false) + if (!isSupported) { sub_98197C_rotated( session, direction, imageId, (int8_t)offset.x, (int8_t)offset.y, bounds.x, bounds.y, 2, height, offset.x, offset.y, @@ -1163,7 +1163,7 @@ static void paint_miniature_railway_track_s_bend_right( | session->TrackColours[SCHEME_TRACK]; LocationXY16 offset = offsetList[trackSequence]; LocationXY16 bounds = boundsList[trackSequence]; - if (isSupported == false) + if (!isSupported) { sub_98197C_rotated( session, direction, imageId, (int8_t)offset.x, (int8_t)offset.y, bounds.x, bounds.y, 2, height, offset.x, offset.y, @@ -1274,7 +1274,7 @@ static void paint_miniature_railway_track_right_quarter_turn_3_tiles( isSupported = wooden_a_supports_paint_setup( session, supportType[direction], 0, height, session->TrackColours[SCHEME_SUPPORTS], nullptr); } - if (isSupported == false) + if (!isSupported) { track_paint_util_right_quarter_turn_3_tiles_paint( session, 3, height, direction, trackSequence, session->TrackColours[SCHEME_TRACK], @@ -1429,7 +1429,7 @@ static void paint_miniature_railway_track_left_eighth_to_diag( session, supportType[direction][trackSequence], 0, height, session->TrackColours[SCHEME_SUPPORTS], nullptr); } uint32_t imageId; - if (isSupported == false) + if (!isSupported) { int8_t index = paint_miniature_railway_eighth_to_diag_index[trackSequence]; if (index >= 0) @@ -1566,7 +1566,7 @@ static void paint_miniature_railway_track_right_eighth_to_diag( } uint32_t imageId; - if (isSupported == false) + if (!isSupported) { int8_t index = paint_miniature_railway_eighth_to_diag_index[trackSequence]; if (index >= 0) diff --git a/src/openrct2/util/SawyerCoding.cpp b/src/openrct2/util/SawyerCoding.cpp index 5af5b86702..c5c3a408d0 100644 --- a/src/openrct2/util/SawyerCoding.cpp +++ b/src/openrct2/util/SawyerCoding.cpp @@ -44,7 +44,7 @@ size_t sawyercoding_write_chunk_buffer(uint8_t* dst_file, const uint8_t* buffer, { uint8_t *encode_buffer, *encode_buffer2; - if (gUseRLE == false) + if (!gUseRLE) { if (chunkHeader.encoding == CHUNK_ENCODING_RLE || chunkHeader.encoding == CHUNK_ENCODING_RLECOMPRESSED) { diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index af42fc01d4..f0f3aa0ce6 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -214,7 +214,7 @@ void fix_duplicated_banners() log_error("Failed to create new banner."); continue; } - Guard::Assert(activeBanners[newBannerIndex] == false); + Guard::Assert(!activeBanners[newBannerIndex]); // Copy over the original banner, but update the location rct_banner& newBanner = gBanners[newBannerIndex]; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index f9ce97242f..e612c344a5 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -733,12 +733,9 @@ int32_t map_height_from_slope(const CoordsXY coords, int32_t slope, bool isSlope bool map_is_location_valid(const CoordsXY coords) { - if (coords.x < (MAXIMUM_MAP_SIZE_TECHNICAL * 32) && coords.x >= 0 && coords.y < (MAXIMUM_MAP_SIZE_TECHNICAL * 32) - && coords.y >= 0) - { - return true; - } - return false; + const bool is_x_valid = coords.x < (MAXIMUM_MAP_SIZE_TECHNICAL * 32) && coords.x >= 0; + const bool is_y_valid = coords.y < (MAXIMUM_MAP_SIZE_TECHNICAL * 32) && coords.y >= 0; + return is_x_valid && is_y_valid; } bool map_is_edge(const CoordsXY coords) @@ -1904,7 +1901,7 @@ EntranceElement* map_get_park_entrance_element_at(int32_t x, int32_t y, int32_t if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE) continue; - if ((ghost == false) && (tileElement->IsGhost())) + if (!ghost && tileElement->IsGhost()) continue; return tileElement->AsEntrance(); @@ -1929,7 +1926,7 @@ EntranceElement* map_get_ride_entrance_element_at(int32_t x, int32_t y, int32_t if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_RIDE_ENTRANCE) continue; - if ((ghost == false) && (tileElement->IsGhost())) + if (!ghost && tileElement->IsGhost()) continue; return tileElement->AsEntrance(); @@ -1954,7 +1951,7 @@ EntranceElement* map_get_ride_exit_element_at(int32_t x, int32_t y, int32_t z, b if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_RIDE_EXIT) continue; - if ((ghost == false) && (tileElement->IsGhost())) + if (!ghost && tileElement->IsGhost()) continue; return tileElement->AsEntrance(); diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 83be386cdf..319cd61b43 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -715,10 +715,7 @@ static bool litter_can_be_at(int32_t x, int32_t y, int32_t z) if (pathZ < z || pathZ >= z + 32) continue; - if (tile_element_is_underground(tileElement)) - return false; - - return true; + return !tile_element_is_underground(tileElement); } while (!(tileElement++)->IsLastForTile()); return false; } From 0eccb3495bc5cf3579979863a26cea3594301daa Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Fri, 10 May 2019 22:45:39 +0200 Subject: [PATCH 322/506] Add #8558 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index fc24e22025..4c622eb239 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,6 +3,7 @@ - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. - Feature: [#8481] Multi-threaded rendering. +- Feature: [#8558] Guest debugging tab. - Feature: [#8659] Banner and sign texts are now shown in tooltips. - Feature: [#8687] New multiplayer toolbar icon showing network status with reconnect option. - Feature: [#8919] Allow setting ride price from console. From b51f6a4d9074a8e6a9c4b05a2c96278eb22e3d34 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Sat, 11 May 2019 13:06:29 +0200 Subject: [PATCH 323/506] Use case-insensitive compare for soring ride and vehicle types (#9229) --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/Ride.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 4c622eb239..42da6c34a4 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -36,6 +36,7 @@ - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Fix: Guests eating popcorn are drawn as if they're eating pizza. +- Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. - Improved: Allow the use of numpad enter key for console and chat. diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index ef509a7884..c0d3f92e61 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ #include #include #include + using namespace OpenRCT2; enum @@ -2210,7 +2212,7 @@ static void populate_ride_type_dropdown() } std::sort(RideDropdownData.begin(), RideDropdownData.end(), [](auto& a, auto& b) { - return std::strcmp(a.label_string, b.label_string) < 0; + return String::Compare(a.label_string, b.label_string, true) < 0; }); RideDropdownDataLanguage = ls.GetCurrentLanguage(); @@ -2313,7 +2315,7 @@ static void populate_vehicle_type_dropdown(Ride* ride) } std::sort(VehicleDropdownData.begin(), VehicleDropdownData.end(), [](auto& a, auto& b) { - return std::strcmp(a.label_string, b.label_string) < 0; + return String::Compare(a.label_string, b.label_string, true) < 0; }); VehicleDropdownExpanded = selectionShouldBeExpanded; From ebefe5721bb458b356d95296cf0ae284912c0d01 Mon Sep 17 00:00:00 2001 From: nexgenration Date: Sat, 11 May 2019 08:20:34 -0400 Subject: [PATCH 324/506] Fix #9198: Move vehicle invalidate to member function To further improve the readability of the codebase the vehicle_invalidate function is now a member function of rct_vehicle. --- src/openrct2/ride/Vehicle.cpp | 90 +++++++++++++++++------------------ src/openrct2/ride/Vehicle.h | 1 + 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 81c4cb0dbe..c3bd1c5817 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -839,9 +839,9 @@ rct_vehicle* try_get_vehicle(uint16_t spriteIndex) return &sprite->vehicle; } -static void vehicle_invalidate(rct_vehicle* vehicle) +void rct_vehicle::Invalidate() { - invalidate_sprite_2((rct_sprite*)vehicle); + invalidate_sprite_2((rct_sprite*)this); } static int32_t get_train_mass(rct_vehicle* first_vehicle) @@ -1392,7 +1392,7 @@ static bool vehicle_close_restraints(rct_vehicle* vehicle) continue; } } - vehicle_invalidate(vehicle); + vehicle->Invalidate(); restraintsClosed = false; } while ((vehicle_id = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL); @@ -1449,7 +1449,7 @@ static bool vehicle_open_restraints(rct_vehicle* vehicle) vehicle->spin_sprite += value; vehicle->spin_speed -= value; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); continue; } } @@ -1460,7 +1460,7 @@ static bool vehicle_open_restraints(rct_vehicle* vehicle) vehicle->var_C8 = vehicle->var_C8 + 0x3333 - 0xFFFF; vehicle->animation_frame++; vehicle->animation_frame &= 7; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } else { @@ -1500,7 +1500,7 @@ static bool vehicle_open_restraints(rct_vehicle* vehicle) } vehicle->restraints_position += 20; } - vehicle_invalidate(vehicle); + vehicle->Invalidate(); restraintsOpen = false; } while ((vehicle_id = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL); @@ -2259,7 +2259,7 @@ static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle) vehicle->sub_state = 1; vehicle->time_waiting = 0; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); return; } else if (vehicle->sub_state == 1) @@ -2451,7 +2451,7 @@ static void vehicle_update_dodgems_mode(rct_vehicle* vehicle) if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_DODGEM_INUSE_LIGHTS && vehicle->animation_frame != 1) { vehicle->animation_frame = 1; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } vehicle_update_motion_dodgems(vehicle); @@ -2467,7 +2467,7 @@ static void vehicle_update_dodgems_mode(rct_vehicle* vehicle) // Mark the dodgem as not in use. vehicle->animation_frame = 0; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); vehicle->velocity = 0; vehicle->acceleration = 0; vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; @@ -3417,7 +3417,7 @@ static void vehicle_update_departing(rct_vehicle* vehicle) if (!vehicle_current_tower_element_is_top(vehicle)) { if (ride->mode == RIDE_MODE_FREEFALL_DROP) - vehicle_invalidate(vehicle); + vehicle->Invalidate(); return; } @@ -3681,7 +3681,7 @@ static void vehicle_update_travelling(rct_vehicle* vehicle) vehicle->animation_frame++; vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); return; } @@ -4321,7 +4321,7 @@ static void vehicle_update_motion_boat_hire(rct_vehicle* vehicle) unk_F64E20.x = vehicle->x; unk_F64E20.y = vehicle->y; unk_F64E20.z = vehicle->z; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); for (;;) { @@ -4545,7 +4545,7 @@ static void vehicle_update_motion_boat_hire(rct_vehicle* vehicle) } sprite_move(unk_F64E20.x, unk_F64E20.y, unk_F64E20.z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } // loc_6DAAC9: @@ -4719,7 +4719,7 @@ static void vehicle_update_swinging(rct_vehicle* vehicle) { // Used to know which sprite to draw vehicle->vehicle_sprite_type = (uint8_t)spriteType; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } return; } @@ -4804,7 +4804,7 @@ static void vehicle_update_ferris_wheel_rotating(rct_vehicle* vehicle) if (rotation == vehicle->sub_state) vehicle->var_CE++; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); uint8_t subState = vehicle->sub_state; if (ride->mode == RIDE_MODE_FORWARD_ROTATION) @@ -4867,7 +4867,7 @@ static void vehicle_update_simulator_operating(rct_vehicle* vehicle) if (al == vehicle->vehicle_sprite_type) return; vehicle->vehicle_sprite_type = al; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); return; } @@ -4921,7 +4921,7 @@ static void vehicle_update_rotating(rct_vehicle* vehicle) if (sprite == vehicle->vehicle_sprite_type) return; vehicle->vehicle_sprite_type = sprite; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); return; } @@ -4985,7 +4985,7 @@ static void vehicle_update_space_rings_operating(rct_vehicle* vehicle) if (spriteType != vehicle->vehicle_sprite_type) { vehicle->vehicle_sprite_type = spriteType; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } else @@ -5011,7 +5011,7 @@ static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle) if (gCurrentTicks & 1) { vehicle->vehicle_sprite_type++; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); if (vehicle->vehicle_sprite_type == 19) vehicle->vehicle_sprite_type = 0; @@ -5035,7 +5035,7 @@ static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle) break; case 75: vehicle->vehicle_sprite_type = 1; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); break; case 400: audio_play_sound_at_location(SOUND_HAUNTED_HOUSE_SCREAM_1, vehicle->x, vehicle->y, vehicle->z); @@ -5045,7 +5045,7 @@ static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle) break; case 775: vehicle->vehicle_sprite_type = 1; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); break; case 1100: audio_play_sound_at_location(SOUND_HAUNTED_HOUSE_SCREAM_2, vehicle->x, vehicle->y, vehicle->z); @@ -5092,13 +5092,13 @@ static void vehicle_update_top_spin_operating(rct_vehicle* vehicle) if (rotation != vehicle->vehicle_sprite_type) { vehicle->vehicle_sprite_type = rotation; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } rotation = sprite_map[vehicle->current_time].bank_rotation; if (rotation != vehicle->bank_rotation) { vehicle->bank_rotation = rotation; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } return; } @@ -5313,7 +5313,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) vehicle->sprite_height_positive = 5; sprite_move(vehicle->x, vehicle->y, vehicle->z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); vehicle->crash_z = 0; } @@ -5368,7 +5368,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) vehicle->sprite_height_positive = 5; sprite_move(vehicle->x, vehicle->y, vehicle->z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); vehicle->crash_z = -1; } @@ -6291,7 +6291,7 @@ static int32_t vehicle_update_motion_dodgems(rct_vehicle* vehicle) vehicle->sprite_direction -= 2; } vehicle->sprite_direction &= 0x1E; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } else if ((scenario_rand() & 0xFFFF) <= 2849) { @@ -6300,7 +6300,7 @@ static int32_t vehicle_update_motion_dodgems(rct_vehicle* vehicle) else vehicle->sprite_direction += 2; vehicle->sprite_direction &= 0x1E; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } @@ -6320,9 +6320,9 @@ static int32_t vehicle_update_motion_dodgems(rct_vehicle* vehicle) if (!vehicle_update_dodgems_collision(vehicle, location.x, location.y, &collideSprite)) { - vehicle_invalidate(vehicle); + vehicle->Invalidate(); sprite_move(location.x, location.y, location.z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } @@ -6335,7 +6335,7 @@ static int32_t vehicle_update_motion_dodgems(rct_vehicle* vehicle) unk_F64E20.y = vehicle->y; unk_F64E20.z = vehicle->z; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); while (true) { @@ -6390,7 +6390,7 @@ static int32_t vehicle_update_motion_dodgems(rct_vehicle* vehicle) } sprite_move(unk_F64E20.x, unk_F64E20.y, unk_F64E20.z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } int32_t eax = vehicle->velocity / 2; @@ -7051,7 +7051,7 @@ static void vehicle_update_swinging_car(rct_vehicle* vehicle) if (swingSprite != vehicle->swing_sprite) { vehicle->swing_sprite = swingSprite; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } @@ -7210,7 +7210,7 @@ static void vehicle_update_spinning_car(rct_vehicle* vehicle) vehicle->spin_sprite += spinSpeed >> 8; // Note this actually increases the spin speed if going right! vehicle->spin_speed -= spinSpeed >> vehicleEntry->spinning_friction; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } /** @@ -7285,7 +7285,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) vehicle->z + SteamParticleOffsets[index].z); } } - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_SWAN: // loc_6D6424 @@ -7294,7 +7294,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != al) { vehicle->animation_frame = al; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_CANOES: // loc_6D6482 @@ -7304,7 +7304,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != ah) { vehicle->animation_frame = ah; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_ROW_BOATS: // loc_6D64F7 @@ -7314,7 +7314,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != ah) { vehicle->animation_frame = ah; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_WATER_TRICYCLES: // loc_6D6453 @@ -7323,7 +7323,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != al) { vehicle->animation_frame = al; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_OBSERVATION_TOWER: // loc_6D65C3 @@ -7336,7 +7336,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) vehicle->var_C8 += 0x3333; vehicle->animation_frame += 1; vehicle->animation_frame &= 7; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_HELICARS: // loc_6D63F5 @@ -7345,7 +7345,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != al) { vehicle->animation_frame = al; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } break; case VEHICLE_ENTRY_ANIMATION_MONORAIL_CYCLES: // loc_6D64B6 @@ -7357,7 +7357,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (vehicle->animation_frame != ah) { vehicle->animation_frame = ah; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } break; @@ -7379,7 +7379,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) vehicle->seat_rotation++; vehicle->animation_frame = (vehicle->seat_rotation - 4) & 7; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); } } break; @@ -8727,7 +8727,7 @@ loc_6DC40E: unk_F64E20.x = vehicle->x; unk_F64E20.y = vehicle->y; unk_F64E20.z = vehicle->z; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); loc_6DC462: if (vehicle->var_D3 == 0) @@ -9071,7 +9071,7 @@ loc_6DCA7A: unk_F64E20.x = vehicle->x; unk_F64E20.y = vehicle->y; unk_F64E20.z = vehicle->z; - vehicle_invalidate(vehicle); + vehicle->Invalidate(); loc_6DCA9A: regs.ax = vehicle->track_progress - 1; @@ -9236,7 +9236,7 @@ loc_6DCD6B: loc_6DCDE4: sprite_move(unk_F64E20.x, unk_F64E20.y, unk_F64E20.z, (rct_sprite*)vehicle); - vehicle_invalidate(vehicle); + vehicle->Invalidate(); loc_6DCE02: vehicle->acceleration /= _vehicleUnkF64E10; diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 5c4d9f8456..76635f76fa 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -234,6 +234,7 @@ struct rct_vehicle : rct_sprite_common rct_vehicle* GetHead(); const rct_vehicle* GetHead() const; const rct_vehicle* GetCar(size_t carIndex) const; + void Invalidate(); }; struct train_ref From bbd69496b4d4d64c7135cdb2b7adba4d3db5b000 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sun, 3 Feb 2019 22:59:28 +0100 Subject: [PATCH 325/506] Sanitize screenshot path --- distribution/changelog.txt | 1 + src/openrct2/interface/Screenshot.cpp | 152 ++++++++++++++------------ src/openrct2/platform/Shared.cpp | 19 ++++ src/openrct2/platform/Windows.cpp | 18 +++ src/openrct2/platform/platform.h | 1 + 5 files changed, 119 insertions(+), 72 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 42da6c34a4..7cbd17abbe 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -116,6 +116,7 @@ - Fix: [#8588] Guest list scrolling breaks above ~2000 guests. - Fix: [#8591] Game loop does not run at a consistent tick rate of 40 Hz. - Fix: [#8647] Marketing campaigns check for entry fees below £1 (original bug). +- Fix: [#8598] Sanitize screenshot parknames. - Fix: [#8653] Crash when peeps attempt to enter a ride with no vehicles. - Fix: [#8720] Desync due to boats colliding with ghost pieces. - Fix: [#8736] Incomplete warning when all ride slots are full. diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index b64b5989bb..18b49c75d1 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -17,6 +17,7 @@ #include "../audio/audio.h" #include "../core/Console.hpp" #include "../core/Imaging.h" +#include "../core/Optional.hpp" #include "../drawing/Drawing.h" #include "../drawing/X8DrawingEngine.h" #include "../localisation/Localisation.h" @@ -28,10 +29,13 @@ #include "../world/Surface.h" #include "Viewport.h" +#include #include #include #include +#include +using namespace std::literals::string_literals; using namespace OpenRCT2; using namespace OpenRCT2::Drawing; @@ -96,88 +100,93 @@ static void screenshot_get_rendered_palette(rct_palette* palette) } } -static int32_t screenshot_get_next_path(char* path, size_t size) +static std::string screenshot_get_park_name() +{ + char buffer[512]; + format_string(buffer, sizeof(buffer), gParkName, &gParkNameArgs); + return buffer; +} + +static opt::optional screenshot_get_directory() { char screenshotPath[MAX_PATH]; - platform_get_user_directory(screenshotPath, "screenshot", sizeof(screenshotPath)); - if (!platform_ensure_directory_exists(screenshotPath)) + + if (platform_ensure_directory_exists(screenshotPath)) { - log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n"); - return -1; + return opt::make_optional(screenshotPath); } - char park_name[128]; - format_string(park_name, 128, gParkName, &gParkNameArgs); + log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n"); + return opt::nullopt; +} - // Retrieve current time - rct2_date currentDate; - platform_get_date_local(¤tDate); - rct2_time currentTime; - platform_get_time_local(¤tTime); +static std::tuple screenshot_get_date_time() +{ + rct2_date date; + platform_get_date_local(&date); -#ifdef _WIN32 - // On NTFS filesystems, a colon (:) in a path - // indicates you want to write a file stream - // (hidden metadata). This will pass the - // file_exists and fopen checks, since it is - // technically valid. We don't want that, so - // replace colons with hyphens in the park name. - char* foundColon = park_name; - while ((foundColon = strchr(foundColon, ':')) != nullptr) - { - *foundColon = '-'; - } -#endif + rct2_time time; + platform_get_time_local(&time); - // Glue together path and filename - safe_strcpy(path, screenshotPath, size); - path_end_with_separator(path, size); - auto fileNameCh = strchr(path, '\0'); - if (fileNameCh == nullptr) - { - log_error("Unable to generate a screenshot filename."); - return -1; - } - const size_t leftBytes = size - strlen(path); + return { date, time }; +} + +static std::string screenshot_get_formatted_date_time() +{ + auto [date, time] = screenshot_get_date_time(); + char formatted[64]; snprintf( - fileNameCh, leftBytes, "%s %d-%02d-%02d %02d-%02d-%02d.png", park_name, currentDate.year, currentDate.month, - currentDate.day, currentTime.hour, currentTime.minute, currentTime.second); + formatted, sizeof(formatted), "%4d-%02d-%02d %02d-%02d-%02d", date.year, date.month, date.day, time.hour, time.minute, + time.second); + return formatted; +} - if (!platform_file_exists(path)) +static opt::optional screenshot_get_next_path() +{ + std::string dir, name, suffix = ".png", path; + + auto screenshotDirectory = screenshot_get_directory(); + + if (screenshotDirectory == opt::nullopt) { - return 0; // path ok + return opt::nullopt; } - // multiple screenshots with same timestamp - // might be possible when switching timezones - // in the unlikely case that this does happen, - // append (%d) to the filename and increment - // this int32_t until it doesn't overwrite any - // other file in the directory. - int32_t i; - for (i = 1; i < 1000; i++) - { - // Glue together path and filename - snprintf( - fileNameCh, leftBytes, "%s %d-%02d-%02d %02d-%02d-%02d (%d).png", park_name, currentDate.year, currentDate.month, - currentDate.day, currentTime.hour, currentTime.minute, currentTime.second, i); + auto parkName = screenshot_get_park_name(); + auto dateTime = screenshot_get_formatted_date_time(); - if (!platform_file_exists(path)) - { - return i; - } + dir = *screenshotDirectory; + name = parkName + " " + dateTime; + + // Generate a path with a `tries` number + auto path_composer = [&dir, &name, &suffix ](int tries) -> auto + { + auto composed_filename = platform_sanitise_filename( + name + ((tries > 0) ? " ("s + std::to_string(tries) + ")" : ""s) + suffix); + return dir + PATH_SEPARATOR + composed_filename; + }; + + for (int tries = 0; tries < 100; tries++) + { + path = path_composer(tries); + if (platform_file_exists(path.c_str())) + continue; + + return path; } log_error("You have too many saved screenshots saved at exactly the same date and time.\n"); - return -1; -} + + return opt::nullopt; +}; std::string screenshot_dump_png(rct_drawpixelinfo* dpi) { // Get a free screenshot path - char path[MAX_PATH] = ""; - if (screenshot_get_next_path(path, MAX_PATH) == -1) + auto path = screenshot_get_next_path(); + + if (path == opt::nullopt) { return ""; } @@ -185,9 +194,9 @@ std::string screenshot_dump_png(rct_drawpixelinfo* dpi) rct_palette renderedPalette; screenshot_get_rendered_palette(&renderedPalette); - if (WriteDpiToFile(path, dpi, renderedPalette)) + if (WriteDpiToFile(path->c_str(), dpi, renderedPalette)) { - return std::string(path); + return *path; } else { @@ -197,9 +206,9 @@ std::string screenshot_dump_png(rct_drawpixelinfo* dpi) std::string screenshot_dump_png_32bpp(int32_t width, int32_t height, const void* pixels) { - // Get a free screenshot path - char path[MAX_PATH] = ""; - if (screenshot_get_next_path(path, MAX_PATH) == -1) + auto path = screenshot_get_next_path(); + + if (path == opt::nullopt) { return ""; } @@ -215,8 +224,8 @@ std::string screenshot_dump_png_32bpp(int32_t width, int32_t height, const void* image.Depth = 32; image.Stride = width * 4; image.Pixels = std::vector(pixels8, pixels8 + pixelsLen); - Imaging::WriteToFile(path, image, IMAGE_FORMAT::PNG_32); - return std::string(path); + Imaging::WriteToFile(path->c_str(), image, IMAGE_FORMAT::PNG_32); + return *path; } catch (const std::exception& e) { @@ -301,9 +310,8 @@ void screenshot_giant() viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); - // Get a free screenshot path - char path[MAX_PATH]; - if (screenshot_get_next_path(path, MAX_PATH) == -1) + auto path = screenshot_get_next_path(); + if (path == opt::nullopt) { log_error("Giant screenshot failed, unable to find a suitable destination path."); context_show_error(STR_SCREENSHOT_FAILED, STR_NONE); @@ -313,13 +321,13 @@ void screenshot_giant() rct_palette renderedPalette; screenshot_get_rendered_palette(&renderedPalette); - WriteDpiToFile(path, &dpi, renderedPalette); + WriteDpiToFile(path->c_str(), &dpi, renderedPalette); free(dpi.bits); // Show user that screenshot saved successfully set_format_arg(0, rct_string_id, STR_STRING); - set_format_arg(2, char*, path_get_filename(path)); + set_format_arg(2, char*, path_get_filename(path->c_str())); context_show_error(STR_SCREENSHOT_SAVED_AS, STR_NONE); } diff --git a/src/openrct2/platform/Shared.cpp b/src/openrct2/platform/Shared.cpp index 6cc2ec2688..050cb2ac13 100644 --- a/src/openrct2/platform/Shared.cpp +++ b/src/openrct2/platform/Shared.cpp @@ -28,6 +28,7 @@ #include "../world/Climate.h" #include "platform.h" +#include #include #include @@ -198,6 +199,24 @@ uint8_t platform_get_currency_value(const char* currCode) return CURRENCY_POUNDS; } +#ifndef _WIN32 +std::string platform_sanitise_filename(const std::string& path) +{ + auto sanitised = path; + + std::vector prohibited = { '/' }; + + std::replace_if( + sanitised.begin(), sanitised.end(), + [&prohibited](const std::string::value_type& ch) { + return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); + }, + '_'); + + return sanitised; +} +#endif + #ifndef __ANDROID__ float platform_get_default_scale() { diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 57c1ca7f64..029014dbf4 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -28,8 +28,10 @@ # include "../util/Util.h" # include "platform.h" +# include # include # include +# include # include # include # include @@ -253,6 +255,22 @@ std::string platform_get_rct2_steam_dir() return "Rollercoaster Tycoon 2"; } +std::string platform_sanitise_filename(const std::string& path) +{ + auto sanitised = path; + + std::vector prohibited = { '<', '>', '*', '\\', ':', '|', '?', '"', '/' }; + + std::replace_if( + sanitised.begin(), sanitised.end(), + [](const std::string::value_type& ch) { + return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); + }, + '_'); + + return sanitised; +} + uint16_t platform_get_locale_language() { CHAR langCode[4]; diff --git a/src/openrct2/platform/platform.h b/src/openrct2/platform/platform.h index 7e2ec421fd..bad0ad63eb 100644 --- a/src/openrct2/platform/platform.h +++ b/src/openrct2/platform/platform.h @@ -126,6 +126,7 @@ bool platform_process_is_elevated(); bool platform_get_steam_path(utf8* outPath, size_t outSize); std::string platform_get_rct1_steam_dir(); std::string platform_get_rct2_steam_dir(); +std::string platform_sanitise_filename(const std::string&); #ifndef NO_TTF bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size); From 744f2225ed0ff203ef918aac56209dfb8eb5735c Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 14:40:24 +0100 Subject: [PATCH 326/506] Write platform tests --- src/openrct2/platform/Windows.cpp | 3 +++ test/tests/CMakeLists.txt | 7 +++++++ test/tests/Platform.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 test/tests/Platform.cpp diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 029014dbf4..9ebc13ffc9 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -22,6 +22,7 @@ # include "../OpenRCT2.h" # include "../Version.h" # include "../config/Config.h" +# include "../core/String.h" # include "../localisation/Date.h" # include "../localisation/Language.h" # include "../rct2/RCT2.h" @@ -268,6 +269,8 @@ std::string platform_sanitise_filename(const std::string& path) }, '_'); + sanitised = String::Trim(sanitised); + return sanitised; } diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 842b6e7e54..72a485032d 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -144,6 +144,13 @@ target_link_libraries(test_ini ${GTEST_LIBRARIES} test-common ${LDL} z) target_link_platform_libraries(test_ini) add_test(NAME ini COMMAND test_ini) +# Platform +add_executable(test_platform ${CMAKE_CURRENT_LIST_DIR}/Platform.cpp) +SET_CHECK_CXX_FLAGS(test_platform) +target_link_libraries(test_platform ${GTEST_LIBRARIES} test-common ${LDL} z libopenrct2) +target_link_platform_libraries(test_platform) +add_test(NAME platform COMMAND test_platform) + # String test set(STRING_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/StringTest.cpp" diff --git a/test/tests/Platform.cpp b/test/tests/Platform.cpp new file mode 100644 index 0000000000..d8e345c052 --- /dev/null +++ b/test/tests/Platform.cpp @@ -0,0 +1,30 @@ +/***************************************************************************** + * 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. + *****************************************************************************/ + +#include + +#include + +TEST(platform, sanitise_filename) +{ +#ifndef _WIN32 + ASSERT_EQ("normal-filename.png", platform_sanitise_filename("normal-filename.png")); + ASSERT_EQ("utf🎱", platform_sanitise_filename("utf🎱")); + ASSERT_EQ("forbidden_char", platform_sanitise_filename("forbidden/char")); + ASSERT_EQ("forbidden_\\:\"|?*chars", platform_sanitise_filename("forbidden/\\:\"|?*chars")); + ASSERT_EQ(" non trimmed ", platform_sanitise_filename(" non trimmed ")); +#else + ASSERT_EQ("normal-filename.png", platform_sanitise_filename("normal-filename.png")); + ASSERT_EQ("utf🎱", platform_sanitise_filename("utf🎱")); + ASSERT_EQ("forbidden_char", platform_sanitise_filename("forbidden/char")); + ASSERT_EQ("forbidden_______chars", platform_sanitise_filename("forbidden/\\:\"|?*chars")); + ASSERT_EQ("non trimmed", platform_sanitise_filename(" non trimmed ")); +#endif +} + From ed353faccfb805386f9f0bfc81dc36c96a85c3c4 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Sat, 2 Mar 2019 14:50:15 +0100 Subject: [PATCH 327/506] Implement replace_if condition lambda Fix include typo and CS --- src/openrct2/platform/Shared.cpp | 2 +- src/openrct2/platform/Windows.cpp | 4 ++-- test/tests/Platform.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/openrct2/platform/Shared.cpp b/src/openrct2/platform/Shared.cpp index 050cb2ac13..4c099b39d9 100644 --- a/src/openrct2/platform/Shared.cpp +++ b/src/openrct2/platform/Shared.cpp @@ -208,7 +208,7 @@ std::string platform_sanitise_filename(const std::string& path) std::replace_if( sanitised.begin(), sanitised.end(), - [&prohibited](const std::string::value_type& ch) { + [&prohibited](const std::string::value_type& ch) -> bool { return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); }, '_'); diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 9ebc13ffc9..2dda11b53e 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -22,7 +22,7 @@ # include "../OpenRCT2.h" # include "../Version.h" # include "../config/Config.h" -# include "../core/String.h" +# include "../core/String.hpp" # include "../localisation/Date.h" # include "../localisation/Language.h" # include "../rct2/RCT2.h" @@ -264,7 +264,7 @@ std::string platform_sanitise_filename(const std::string& path) std::replace_if( sanitised.begin(), sanitised.end(), - [](const std::string::value_type& ch) { + [&prohibited](const std::string::value_type& ch) -> bool { return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); }, '_'); diff --git a/test/tests/Platform.cpp b/test/tests/Platform.cpp index d8e345c052..dccea3aad0 100644 --- a/test/tests/Platform.cpp +++ b/test/tests/Platform.cpp @@ -7,9 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include - #include +#include TEST(platform, sanitise_filename) { @@ -27,4 +26,3 @@ TEST(platform, sanitise_filename) ASSERT_EQ("non trimmed", platform_sanitise_filename(" non trimmed ")); #endif } - From 7074d6f3ae4c9059297a31e29da74412adf29aeb Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 May 2019 22:03:17 +0100 Subject: [PATCH 328/506] Apply review suggestions --- distribution/changelog.txt | 4 +-- src/openrct2/interface/Screenshot.cpp | 47 ++++++++++----------------- src/openrct2/platform/Shared.cpp | 7 ++-- src/openrct2/platform/Windows.cpp | 8 ++--- 4 files changed, 23 insertions(+), 43 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 7cbd17abbe..45167eac71 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -25,6 +25,7 @@ - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8507] Incorrect change in vehicle rolling direction. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. +- Fix: [#8598] Taking screenshots fails with some park names. - Fix: [#8649] Setting date does not work in multiplayer. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). @@ -115,8 +116,7 @@ - Fix: [#8585] Part of track missing on air powered vertical coaster. - Fix: [#8588] Guest list scrolling breaks above ~2000 guests. - Fix: [#8591] Game loop does not run at a consistent tick rate of 40 Hz. -- Fix: [#8647] Marketing campaigns check for entry fees below £1 (original bug). -- Fix: [#8598] Sanitize screenshot parknames. +- Fix: [#8647] Marketing campaigns check for entry fees below £1 (original bug). - Fix: [#8653] Crash when peeps attempt to enter a ride with no vehicles. - Fix: [#8720] Desync due to boats colliding with ghost pieces. - Fix: [#8736] Incomplete warning when all ride slots are full. diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 18b49c75d1..ca46599eee 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -107,21 +107,14 @@ static std::string screenshot_get_park_name() return buffer; } -static opt::optional screenshot_get_directory() +static std::string screenshot_get_directory() { char screenshotPath[MAX_PATH]; platform_get_user_directory(screenshotPath, "screenshot", sizeof(screenshotPath)); - - if (platform_ensure_directory_exists(screenshotPath)) - { - return opt::make_optional(screenshotPath); - } - - log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n"); - return opt::nullopt; + return screenshotPath; } -static std::tuple screenshot_get_date_time() +static std::pair screenshot_get_date_time() { rct2_date date; platform_get_date_local(&date); @@ -144,41 +137,35 @@ static std::string screenshot_get_formatted_date_time() static opt::optional screenshot_get_next_path() { - std::string dir, name, suffix = ".png", path; - auto screenshotDirectory = screenshot_get_directory(); - - if (screenshotDirectory == opt::nullopt) + if (!platform_ensure_directory_exists(screenshotDirectory.c_str())) { - return opt::nullopt; + log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n"); + return {}; } auto parkName = screenshot_get_park_name(); auto dateTime = screenshot_get_formatted_date_time(); - - dir = *screenshotDirectory; - name = parkName + " " + dateTime; + auto name = parkName + " " + dateTime; // Generate a path with a `tries` number - auto path_composer = [&dir, &name, &suffix ](int tries) -> auto - { - auto composed_filename = platform_sanitise_filename( - name + ((tries > 0) ? " ("s + std::to_string(tries) + ")" : ""s) + suffix); - return dir + PATH_SEPARATOR + composed_filename; + auto pathComposer = [&screenshotDirectory, &name](int tries) { + auto composedFilename = platform_sanitise_filename( + name + ((tries > 0) ? " ("s + std::to_string(tries) + ")" : ""s) + ".png"); + return screenshotDirectory + PATH_SEPARATOR + composedFilename; }; for (int tries = 0; tries < 100; tries++) { - path = path_composer(tries); - if (platform_file_exists(path.c_str())) - continue; - - return path; + auto path = pathComposer(tries); + if (!platform_file_exists(path.c_str())) + { + return path; + } } log_error("You have too many saved screenshots saved at exactly the same date and time.\n"); - - return opt::nullopt; + return {}; }; std::string screenshot_dump_png(rct_drawpixelinfo* dpi) diff --git a/src/openrct2/platform/Shared.cpp b/src/openrct2/platform/Shared.cpp index 4c099b39d9..7672bf71d0 100644 --- a/src/openrct2/platform/Shared.cpp +++ b/src/openrct2/platform/Shared.cpp @@ -202,17 +202,14 @@ uint8_t platform_get_currency_value(const char* currCode) #ifndef _WIN32 std::string platform_sanitise_filename(const std::string& path) { + static const std::array prohibited = { '/' }; auto sanitised = path; - - std::vector prohibited = { '/' }; - std::replace_if( sanitised.begin(), sanitised.end(), - [&prohibited](const std::string::value_type& ch) -> bool { + [](const std::string::value_type& ch) -> bool { return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); }, '_'); - return sanitised; } #endif diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 2dda11b53e..5167add70b 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -258,19 +258,15 @@ std::string platform_get_rct2_steam_dir() std::string platform_sanitise_filename(const std::string& path) { + static const std::array prohibited = { '<', '>', '*', '\\', ':', '|', '?', '"', '/' }; auto sanitised = path; - - std::vector prohibited = { '<', '>', '*', '\\', ':', '|', '?', '"', '/' }; - std::replace_if( sanitised.begin(), sanitised.end(), - [&prohibited](const std::string::value_type& ch) -> bool { + [](const std::string::value_type& ch) -> bool { return std::find(prohibited.begin(), prohibited.end(), ch) != prohibited.end(); }, '_'); - sanitised = String::Trim(sanitised); - return sanitised; } From 1f6c7c99427ee83bcad21648336e9fad0ea429e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 11 May 2019 18:27:09 +0200 Subject: [PATCH 329/506] Fix false positive desync when changing map during network play --- src/openrct2/network/Network.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 314408b792..f4c3eec266 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -2643,6 +2643,7 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection, { game_load_init(); game_command_queue.clear(); + _serverTickData.clear(); server_tick = gCurrentTicks; // window_network_status_open("Loaded new map from network"); _desynchronised = false; From c8f822ea70ba41deefdef2767235d7ecdd744281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 11 May 2019 21:31:34 +0200 Subject: [PATCH 330/506] Gamestate snapshots (#8819) * Add initial interface. * Implement move operator in MemoryStream * Add pod array serialisation traits. * Add push_back with move semantics to CircularBuffer * Initial implementation of GameStateSnapshots * Add GameStateSnapshots to Context. * Add mp_desync console command. * Compare sprite data and fill change list. * Minor changes. * Proof of concept. * Calculate offset instead of using offsetof * Implement game state difference detection * Update mp_desync console command. * Fix identification of sprite remove/add. * Fix crash when only one peep in park when using mp_desync * Output state differences into user directory desync folder. * Add desync debugging as an option. * Add information to network status when a desync report was created. * Cast to proper type for %llu. * Update xcode project * Add more information to the diffed data. * Remove client-only relevant fields. * Cleanup. * Add better name output for misc sprites * Add srand0 and tick information to the output * Bump up network version * Cleanup * Set desync_debugging to false as default * Apply suggestions --- OpenRCT2.xcodeproj/project.pbxproj | 6 + data/language/en-GB.txt | 1 + src/openrct2/Context.cpp | 9 + src/openrct2/Context.h | 2 + src/openrct2/Game.cpp | 4 + src/openrct2/GameState.cpp | 30 +- src/openrct2/GameState.h | 3 + src/openrct2/GameStateSnapshots.cpp | 578 ++++++++++++++++++ src/openrct2/GameStateSnapshots.h | 108 ++++ src/openrct2/PlatformEnvironment.cpp | 1 + src/openrct2/PlatformEnvironment.h | 1 + src/openrct2/config/Config.cpp | 2 + src/openrct2/config/Config.h | 1 + src/openrct2/core/CircularBuffer.h | 28 + src/openrct2/core/DataSerialiserTraits.h | 58 ++ src/openrct2/core/MemoryStream.cpp | 20 + src/openrct2/core/MemoryStream.h | 3 + src/openrct2/interface/InteractiveConsole.cpp | 61 ++ src/openrct2/localisation/StringIds.h | 3 + src/openrct2/network/Network.cpp | 230 ++++++- src/openrct2/network/NetworkTypes.h | 17 + src/openrct2/network/network.h | 5 +- 22 files changed, 1152 insertions(+), 19 deletions(-) create mode 100644 src/openrct2/GameStateSnapshots.cpp create mode 100644 src/openrct2/GameStateSnapshots.h diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 2d374072be..a7b3e30d16 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -450,6 +450,7 @@ C6E415511FAFD6DC00D4A52A /* RideConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6E415501FAFD6DB00D4A52A /* RideConstruction.cpp */; }; C6E96E361E0408B40076A04F /* libzip.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; }; C6E96E371E040E040076A04F /* libzip.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + C9C630B62235A22D009AD16E /* GameStateSnapshots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9C630B52235A22C009AD16E /* GameStateSnapshots.cpp */; }; D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B73EE1C2101890080A7B9 /* libcurl.tbd */; }; D41B741D1C210A7A0080A7B9 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B741C1C210A7A0080A7B9 /* libiconv.tbd */; }; D41B74731C2125E50080A7B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D41B74721C2125E50080A7B9 /* Assets.xcassets */; }; @@ -1390,6 +1391,8 @@ C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterLowerAction.hpp; sourceTree = ""; }; C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = WaterRaiseAction.hpp; sourceTree = ""; }; C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FootpathPlaceFromTrackAction.hpp; sourceTree = ""; }; + C9C630B42235A22C009AD16E /* GameStateSnapshots.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameStateSnapshots.h; sourceTree = ""; }; + C9C630B52235A22C009AD16E /* GameStateSnapshots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameStateSnapshots.cpp; sourceTree = ""; }; D41B73EE1C2101890080A7B9 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/macos/Assets.xcassets; sourceTree = SOURCE_ROOT; }; @@ -2512,6 +2515,8 @@ F76C83551EC4E7CC00FA49E2 /* libopenrct2 */ = { isa = PBXGroup; children = ( + C9C630B52235A22C009AD16E /* GameStateSnapshots.cpp */, + C9C630B42235A22C009AD16E /* GameStateSnapshots.h */, 4C358E5021C445F700ADE6BC /* ReplayManager.cpp */, 4C358E5121C445F700ADE6BC /* ReplayManager.h */, C6352B871F477032006CCEE3 /* actions */, @@ -3972,6 +3977,7 @@ C68878C220289B710084B384 /* DrawLineShader.cpp in Sources */, F76C888B1EC5324E00FA49E2 /* Ui.cpp in Sources */, C685E51A1F8907850090598F /* Staff.cpp in Sources */, + C9C630B62235A22D009AD16E /* GameStateSnapshots.cpp in Sources */, F76C888C1EC5324E00FA49E2 /* UiContext.cpp in Sources */, C666EE7D1F37ACB10061AA04 /* TitleMenu.cpp in Sources */, 93F6004C213DD7DD00EEB83E /* TerrainSurfaceObject.cpp in Sources */, diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index a6290f01b1..2eeb90605d 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3765,6 +3765,7 @@ STR_6314 :{WINDOW_COLOUR_2}Dest: {BLACK}{INT32}, {INT32} tolerance {INT32} STR_6315 :{WINDOW_COLOUR_2}Pathfind Goal: {BLACK}{INT32}, {INT32}, {INT32} dir {INT32} STR_6316 :{WINDOW_COLOUR_2}Pathfind history: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6318 :Network desync detected.{NEWLINE}Log file: {STRING} ############# # Scenarios # diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 7a39417afc..11674063fe 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -16,6 +16,7 @@ #include "FileClassifier.h" #include "Game.h" #include "GameState.h" +#include "GameStateSnapshots.h" #include "Input.h" #include "Intro.h" #include "OpenRCT2.h" @@ -92,6 +93,7 @@ namespace OpenRCT2 std::unique_ptr _trackDesignRepository; std::unique_ptr _scenarioRepository; std::unique_ptr _replayManager; + std::unique_ptr _gameStateSnapshots; #ifdef __ENABLE_DISCORD__ std::unique_ptr _discordService; #endif @@ -211,6 +213,11 @@ namespace OpenRCT2 return _replayManager.get(); } + IGameStateSnapshots* GetGameStateSnapshots() override + { + return _gameStateSnapshots.get(); + } + int32_t GetDrawingEngineType() override { return _drawingEngineType; @@ -340,6 +347,7 @@ namespace OpenRCT2 _trackDesignRepository = CreateTrackDesignRepository(_env); _scenarioRepository = CreateScenarioRepository(_env); _replayManager = CreateReplayManager(); + _gameStateSnapshots = CreateGameStateSnapshots(); #ifdef __ENABLE_DISCORD__ _discordService = std::make_unique(); #endif @@ -994,6 +1002,7 @@ namespace OpenRCT2 DIRID::THEME, DIRID::SEQUENCE, DIRID::REPLAY, + DIRID::LOG_DESYNCS, }); } diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index dfe2479034..5e147c33ad 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -19,6 +19,7 @@ interface IObjectRepository; interface IScenarioRepository; interface IStream; interface ITrackDesignRepository; +interface IGameStateSnapshots; class Intent; struct rct_window; @@ -110,6 +111,7 @@ namespace OpenRCT2 virtual ITrackDesignRepository* GetTrackDesignRepository() abstract; virtual IScenarioRepository* GetScenarioRepository() abstract; virtual IReplayManager* GetReplayManager() abstract; + virtual IGameStateSnapshots* GetGameStateSnapshots() abstract; virtual int32_t GetDrawingEngineType() abstract; virtual Drawing::IDrawingEngine* GetDrawingEngine() abstract; virtual Paint::Painter* GetPainter() abstract; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 0901871363..08d131f8f3 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -13,6 +13,7 @@ #include "Context.h" #include "Editor.h" #include "FileClassifier.h" +#include "GameStateSnapshots.h" #include "Input.h" #include "OpenRCT2.h" #include "ParkImporter.h" @@ -847,6 +848,9 @@ void game_load_init() { rct_window* mainWindow; + IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots(); + snapshots->Reset(); + gScreenFlags = SCREEN_FLAGS_PLAYING; audio_stop_all_music_and_sounds(); if (!gLoadKeepWindowsOpen) diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index fc4544aa59..ebafbd0e3b 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -12,9 +12,11 @@ #include "Context.h" #include "Editor.h" #include "Game.h" +#include "GameStateSnapshots.h" #include "Input.h" #include "OpenRCT2.h" #include "ReplayManager.h" +#include "config/Config.h" #include "interface/Screenshot.h" #include "localisation/Date.h" #include "localisation/Localisation.h" @@ -238,13 +240,30 @@ void GameState::UpdateLogic() if (network_get_mode() == NETWORK_MODE_SERVER) { + if (network_gamestate_snapshots_enabled()) + { + CreateStateSnapshot(); + } + // Send current tick out. network_send_tick(); } else if (network_get_mode() == NETWORK_MODE_CLIENT) { // Check desync. - network_check_desynchronization(); + bool desynced = network_check_desynchronisation(); + if (desynced) + { + // If desync debugging is enabled and we are still connected request the specific game state from server. + if (network_gamestate_snapshots_enabled() && network_get_status() == NETWORK_STATUS_CONNECTED) + { + // Create snapshot from this tick so we can compare it later + // as we won't pause the game on this event. + CreateStateSnapshot(); + + network_request_gamestate_snapshot(); + } + } } date_update(); @@ -311,3 +330,12 @@ void GameState::UpdateLogic() gScenarioTicks++; gSavedAge++; } + +void GameState::CreateStateSnapshot() +{ + IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots(); + + auto& snapshot = snapshots->CreateSnapshot(); + snapshots->Capture(snapshot); + snapshots->LinkSnapshot(snapshot, gCurrentTicks, scenario_rand_state().s0); +} diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index b613163c64..83bad8a89e 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -42,5 +42,8 @@ namespace OpenRCT2 void InitAll(int32_t mapSize); void Update(); void UpdateLogic(); + + private: + void CreateStateSnapshot(); }; } // namespace OpenRCT2 diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp new file mode 100644 index 0000000000..9307dc3c8a --- /dev/null +++ b/src/openrct2/GameStateSnapshots.cpp @@ -0,0 +1,578 @@ +#include "GameStateSnapshots.h" + +#include "core/CircularBuffer.h" +#include "peep/Peep.h" +#include "world/Sprite.h" + +static constexpr size_t MaximumGameStateSnapshots = 32; +static constexpr uint32_t InvalidTick = 0xFFFFFFFF; + +struct GameStateSnapshot_t +{ + GameStateSnapshot_t& operator=(GameStateSnapshot_t&& mv) + { + tick = mv.tick; + storedSprites = std::move(mv.storedSprites); + return *this; + } + + uint32_t tick = InvalidTick; + uint32_t srand0 = 0; + + MemoryStream storedSprites; + MemoryStream parkParameters; + + void SerialiseSprites(rct_sprite* sprites, const size_t numSprites, bool saving) + { + const bool loading = !saving; + + storedSprites.SetPosition(0); + DataSerialiser ds(saving, storedSprites); + + std::vector indexTable; + indexTable.reserve(numSprites); + + uint32_t numSavedSprites = 0; + + if (saving) + { + for (size_t i = 0; i < numSprites; i++) + { + if (sprites[i].generic.sprite_identifier == SPRITE_IDENTIFIER_NULL) + continue; + indexTable.push_back((uint32_t)i); + } + numSavedSprites = (uint32_t)indexTable.size(); + } + + ds << numSavedSprites; + + if (loading) + { + indexTable.resize(numSavedSprites); + } + + for (uint32_t i = 0; i < numSavedSprites; i++) + { + ds << indexTable[i]; + + const uint32_t spriteIdx = indexTable[i]; + rct_sprite& sprite = sprites[spriteIdx]; + + ds << sprite.generic.sprite_identifier; + + switch (sprite.generic.sprite_identifier) + { + case SPRITE_IDENTIFIER_VEHICLE: + ds << reinterpret_cast(sprite.vehicle); + break; + case SPRITE_IDENTIFIER_PEEP: + ds << reinterpret_cast(sprite.peep); + break; + case SPRITE_IDENTIFIER_LITTER: + ds << reinterpret_cast(sprite.litter); + break; + case SPRITE_IDENTIFIER_MISC: + { + ds << sprite.generic.type; + switch (sprite.generic.type) + { + case SPRITE_MISC_MONEY_EFFECT: + ds << reinterpret_cast(sprite.money_effect); + break; + case SPRITE_MISC_BALLOON: + ds << reinterpret_cast(sprite.balloon); + break; + case SPRITE_MISC_DUCK: + ds << reinterpret_cast(sprite.duck); + break; + case SPRITE_MISC_JUMPING_FOUNTAIN_WATER: + ds << reinterpret_cast(sprite.jumping_fountain); + break; + case SPRITE_MISC_STEAM_PARTICLE: + ds << reinterpret_cast(sprite.steam_particle); + break; + } + } + break; + } + } + } +}; + +struct GameStateSnapshots : public IGameStateSnapshots +{ + virtual void Reset() override final + { + _snapshots.clear(); + } + + virtual GameStateSnapshot_t& CreateSnapshot() override final + { + auto snapshot = std::make_unique(); + _snapshots.push_back(std::move(snapshot)); + + return *_snapshots.back(); + } + + virtual void LinkSnapshot(GameStateSnapshot_t& snapshot, uint32_t tick, uint32_t srand0) override final + { + snapshot.tick = tick; + snapshot.srand0 = srand0; + } + + virtual void Capture(GameStateSnapshot_t& snapshot) override final + { + snapshot.SerialiseSprites(get_sprite(0), MAX_SPRITES, true); + + // log_info("Snapshot size: %u bytes\n", (uint32_t)snapshot.storedSprites.GetLength()); + } + + virtual const GameStateSnapshot_t* GetLinkedSnapshot(uint32_t tick) const override final + { + for (size_t i = 0; i < _snapshots.size(); i++) + { + if (_snapshots[i]->tick == tick) + return _snapshots[i].get(); + } + return nullptr; + } + + virtual void SerialiseSnapshot(GameStateSnapshot_t& snapshot, DataSerialiser& ds) const override final + { + ds << snapshot.tick; + ds << snapshot.srand0; + ds << snapshot.storedSprites; + ds << snapshot.parkParameters; + } + + std::vector BuildSpriteList(GameStateSnapshot_t& snapshot) const + { + std::vector spriteList; + spriteList.resize(MAX_SPRITES); + + for (auto& sprite : spriteList) + { + // By default they don't exist. + sprite.generic.sprite_identifier = SPRITE_IDENTIFIER_NULL; + } + + snapshot.SerialiseSprites(spriteList.data(), MAX_SPRITES, false); + + return spriteList; + } + +#define COMPARE_FIELD(struc, field) \ + if (std::memcmp(&spriteBase.field, &spriteCmp.field, sizeof(struc::field)) != 0) \ + { \ + uint64_t valA = 0; \ + uint64_t valB = 0; \ + std::memcpy(&valA, &spriteBase.field, sizeof(struc::field)); \ + std::memcpy(&valB, &spriteCmp.field, sizeof(struc::field)); \ + uintptr_t offset = reinterpret_cast(&spriteBase.field) - reinterpret_cast(&spriteBase); \ + changeData.diffs.push_back( \ + GameStateSpriteChange_t::Diff_t{ (size_t)offset, sizeof(struc::field), #struc, #field, valA, valB }); \ + } + + void CompareSpriteDataCommon( + const rct_sprite_common& spriteBase, const rct_sprite_common& spriteCmp, GameStateSpriteChange_t& changeData) const + { + COMPARE_FIELD(rct_sprite_common, sprite_identifier); + COMPARE_FIELD(rct_sprite_common, type); + COMPARE_FIELD(rct_sprite_common, next_in_quadrant); + COMPARE_FIELD(rct_sprite_common, next); + COMPARE_FIELD(rct_sprite_common, previous); + COMPARE_FIELD(rct_sprite_common, linked_list_type_offset); + COMPARE_FIELD(rct_sprite_common, sprite_index); + COMPARE_FIELD(rct_sprite_common, flags); + COMPARE_FIELD(rct_sprite_common, x); + COMPARE_FIELD(rct_sprite_common, y); + COMPARE_FIELD(rct_sprite_common, z); + /* Only relevant for rendering, does not affect game state. + COMPARE_FIELD(rct_sprite_common, sprite_width); + COMPARE_FIELD(rct_sprite_common, sprite_height_negative); + COMPARE_FIELD(rct_sprite_common, sprite_height_positive); + COMPARE_FIELD(rct_sprite_common, sprite_left); + COMPARE_FIELD(rct_sprite_common, sprite_top); + COMPARE_FIELD(rct_sprite_common, sprite_right); + COMPARE_FIELD(rct_sprite_common, sprite_bottom); + */ + COMPARE_FIELD(rct_sprite_common, sprite_direction); + } + + void CompareSpriteDataPeep(const Peep& spriteBase, const Peep& spriteCmp, GameStateSpriteChange_t& changeData) const + { + COMPARE_FIELD(Peep, name_string_idx); + COMPARE_FIELD(Peep, next_x); + COMPARE_FIELD(Peep, next_y); + COMPARE_FIELD(Peep, next_z); + COMPARE_FIELD(Peep, next_flags); + COMPARE_FIELD(Peep, outside_of_park); + COMPARE_FIELD(Peep, state); + COMPARE_FIELD(Peep, sub_state); + COMPARE_FIELD(Peep, sprite_type); + COMPARE_FIELD(Peep, type); + COMPARE_FIELD(Peep, no_of_rides); + COMPARE_FIELD(Peep, tshirt_colour); + COMPARE_FIELD(Peep, trousers_colour); + COMPARE_FIELD(Peep, destination_x); + COMPARE_FIELD(Peep, destination_y); + COMPARE_FIELD(Peep, destination_tolerance); + COMPARE_FIELD(Peep, var_37); + COMPARE_FIELD(Peep, energy); + COMPARE_FIELD(Peep, energy_target); + COMPARE_FIELD(Peep, happiness); + COMPARE_FIELD(Peep, happiness_target); + COMPARE_FIELD(Peep, nausea); + COMPARE_FIELD(Peep, nausea_target); + COMPARE_FIELD(Peep, hunger); + COMPARE_FIELD(Peep, thirst); + COMPARE_FIELD(Peep, toilet); + COMPARE_FIELD(Peep, mass); + COMPARE_FIELD(Peep, time_to_consume); + COMPARE_FIELD(Peep, intensity); + COMPARE_FIELD(Peep, nausea_tolerance); + COMPARE_FIELD(Peep, window_invalidate_flags); + COMPARE_FIELD(Peep, paid_on_drink); + for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) + { + COMPARE_FIELD(Peep, ride_types_been_on[i]); + } + COMPARE_FIELD(Peep, item_extra_flags); + COMPARE_FIELD(Peep, photo2_ride_ref); + COMPARE_FIELD(Peep, photo3_ride_ref); + COMPARE_FIELD(Peep, photo4_ride_ref); + COMPARE_FIELD(Peep, current_ride); + COMPARE_FIELD(Peep, current_ride_station); + COMPARE_FIELD(Peep, current_train); + COMPARE_FIELD(Peep, time_to_sitdown); + COMPARE_FIELD(Peep, special_sprite); + COMPARE_FIELD(Peep, action_sprite_type); + COMPARE_FIELD(Peep, next_action_sprite_type); + COMPARE_FIELD(Peep, action_sprite_image_offset); + COMPARE_FIELD(Peep, action); + COMPARE_FIELD(Peep, action_frame); + COMPARE_FIELD(Peep, step_progress); + COMPARE_FIELD(Peep, next_in_queue); + COMPARE_FIELD(Peep, maze_last_edge); + COMPARE_FIELD(Peep, interaction_ride_index); + COMPARE_FIELD(Peep, time_in_queue); + for (int i = 0; i < 32; i++) + { + COMPARE_FIELD(Peep, rides_been_on[i]); + } + COMPARE_FIELD(Peep, id); + COMPARE_FIELD(Peep, cash_in_pocket); + COMPARE_FIELD(Peep, cash_spent); + COMPARE_FIELD(Peep, time_in_park); + COMPARE_FIELD(Peep, rejoin_queue_timeout); + COMPARE_FIELD(Peep, previous_ride); + COMPARE_FIELD(Peep, previous_ride_time_out); + for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) + { + COMPARE_FIELD(Peep, thoughts[i]); + } + COMPARE_FIELD(Peep, path_check_optimisation); + COMPARE_FIELD(Peep, guest_heading_to_ride_id); + COMPARE_FIELD(Peep, staff_orders); + COMPARE_FIELD(Peep, photo1_ride_ref); + COMPARE_FIELD(Peep, peep_flags); + COMPARE_FIELD(Peep, pathfind_goal); + for (int i = 0; i < 4; i++) + { + COMPARE_FIELD(Peep, pathfind_history[i]); + } + COMPARE_FIELD(Peep, no_action_frame_num); + COMPARE_FIELD(Peep, litter_count); + COMPARE_FIELD(Peep, time_on_ride); + COMPARE_FIELD(Peep, disgusting_count); + COMPARE_FIELD(Peep, paid_to_enter); + COMPARE_FIELD(Peep, paid_on_rides); + COMPARE_FIELD(Peep, paid_on_food); + COMPARE_FIELD(Peep, paid_on_souvenirs); + COMPARE_FIELD(Peep, no_of_food); + COMPARE_FIELD(Peep, no_of_drinks); + COMPARE_FIELD(Peep, no_of_souvenirs); + COMPARE_FIELD(Peep, vandalism_seen); + COMPARE_FIELD(Peep, voucher_type); + COMPARE_FIELD(Peep, voucher_arguments); + COMPARE_FIELD(Peep, surroundings_thought_timeout); + COMPARE_FIELD(Peep, angriness); + COMPARE_FIELD(Peep, time_lost); + COMPARE_FIELD(Peep, days_in_queue); + COMPARE_FIELD(Peep, balloon_colour); + COMPARE_FIELD(Peep, umbrella_colour); + COMPARE_FIELD(Peep, hat_colour); + COMPARE_FIELD(Peep, favourite_ride); + COMPARE_FIELD(Peep, favourite_ride_rating); + COMPARE_FIELD(Peep, item_standard_flags); + } + + void CompareSpriteDataVehicle( + const rct_vehicle& spriteBase, const rct_vehicle& spriteCmp, GameStateSpriteChange_t& changeData) const + { + COMPARE_FIELD(rct_vehicle, vehicle_sprite_type); + COMPARE_FIELD(rct_vehicle, bank_rotation); + COMPARE_FIELD(rct_vehicle, remaining_distance); + COMPARE_FIELD(rct_vehicle, velocity); + COMPARE_FIELD(rct_vehicle, acceleration); + COMPARE_FIELD(rct_vehicle, ride); + COMPARE_FIELD(rct_vehicle, vehicle_type); + COMPARE_FIELD(rct_vehicle, colours); + COMPARE_FIELD(rct_vehicle, track_progress); + COMPARE_FIELD(rct_vehicle, track_direction); + COMPARE_FIELD(rct_vehicle, track_x); + COMPARE_FIELD(rct_vehicle, track_y); + COMPARE_FIELD(rct_vehicle, track_z); + COMPARE_FIELD(rct_vehicle, next_vehicle_on_train); + COMPARE_FIELD(rct_vehicle, prev_vehicle_on_ride); + COMPARE_FIELD(rct_vehicle, next_vehicle_on_ride); + COMPARE_FIELD(rct_vehicle, var_44); + COMPARE_FIELD(rct_vehicle, mass); + COMPARE_FIELD(rct_vehicle, update_flags); + COMPARE_FIELD(rct_vehicle, swing_sprite); + COMPARE_FIELD(rct_vehicle, current_station); + COMPARE_FIELD(rct_vehicle, swinging_car_var_0); + COMPARE_FIELD(rct_vehicle, var_4E); + COMPARE_FIELD(rct_vehicle, status); + COMPARE_FIELD(rct_vehicle, sub_state); + for (int i = 0; i < 32; i++) + { + COMPARE_FIELD(rct_vehicle, peep[i]); + } + for (int i = 0; i < 32; i++) + { + COMPARE_FIELD(rct_vehicle, peep_tshirt_colours[i]); + } + COMPARE_FIELD(rct_vehicle, num_seats); + COMPARE_FIELD(rct_vehicle, num_peeps); + COMPARE_FIELD(rct_vehicle, next_free_seat); + COMPARE_FIELD(rct_vehicle, restraints_position); + COMPARE_FIELD(rct_vehicle, spin_speed); + COMPARE_FIELD(rct_vehicle, sound2_flags); + COMPARE_FIELD(rct_vehicle, spin_sprite); + COMPARE_FIELD(rct_vehicle, sound1_id); + COMPARE_FIELD(rct_vehicle, sound1_volume); + COMPARE_FIELD(rct_vehicle, sound2_id); + COMPARE_FIELD(rct_vehicle, sound2_volume); + COMPARE_FIELD(rct_vehicle, sound_vector_factor); + COMPARE_FIELD(rct_vehicle, cable_lift_target); + COMPARE_FIELD(rct_vehicle, speed); + COMPARE_FIELD(rct_vehicle, powered_acceleration); + COMPARE_FIELD(rct_vehicle, var_C4); + COMPARE_FIELD(rct_vehicle, animation_frame); + for (int i = 0; i < 2; i++) + { + COMPARE_FIELD(rct_vehicle, pad_C6[i]); + } + COMPARE_FIELD(rct_vehicle, var_C8); + COMPARE_FIELD(rct_vehicle, var_CA); + COMPARE_FIELD(rct_vehicle, scream_sound_id); + COMPARE_FIELD(rct_vehicle, var_CD); + COMPARE_FIELD(rct_vehicle, num_laps); + COMPARE_FIELD(rct_vehicle, brake_speed); + COMPARE_FIELD(rct_vehicle, lost_time_out); + COMPARE_FIELD(rct_vehicle, vertical_drop_countdown); + COMPARE_FIELD(rct_vehicle, var_D3); + COMPARE_FIELD(rct_vehicle, mini_golf_current_animation); + COMPARE_FIELD(rct_vehicle, mini_golf_flags); + COMPARE_FIELD(rct_vehicle, ride_subtype); + COMPARE_FIELD(rct_vehicle, colours_extended); + COMPARE_FIELD(rct_vehicle, seat_rotation); + COMPARE_FIELD(rct_vehicle, target_seat_rotation); + } + + void CompareSpriteDataLitter( + const rct_litter& spriteBase, const rct_litter& spriteCmp, GameStateSpriteChange_t& changeData) const + { + COMPARE_FIELD(rct_litter, creationTick); + } + + void CompareSpriteData(const rct_sprite& spriteBase, const rct_sprite& spriteCmp, GameStateSpriteChange_t& changeData) const + { + CompareSpriteDataCommon(spriteBase.generic, spriteCmp.generic, changeData); + if (spriteBase.generic.sprite_identifier == spriteCmp.generic.sprite_identifier) + { + switch (spriteBase.generic.sprite_identifier) + { + case SPRITE_IDENTIFIER_PEEP: + CompareSpriteDataPeep(spriteBase.peep, spriteCmp.peep, changeData); + break; + case SPRITE_IDENTIFIER_VEHICLE: + CompareSpriteDataVehicle(spriteBase.vehicle, spriteCmp.vehicle, changeData); + break; + case SPRITE_IDENTIFIER_LITTER: + CompareSpriteDataLitter(spriteBase.litter, spriteCmp.litter, changeData); + break; + } + } + } + + virtual GameStateCompareData_t Compare(const GameStateSnapshot_t& base, const GameStateSnapshot_t& cmp) const override final + { + GameStateCompareData_t res; + res.tick = base.tick; + res.srand0Left = base.srand0; + res.srand0Right = cmp.srand0; + + std::vector spritesBase = BuildSpriteList(const_cast(base)); + std::vector spritesCmp = BuildSpriteList(const_cast(cmp)); + + for (uint32_t i = 0; i < (uint32_t)spritesBase.size(); i++) + { + GameStateSpriteChange_t changeData; + changeData.spriteIndex = i; + + const rct_sprite& spriteBase = spritesBase[i]; + const rct_sprite& spriteCmp = spritesCmp[i]; + + changeData.spriteIdentifier = spriteBase.generic.sprite_identifier; + changeData.miscIdentifier = spriteBase.generic.type; + + if (spriteBase.generic.sprite_identifier == SPRITE_IDENTIFIER_NULL + && spriteCmp.generic.sprite_identifier != SPRITE_IDENTIFIER_NULL) + { + // Sprite was added. + changeData.changeType = GameStateSpriteChange_t::ADDED; + changeData.spriteIdentifier = spriteCmp.generic.sprite_identifier; + } + else if ( + spriteBase.generic.sprite_identifier != SPRITE_IDENTIFIER_NULL + && spriteCmp.generic.sprite_identifier == SPRITE_IDENTIFIER_NULL) + { + // Sprite was removed. + changeData.changeType = GameStateSpriteChange_t::REMOVED; + changeData.spriteIdentifier = spriteBase.generic.sprite_identifier; + } + else if ( + spriteBase.generic.sprite_identifier == SPRITE_IDENTIFIER_NULL + && spriteCmp.generic.sprite_identifier == SPRITE_IDENTIFIER_NULL) + { + // Do nothing. + changeData.changeType = GameStateSpriteChange_t::EQUAL; + } + else + { + CompareSpriteData(spriteBase, spriteCmp, changeData); + if (changeData.diffs.size() == 0) + { + changeData.changeType = GameStateSpriteChange_t::EQUAL; + } + else + { + changeData.changeType = GameStateSpriteChange_t::MODIFIED; + } + } + + res.spriteChanges.push_back(changeData); + } + + return res; + } + + static const char* GetSpriteIdentifierName(uint32_t spriteIdentifier, uint8_t miscIdentifier) + { + switch (spriteIdentifier) + { + case SPRITE_IDENTIFIER_NULL: + return "Null"; + case SPRITE_IDENTIFIER_PEEP: + return "Peep"; + case SPRITE_IDENTIFIER_VEHICLE: + return "Vehicle"; + case SPRITE_IDENTIFIER_LITTER: + return "Litter"; + case SPRITE_IDENTIFIER_MISC: + switch (miscIdentifier) + { + case SPRITE_MISC_STEAM_PARTICLE: + return "Misc: Steam Particle"; + case SPRITE_MISC_MONEY_EFFECT: + return "Misc: Money effect"; + case SPRITE_MISC_CRASHED_VEHICLE_PARTICLE: + return "Misc: Crash Vehicle Particle"; + case SPRITE_MISC_EXPLOSION_CLOUD: + return "Misc: Explosion Cloud"; + case SPRITE_MISC_CRASH_SPLASH: + return "Misc: Crash Splash"; + case SPRITE_MISC_EXPLOSION_FLARE: + return "Misc: Explosion Flare"; + case SPRITE_MISC_JUMPING_FOUNTAIN_WATER: + return "Misc: Jumping fountain water"; + case SPRITE_MISC_BALLOON: + return "Misc: Balloon"; + case SPRITE_MISC_DUCK: + return "Misc: Duck"; + case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW: + return "Misc: Jumping fountain snow"; + } + return "Misc"; + } + return "Unknown"; + } + + virtual bool LogCompareDataToFile(const std::string& fileName, const GameStateCompareData_t& cmpData) const override + { + std::string outputBuffer; + char tempBuffer[1024] = {}; + + snprintf(tempBuffer, sizeof(tempBuffer), "tick: %08X\n", cmpData.tick); + outputBuffer += tempBuffer; + + snprintf( + tempBuffer, sizeof(tempBuffer), "srand0 left = %08X, srand0 right = %08X\n", cmpData.srand0Left, + cmpData.srand0Right); + outputBuffer += tempBuffer; + + for (auto& change : cmpData.spriteChanges) + { + if (change.changeType == GameStateSpriteChange_t::EQUAL) + continue; + + const char* typeName = GetSpriteIdentifierName(change.spriteIdentifier, change.miscIdentifier); + + if (change.changeType == GameStateSpriteChange_t::ADDED) + { + snprintf(tempBuffer, sizeof(tempBuffer), "Sprite added (%s), index: %u\n", typeName, change.spriteIndex); + outputBuffer += tempBuffer; + } + else if (change.changeType == GameStateSpriteChange_t::REMOVED) + { + snprintf(tempBuffer, sizeof(tempBuffer), "Sprite removed (%s), index: %u\n", typeName, change.spriteIndex); + outputBuffer += tempBuffer; + } + else if (change.changeType == GameStateSpriteChange_t::MODIFIED) + { + snprintf( + tempBuffer, sizeof(tempBuffer), "Sprite modifications (%s), index: %u\n", typeName, change.spriteIndex); + outputBuffer += tempBuffer; + for (auto& diff : change.diffs) + { + snprintf( + tempBuffer, sizeof(tempBuffer), + " %s::%s, len = %u, offset = %u, left = 0x%.16llX, right = 0x%.16llX\n", diff.structname, + diff.fieldname, (uint32_t)diff.length, (uint32_t)diff.offset, (unsigned long long)diff.valueA, + (unsigned long long)diff.valueB); + outputBuffer += tempBuffer; + } + } + } + + FILE* fp = fopen(fileName.c_str(), "wt"); + if (!fp) + return false; + + fputs(outputBuffer.c_str(), fp); + fclose(fp); + + return true; + } + +private: + CircularBuffer, MaximumGameStateSnapshots> _snapshots; +}; + +std::unique_ptr CreateGameStateSnapshots() +{ + return std::make_unique(); +} diff --git a/src/openrct2/GameStateSnapshots.h b/src/openrct2/GameStateSnapshots.h new file mode 100644 index 0000000000..235a5e697d --- /dev/null +++ b/src/openrct2/GameStateSnapshots.h @@ -0,0 +1,108 @@ +/***************************************************************************** + * 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 "common.h" +#include "core/DataSerialiser.h" + +#include +#include +#include + +struct GameStateSnapshot_t; + +struct GameStateSpriteChange_t +{ + enum + { + REMOVED, + ADDED, + MODIFIED, + EQUAL + }; + + struct Diff_t + { + size_t offset; + size_t length; + const char* structname; + const char* fieldname; + uint64_t valueA; + uint64_t valueB; + }; + + uint8_t changeType; + uint8_t spriteIdentifier; + uint8_t miscIdentifier; + uint32_t spriteIndex; + + std::vector diffs; +}; + +struct GameStateCompareData_t +{ + uint32_t tick; + uint32_t srand0Left; + uint32_t srand0Right; + std::vector spriteChanges; +}; + +/* + * Interface to create and capture game states. It only allows to have 32 active snapshots + * the oldest snapshot will be removed from the buffer. Never store the snapshot pointer + * as it may become invalid at any time when a snapshot is created, rather Link the snapshot + * to a specific tick which can be obtained by that later again assuming its still valid. + */ +interface IGameStateSnapshots +{ + virtual ~IGameStateSnapshots() = default; + + /* + * Removes all existing entries and starts over. + */ + virtual void Reset() = 0; + + /* + * Creates a new empty snapshot, oldest snapshot will be removed. + */ + virtual GameStateSnapshot_t& CreateSnapshot() = 0; + + /* + * Links the snapshot to a specific game tick. + */ + virtual void LinkSnapshot(GameStateSnapshot_t & snapshot, uint32_t tick, uint32_t srand0) = 0; + + /* + * This will fill the snapshot with the current game state in a compact form. + */ + virtual void Capture(GameStateSnapshot_t & snapshot) = 0; + + /* + * Returns the snapshot for a given tick in the history, nullptr if not found. + */ + virtual const GameStateSnapshot_t* GetLinkedSnapshot(uint32_t tick) const = 0; + + /* + * Serialisation of GameStateSnapshot_t + */ + virtual void SerialiseSnapshot(GameStateSnapshot_t & snapshot, DataSerialiser & serialiser) const = 0; + + /* + * Compares two states resulting GameStateCompareData_t with all mismatches stored. + */ + virtual GameStateCompareData_t Compare(const GameStateSnapshot_t& base, const GameStateSnapshot_t& cmp) const = 0; + + /* + * Writes the GameStateCompareData_t into the specified file as readable text. + */ + virtual bool LogCompareDataToFile(const std::string& fileName, const GameStateCompareData_t& cmpData) const = 0; +}; + +std::unique_ptr CreateGameStateSnapshots(); diff --git a/src/openrct2/PlatformEnvironment.cpp b/src/openrct2/PlatformEnvironment.cpp index 45314a1c05..9e1fd90522 100644 --- a/src/openrct2/PlatformEnvironment.cpp +++ b/src/openrct2/PlatformEnvironment.cpp @@ -221,6 +221,7 @@ const char * PlatformEnvironment::DirectoryNamesOpenRCT2[] = "track", // TRACK "heightmap", // HEIGHTMAP "replay", // REPLAY + "desyncs", // DESYNCS }; const char * PlatformEnvironment::FileNames[] = diff --git a/src/openrct2/PlatformEnvironment.h b/src/openrct2/PlatformEnvironment.h index d912e29285..2df41e60ee 100644 --- a/src/openrct2/PlatformEnvironment.h +++ b/src/openrct2/PlatformEnvironment.h @@ -47,6 +47,7 @@ namespace OpenRCT2 TRACK, // Contains track designs. HEIGHTMAP, // Contains heightmap data. REPLAY, // Contains recorded replays. + LOG_DESYNCS, // Contains desync reports. }; enum class PATHID diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index c34aaa9f0a..edb4251b28 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -395,6 +395,7 @@ namespace Config model->log_chat = reader->GetBoolean("log_chat", false); model->log_server_actions = reader->GetBoolean("log_server_actions", false); model->pause_server_if_no_clients = reader->GetBoolean("pause_server_if_no_clients", false); + model->desync_debugging = reader->GetBoolean("desync_debugging", false); } } @@ -420,6 +421,7 @@ namespace Config writer->WriteBoolean("log_chat", model->log_chat); writer->WriteBoolean("log_server_actions", model->log_server_actions); writer->WriteBoolean("pause_server_if_no_clients", model->pause_server_if_no_clients); + writer->WriteBoolean("desync_debugging", model->desync_debugging); } static void ReadNotifications(IIniReader* reader) diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 5d6ffc477e..b346365967 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -156,6 +156,7 @@ struct NetworkConfiguration bool log_chat; bool log_server_actions; bool pause_server_if_no_clients; + bool desync_debugging; }; struct NotificationConfiguration diff --git a/src/openrct2/core/CircularBuffer.h b/src/openrct2/core/CircularBuffer.h index a46da8e787..c7c4f1cec9 100644 --- a/src/openrct2/core/CircularBuffer.h +++ b/src/openrct2/core/CircularBuffer.h @@ -104,6 +104,34 @@ public: } } + void push_back(value_type&& val) + { + if (_size == 0) + { + _elements[_head] = std::move(val); + _tail = _head; + _size++; + } + else if (_size != capacity()) + { + _tail++; + if (_tail == capacity()) + _tail = 0; + _size++; + _elements[_tail] = std::move(val); + } + else + { + _head++; + if (_head == capacity()) + _head = 0; + _tail++; + if (_tail == capacity()) + _tail = 0; + _elements[_tail] = std::move(val); + } + } + private: size_t _head = 0; size_t _tail = 0; diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index a55bdf8aa5..fe69c07e84 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -253,6 +253,64 @@ template<> struct DataSerializerTraits } }; +template struct DataSerializerTraitsPODArray +{ + static void encode(IStream* stream, const _Ty (&val)[_Size]) + { + uint16_t len = (uint16_t)_Size; + uint16_t swapped = ByteSwapBE(len); + stream->Write(&swapped); + + DataSerializerTraits s; + for (auto&& sub : val) + { + s.encode(stream, sub); + } + } + static void decode(IStream* stream, _Ty (&val)[_Size]) + { + uint16_t len; + stream->Read(&len); + len = ByteSwapBE(len); + + if (len != _Size) + throw std::runtime_error("Invalid size, can't decode"); + + DataSerializerTraits<_Ty> s; + for (auto&& sub : val) + { + s.decode(stream, sub); + } + } + static void log(IStream* stream, const _Ty (&val)[_Size]) + { + stream->Write("{", 1); + DataSerializerTraits<_Ty> s; + for (auto&& sub : val) + { + s.log(stream, sub); + stream->Write("; ", 2); + } + stream->Write("}", 1); + } +}; + +template struct DataSerializerTraits : public DataSerializerTraitsPODArray +{ +}; + +template struct DataSerializerTraits : public DataSerializerTraitsPODArray +{ +}; + +template struct DataSerializerTraits : public DataSerializerTraitsPODArray +{ +}; + +template struct DataSerializerTraits : public DataSerializerTraitsPODArray +{ +}; + template struct DataSerializerTraits> { static void encode(IStream* stream, const std::array<_Ty, _Size>& val) diff --git a/src/openrct2/core/MemoryStream.cpp b/src/openrct2/core/MemoryStream.cpp index b58f5b87f6..fcae646afc 100644 --- a/src/openrct2/core/MemoryStream.cpp +++ b/src/openrct2/core/MemoryStream.cpp @@ -49,6 +49,11 @@ MemoryStream::MemoryStream(const void* data, size_t dataSize) { } +MemoryStream::MemoryStream(MemoryStream&& mv) +{ + *this = std::move(mv); +} + MemoryStream::~MemoryStream() { if (_access & MEMORY_ACCESS::OWNER) @@ -60,6 +65,21 @@ MemoryStream::~MemoryStream() _data = nullptr; } +MemoryStream& MemoryStream::operator=(MemoryStream&& mv) +{ + _access = mv._access; + _dataCapacity = mv._dataCapacity; + _data = mv._data; + _position = mv._position; + + mv._data = nullptr; + mv._position = nullptr; + mv._dataCapacity = 0; + mv._dataSize = 0; + + return *this; +} + const void* MemoryStream::GetData() const { return _data; diff --git a/src/openrct2/core/MemoryStream.h b/src/openrct2/core/MemoryStream.h index aca6badb0f..e1ac6870fb 100644 --- a/src/openrct2/core/MemoryStream.h +++ b/src/openrct2/core/MemoryStream.h @@ -34,11 +34,14 @@ private: public: MemoryStream() = default; MemoryStream(const MemoryStream& copy); + MemoryStream(MemoryStream&& mv); explicit MemoryStream(size_t capacity); MemoryStream(void* data, size_t dataSize, uint8_t access = MEMORY_ACCESS::READ); MemoryStream(const void* data, size_t dataSize); virtual ~MemoryStream(); + MemoryStream& operator=(MemoryStream&& mv); + const void* GetData() const; void* GetDataCopy() const; void* TakeData(); diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index eebeea7f4d..1a2e574e37 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1549,6 +1549,66 @@ static int32_t cc_replay_normalise(InteractiveConsole& console, const arguments_ return 0; } +static int32_t cc_mp_desync(InteractiveConsole& console, const arguments_t& argv) +{ + int32_t desyncType = 0; + if (argv.size() >= 1) + { + desyncType = atoi(argv[0].c_str()); + } + + std::vector peeps; + std::vector vehicles; + + for (int i = 0; i < MAX_SPRITES; i++) + { + rct_sprite* sprite = get_sprite(i); + if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_NULL) + continue; + + if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_PEEP) + peeps.push_back(sprite); + else if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE) + vehicles.push_back(sprite); + } + + switch (desyncType) + { + case 0: // Peep t-shirts. + { + if (peeps.empty()) + { + console.WriteFormatLine("No peeps"); + } + else + { + rct_sprite* sprite = peeps[0]; + if (peeps.size() > 1) + sprite = peeps[util_rand() % peeps.size() - 1]; + sprite->peep.tshirt_colour = util_rand() & 0xFF; + invalidate_sprite_0(sprite); + } + break; + } + case 1: // Remove random peep. + { + if (peeps.empty()) + { + console.WriteFormatLine("No peep removed"); + } + else + { + rct_sprite* sprite = peeps[0]; + if (peeps.size() > 1) + sprite = peeps[util_rand() % peeps.size() - 1]; + sprite->AsPeep()->Remove(); + } + break; + } + } + return 0; +} + #pragma warning(push) #pragma warning(disable : 4702) // unreachable code static int32_t cc_abort([[maybe_unused]] InteractiveConsole& console, [[maybe_unused]] const arguments_t& argv) @@ -1670,6 +1730,7 @@ static constexpr const console_command console_command_table[] = { { "replay_start", cc_replay_start, "Starts a replay", "replay_start "}, { "replay_stop", cc_replay_stop, "Stops the replay", "replay_stop"}, { "replay_normalise", cc_replay_normalise, "Normalises the replay to remove all gaps", "replay_normalise "}, + { "mp_desync", cc_mp_desync, "Forces a multiplayer desync", "cc_mp_desync [desync_type, 0 = Random t-shirt color on random peep, 1 = Remove random peep ]"}, }; // clang-format on diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 0b31ebc581..9764813223 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3934,6 +3934,7 @@ enum STR_DOWNLOADING_OBJECTS = 6303, STR_SHORTCUT_OPEN_SCENERY_PICKER = 6304, + STR_MULTITHREADING = 6305, STR_MULTITHREADING_TIP = 6306, @@ -3952,6 +3953,8 @@ enum STR_PEEP_DEBUG_PATHFIND_HISTORY = 6316, STR_PEEP_DEBUG_PATHFIND_HISTORY_ITEM = 6317, + STR_DESYNC_REPORT = 6318, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index f4c3eec266..88c9eb6a34 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -11,6 +11,7 @@ #include "../Context.h" #include "../Game.h" +#include "../GameStateSnapshots.h" #include "../OpenRCT2.h" #include "../PlatformEnvironment.h" #include "../actions/LoadOrQuitAction.hpp" @@ -31,12 +32,16 @@ // 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 "24" +#define NETWORK_STREAM_VERSION "25" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; static int32_t _pickup_peep_old_x = LOCATION_NULL; +// General chunk size is 63 KiB, this can not be any larger because the packet size is encoded +// with uint16_t and needs some spare room for other data in the packet. +static constexpr uint32_t CHUNK_SIZE = 1024 * 63; + #ifndef DISABLE_NETWORK # include "../Cheats.h" @@ -137,7 +142,9 @@ public: void SendPacketToClients(NetworkPacket& packet, bool front = false, bool gameCmd = false); bool CheckSRAND(uint32_t tick, uint32_t srand0); bool IsDesynchronised(); - void CheckDesynchronizaton(); + bool CheckDesynchronizaton(); + void RequestStateSnapshot(); + NetworkServerState_t GetServerState() const; void KickPlayer(int32_t playerId); void SetPassword(const char* password); void ShutdownClient(); @@ -160,6 +167,8 @@ public: void AppendServerLog(const std::string& s); void CloseServerLog(); + void Client_Send_RequestGameState(uint32_t tick); + void Client_Send_TOKEN(); void Client_Send_AUTH( const std::string& name, const std::string& password, const std::string& pubkey, const std::vector& signature); @@ -309,7 +318,6 @@ private: uint16_t listening_port = 0; SOCKET_STATUS _lastConnectStatus = SOCKET_STATUS_CLOSED; uint32_t last_ping_sent_time = 0; - uint32_t server_tick = 0; uint8_t player_id = 0; std::list> client_connection_list; std::multiset game_command_queue; @@ -317,7 +325,8 @@ private: std::string _host; uint16_t _port = 0; std::string _password; - bool _desynchronised = false; + NetworkServerState_t _serverState; + MemoryStream _serverGameState; uint32_t server_connect_time = 0; uint8_t default_group = 0; uint32_t _commandId; @@ -336,6 +345,7 @@ private: private: std::vector client_command_handlers; std::vector server_command_handlers; + void Server_Handle_REQUEST_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_AUTH(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& packet); void Server_Client_Joined(const char* name, const std::string& keyhash, NetworkConnection& connection); @@ -361,6 +371,7 @@ private: void Client_Handle_TOKEN(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_TOKEN(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket& packet); + void Client_Handle_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket& packet); uint8_t* save_for_network(size_t& out_size, const std::vector& objects) const; @@ -397,6 +408,7 @@ Network::Network() client_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Client_Handle_GAMEINFO; client_command_handlers[NETWORK_COMMAND_TOKEN] = &Network::Client_Handle_TOKEN; client_command_handlers[NETWORK_COMMAND_OBJECTS] = &Network::Client_Handle_OBJECTS; + client_command_handlers[NETWORK_COMMAND_GAMESTATE] = &Network::Client_Handle_GAMESTATE; server_command_handlers.resize(NETWORK_COMMAND_MAX, nullptr); server_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Server_Handle_AUTH; server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT; @@ -406,6 +418,7 @@ Network::Network() server_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Server_Handle_GAMEINFO; server_command_handlers[NETWORK_COMMAND_TOKEN] = &Network::Server_Handle_TOKEN; server_command_handlers[NETWORK_COMMAND_OBJECTS] = &Network::Server_Handle_OBJECTS; + server_command_handlers[NETWORK_COMMAND_REQUEST_GAMESTATE] = &Network::Server_Handle_REQUEST_GAMESTATE; _chat_log_fs << std::unitbuf; _server_log_fs << std::unitbuf; @@ -532,6 +545,8 @@ bool Network::BeginClient(const std::string& host, uint16_t port) _serverConnection = std::make_unique(); _serverConnection->Socket = CreateTcpSocket(); _serverConnection->Socket->ConnectAsync(host, port); + _serverState.gamestateSnapshotsEnabled = false; + status = NETWORK_STATUS_CONNECTING; _lastConnectStatus = SOCKET_STATUS_CLOSED; _clientMapLoaded = false; @@ -664,6 +679,8 @@ bool Network::BeginServer(uint16_t port, const std::string& address) status = NETWORK_STATUS_CONNECTED; listening_port = port; + _serverState.gamestateSnapshotsEnabled = gConfigNetwork.desync_debugging; + if (gConfigNetwork.advertise) { _advertiser = CreateServerAdvertiser(listening_port); @@ -703,7 +720,7 @@ int32_t Network::GetAuthStatus() uint32_t Network::GetServerTick() { - return server_tick; + return _serverState.tick; } uint8_t Network::GetPlayerID() @@ -997,7 +1014,10 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) _serverTickData.erase(itTickData); if (storedTick.srand0 != srand0) + { + log_info("Srand0 mismatch, client = %08X, server = %08X", srand0, storedTick.srand0); return false; + } if (!storedTick.spriteHash.empty()) { @@ -1005,6 +1025,7 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) std::string clientSpriteHash = checksum.ToString(); if (clientSpriteHash != storedTick.spriteHash) { + log_info("Sprite hash mismatch, client = %s, server = %s", clientSpriteHash.c_str(), storedTick.spriteHash.c_str()); return false; } } @@ -1014,15 +1035,17 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) bool Network::IsDesynchronised() { - return gNetwork._desynchronised; + return _serverState.state == NETWORK_SERVER_STATE_DESYNCED; } -void Network::CheckDesynchronizaton() +bool Network::CheckDesynchronizaton() { // Check synchronisation - if (GetMode() == NETWORK_MODE_CLIENT && !_desynchronised && !CheckSRAND(gCurrentTicks, scenario_rand_state().s0)) + if (GetMode() == NETWORK_MODE_CLIENT && _serverState.state != NETWORK_SERVER_STATE_DESYNCED + && !CheckSRAND(gCurrentTicks, scenario_rand_state().s0)) { - _desynchronised = true; + _serverState.state = NETWORK_SERVER_STATE_DESYNCED; + _serverState.desyncTick = gCurrentTicks; char str_desync[256]; format_string(str_desync, 256, STR_MULTIPLAYER_DESYNC, nullptr); @@ -1035,7 +1058,23 @@ void Network::CheckDesynchronizaton() { Close(); } + + return true; } + + return false; +} + +void Network::RequestStateSnapshot() +{ + log_info("Requesting game state for tick %u", _serverState.desyncTick); + + Client_Send_RequestGameState(_serverState.desyncTick); +} + +NetworkServerState_t Network::GetServerState() const +{ + return _serverState; } void Network::KickPlayer(int32_t playerId) @@ -1403,6 +1442,20 @@ void Network::CloseServerLog() _server_log_fs.close(); } +void Network::Client_Send_RequestGameState(uint32_t tick) +{ + if (_serverState.gamestateSnapshotsEnabled == false) + { + log_verbose("Server does not store a gamestate history"); + return; + } + + log_verbose("Requesting gamestate from server for tick %u", tick); + std::unique_ptr packet(NetworkPacket::Allocate()); + *packet << (uint32_t)NETWORK_COMMAND_REQUEST_GAMESTATE << tick; + _serverConnection->QueuePacket(std::move(packet)); +} + void Network::Client_Send_TOKEN() { log_verbose("requesting token"); @@ -1531,7 +1584,7 @@ void Network::Server_Send_MAP(NetworkConnection* connection) } return; } - size_t chunksize = 65000; + size_t chunksize = CHUNK_SIZE; for (size_t i = 0; i < out_size; i += chunksize) { size_t datasize = std::min(chunksize, out_size - i); @@ -1784,6 +1837,8 @@ void Network::Server_Send_GAMEINFO(NetworkConnection& connection) json_object_set_new(obj, "provider", jsonProvider); packet->WriteString(json_dumps(obj, 0)); + *packet << _serverState.gamestateSnapshotsEnabled; + json_decref(obj); # endif connection.QueuePacket(std::move(packet)); @@ -2313,6 +2368,48 @@ void Network::Client_Handle_TOKEN(NetworkConnection& connection, NetworkPacket& Client_Send_AUTH(gConfigNetwork.player_name.c_str(), password, pubkey.c_str(), signature); } +void Network::Server_Handle_REQUEST_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet) +{ + uint32_t tick; + packet >> tick; + + if (_serverState.gamestateSnapshotsEnabled == false) + { + // Ignore this if this is off. + return; + } + + IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots(); + + const GameStateSnapshot_t* snapshot = snapshots->GetLinkedSnapshot(tick); + if (snapshot) + { + MemoryStream snapshotMemory; + DataSerialiser ds(true, snapshotMemory); + + snapshots->SerialiseSnapshot(const_cast(*snapshot), ds); + + uint32_t bytesSent = 0; + uint32_t length = (uint32_t)snapshotMemory.GetLength(); + while (bytesSent < length) + { + uint32_t dataSize = CHUNK_SIZE; + if (bytesSent + dataSize > snapshotMemory.GetLength()) + { + dataSize = snapshotMemory.GetLength() - bytesSent; + } + + std::unique_ptr gameStateChunk(NetworkPacket::Allocate()); + *gameStateChunk << (uint32_t)NETWORK_COMMAND_GAMESTATE << tick << length << bytesSent << dataSize; + gameStateChunk->Write((const uint8_t*)snapshotMemory.GetData() + bytesSent, dataSize); + + connection.QueuePacket(std::move(gameStateChunk)); + + bytesSent += dataSize; + } + } +} + void Network::Client_Handle_AUTH(NetworkConnection& connection, NetworkPacket& packet) { uint32_t auth_status; @@ -2436,6 +2533,73 @@ void Network::Client_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket Client_Send_OBJECTS(requested_objects); } +void Network::Client_Handle_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet) +{ + uint32_t tick; + uint32_t totalSize; + uint32_t offset; + uint32_t dataSize; + + packet >> tick >> totalSize >> offset >> dataSize; + + if (offset == 0) + { + // Reset + _serverGameState = MemoryStream(); + } + + _serverGameState.SetPosition(offset); + + const uint8_t* data = packet.Read(dataSize); + _serverGameState.Write(data, dataSize); + + log_verbose("Received Game State %.02f%%", ((float)_serverGameState.GetLength() / (float)totalSize) * 100.0f); + + if (_serverGameState.GetLength() == totalSize) + { + _serverGameState.SetPosition(0); + DataSerialiser ds(false, _serverGameState); + + IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots(); + + GameStateSnapshot_t& serverSnapshot = snapshots->CreateSnapshot(); + snapshots->SerialiseSnapshot(serverSnapshot, ds); + + const GameStateSnapshot_t* desyncSnapshot = snapshots->GetLinkedSnapshot(tick); + if (desyncSnapshot) + { + GameStateCompareData_t cmpData = snapshots->Compare(serverSnapshot, *desyncSnapshot); + + std::string outputPath = GetContext()->GetPlatformEnvironment()->GetDirectoryPath( + DIRBASE::USER, DIRID::LOG_DESYNCS); + + platform_ensure_directory_exists(outputPath.c_str()); + + char uniqueFileName[128] = {}; + snprintf( + uniqueFileName, sizeof(uniqueFileName), "desync_%llu_%u.txt", + (long long unsigned)platform_get_datetime_now_utc(), tick); + + std::string outputFile = Path::Combine(outputPath, uniqueFileName); + + if (snapshots->LogCompareDataToFile(outputFile, cmpData)) + { + log_info("Wrote desync report to '%s'", outputFile.c_str()); + + uint8_t args[32]{}; + set_format_arg_on(args, 0, char*, uniqueFileName); + + char str_desync[1024]; + format_string(str_desync, sizeof(str_desync), STR_DESYNC_REPORT, args); + + auto intent = Intent(WC_NETWORK_STATUS); + intent.putExtra(INTENT_EXTRA_MESSAGE, std::string{ str_desync }); + context_open_intent(&intent); + } + } + } +} + void Network::Server_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket& packet) { uint32_t size; @@ -2644,9 +2808,10 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection, game_load_init(); game_command_queue.clear(); _serverTickData.clear(); - server_tick = gCurrentTicks; + _serverState.tick = gCurrentTicks; + _serverTickData.clear(); // window_network_status_open("Loaded new map from network"); - _desynchronised = false; + _serverState.state = NETWORK_SERVER_STATE_OK; _clientMapLoaded = true; gFirstTimeSaving = true; @@ -2977,11 +3142,13 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, { uint32_t srand0; uint32_t flags; - packet >> server_tick >> srand0 >> flags; + uint32_t serverTick; + + packet >> serverTick >> srand0 >> flags; ServerTickData_t tickData; tickData.srand0 = srand0; - tickData.tick = server_tick; + tickData.tick = serverTick; if (flags & NETWORK_TICK_FLAG_CHECKSUMS) { @@ -2998,7 +3165,8 @@ void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, _serverTickData.erase(_serverTickData.begin()); } - _serverTickData.emplace(server_tick, tickData); + _serverState.tick = serverTick; + _serverTickData.emplace(serverTick, tickData); } void Network::Client_Handle_PLAYERINFO([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) @@ -3154,6 +3322,7 @@ static std::string json_stdstring_value(const json_t* string) void Network::Client_Handle_GAMEINFO([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) { const char* jsonString = packet.ReadString(); + packet >> _serverState.gamestateSnapshotsEnabled; json_error_t error; json_t* root = json_loads(jsonString, 0, &error); @@ -3234,11 +3403,16 @@ bool network_is_desynchronised() return gNetwork.IsDesynchronised(); } -void network_check_desynchronization() +bool network_check_desynchronisation() { return gNetwork.CheckDesynchronizaton(); } +void network_request_gamestate_snapshot() +{ + return gNetwork.RequestStateSnapshot(); +} + void network_send_tick() { gNetwork.Server_Send_TICK(); @@ -3995,6 +4169,16 @@ NetworkStats_t network_get_stats() return gNetwork.GetStats(); } +NetworkServerState_t network_get_server_state() +{ + return gNetwork.GetServerState(); +} + +bool network_gamestate_snapshots_enabled() +{ + return network_get_server_state().gamestateSnapshotsEnabled; +} + #else int32_t network_get_mode() { @@ -4022,7 +4206,15 @@ bool network_is_desynchronised() { return false; } -void network_check_desynchronization() +bool network_gamestate_snapshots_enabled() +{ + return false; +} +bool network_check_desynchronisation() +{ + return false; +} +void network_request_gamestate_snapshot() { } void network_enqueue_game_action(const GameAction* action) @@ -4240,4 +4432,8 @@ NetworkStats_t network_get_stats() { return NetworkStats_t{}; } +NetworkServerState_t network_get_server_state() +{ + return NetworkServerState_t{}; +} #endif /* DISABLE_NETWORK */ diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index 2fd6d588e2..7a99db8022 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -66,12 +66,29 @@ enum NETWORK_COMMAND NETWORK_COMMAND_OBJECTS, NETWORK_COMMAND_GAME_ACTION, NETWORK_COMMAND_PLAYERINFO, + NETWORK_COMMAND_REQUEST_GAMESTATE, + NETWORK_COMMAND_GAMESTATE, NETWORK_COMMAND_MAX, NETWORK_COMMAND_INVALID = -1 }; static_assert(NETWORK_COMMAND::NETWORK_COMMAND_GAMEINFO == 9, "Master server expects this to be 9"); +enum NETWORK_SERVER_STATE +{ + NETWORK_SERVER_STATE_OK, + NETWORK_SERVER_STATE_DESYNCED, +}; + +struct NetworkServerState_t +{ + NETWORK_SERVER_STATE state = NETWORK_SERVER_STATE_OK; + uint32_t desyncTick = 0; + uint32_t tick = 0; + uint32_t srand0 = 0; + bool gamestateSnapshotsEnabled = false; +}; + // Structure is used for networking specific fields with meaning, // this structure can be used in combination with DataSerialiser // to provide extra details with template specialization. diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 9c294c65e0..f19a83f8b3 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -39,8 +39,10 @@ int32_t network_begin_server(int32_t port, const std::string& address); int32_t network_get_mode(); int32_t network_get_status(); bool network_is_desynchronised(); -void network_check_desynchronization(); +bool network_check_desynchronisation(); +void network_request_gamestate_snapshot(); void network_send_tick(); +bool network_gamestate_snapshots_enabled(); void network_update(); void network_process_pending(); void network_flush(); @@ -106,3 +108,4 @@ const utf8* network_get_server_provider_website(); std::string network_get_version(); NetworkStats_t network_get_stats(); +NetworkServerState_t network_get_server_state(); From 7c7909fb45684b95ea9ce32ab09eb824ffd28340 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 20:08:53 +0200 Subject: [PATCH 331/506] Fix #2294: Clients crashing the server with invalid object selection --- src/openrct2/actions/RideCreateAction.hpp | 36 ++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 05b3ee4cd6..8919268d04 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -30,7 +30,7 @@ class RideCreateGameActionResult final : public GameActionResult { public: RideCreateGameActionResult() - : GameActionResult(GA_ERROR::OK, 0) + : GameActionResult(GA_ERROR::OK, STR_NONE) { } RideCreateGameActionResult(GA_ERROR error, rct_string_id message) @@ -44,15 +44,14 @@ public: DEFINE_GAME_ACTION(RideCreateAction, GAME_COMMAND_CREATE_RIDE, RideCreateGameActionResult) { private: - int32_t _rideType; - int32_t _subType; - uint8_t _colour1; - uint8_t _colour2; + int32_t _rideType{ RIDE_ID_NULL }; + int32_t _subType{ RIDE_ENTRY_INDEX_NULL }; + uint8_t _colour1{ 0xFF }; + uint8_t _colour2{ 0xFF }; public: - RideCreateAction() - { - } + RideCreateAction() = default; + RideCreateAction(int32_t rideType, int32_t subType, int32_t colour1, int32_t colour2) : _rideType(rideType) , _subType(subType) @@ -79,42 +78,45 @@ public: if (rideIndex == RIDE_ID_NULL) { // No more free slots available. - return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_RIDES); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_RIDES); } if (_rideType >= RIDE_TYPE_COUNT) { - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); } int32_t rideEntryIndex = ride_get_entry_index(_rideType, _subType); if (rideEntryIndex >= 128) { - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); } const track_colour_preset_list* colourPresets = &RideColourPresets[_rideType]; if (_colour1 >= colourPresets->count) { - // FIXME: Add new error string. - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } rct_ride_entry* rideEntry = get_ride_entry(rideEntryIndex); + if (rideEntry == nullptr) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + vehicle_colour_preset_list* presetList = rideEntry->vehicle_preset_list; if ((presetList->count > 0 && presetList->count != 255) && _colour2 >= presetList->count) { - // FIXME: Add new error string. - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - return std::make_unique(); + return MakeResult(); } GameActionResult::Ptr Execute() const override { rct_ride_entry* rideEntry; - auto res = std::make_unique(); + auto res = MakeResult(); int32_t rideEntryIndex = ride_get_entry_index(_rideType, _subType); ride_id_t rideIndex = ride_get_empty_slot(); From 46c9b8925951cba998d470eb8cf878d646a06d07 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 20:16:32 +0200 Subject: [PATCH 332/506] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 45167eac71..73674304cb 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -11,6 +11,7 @@ - Feature: [#9154] Change map toolbar icon with current viewport rotation. - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8688] Move common actions from debug menu into cheats menu. +- Fix: [#2294] Clients crashing the server with invalid object selection. - Fix: [#5103] OpenGL: ride track preview not rendered. - Fix: [#5889] Giant screenshot does not work while using OpenGL renderer. - Fix: [#5579] Network desync immediately after connecting. From 9561567b6c87fbec772766362137670431a75e56 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 21:38:28 +0200 Subject: [PATCH 333/506] Bump up 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 88c9eb6a34..55376637ec 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,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 "25" +#define NETWORK_STREAM_VERSION "26" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 6aa0e74d3e3b4fe6e9d7892caf55c2a987df82f3 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 22:37:19 +0200 Subject: [PATCH 334/506] Fix util_rand only returning 15 bit values. --- src/openrct2/util/Util.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 0245e4158d..29d858ee3c 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -21,6 +21,9 @@ #include #include #include +#include + +static std::mt19937 _prng; int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres) { @@ -528,13 +531,12 @@ bool str_is_null_or_empty(const char* str) void util_srand(int32_t source) { - srand(source); + _prng.seed(source); } -// Caveat: rand() might only return values up to 0x7FFF, which is the minimum specified in the C standard. uint32_t util_rand() { - return rand(); + return _prng(); } #define CHUNK (128 * 1024) From c1d6337e3bd0f6875a4529d5642de757c51902ed Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 23:40:59 +0200 Subject: [PATCH 335/506] Increase buffer size to avoid truncating text --- 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 55376637ec..e2ccb522d9 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1348,7 +1348,7 @@ void Network::AppendLog(std::ostream& fs, const std::string& s) } try { - utf8 buffer[256]; + utf8 buffer[1024]; time_t timer; time(&timer); auto tmInfo = localtime(&timer); From 2ea15ac1462c29327bcc5691a6b3e958525e4bd7 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 23:42:23 +0200 Subject: [PATCH 336/506] Write server log as binary --- src/openrct2/network/Network.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index e2ccb522d9..6afedde069 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1400,9 +1400,9 @@ void Network::BeginServerLog() # if defined(_WIN32) && !defined(__MINGW32__) auto pathW = std::unique_ptr(utf8_to_widechar(_serverLogPath.c_str())); - _server_log_fs.open(pathW.get(), std::ios::out | std::ios::app); + _server_log_fs.open(pathW.get(), std::ios::out | std::ios::app | std::ios::binary); # else - _server_log_fs.open(_serverLogPath, std::ios::out | std::ios::app); + _server_log_fs.open(_serverLogPath, std::ios::out | std::ios::app | std::ios::binary); # endif // Log server start event From 5992b9f76e65a2ca40558c923d376e59fbc4861d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 4 May 2019 21:27:12 +0000 Subject: [PATCH 337/506] Add UDP socket class --- src/openrct2/network/UdpSocket.cpp | 322 +++++++++++++++++++++++++++++ src/openrct2/network/UdpSocket.h | 57 +++++ 2 files changed, 379 insertions(+) create mode 100644 src/openrct2/network/UdpSocket.cpp create mode 100644 src/openrct2/network/UdpSocket.h diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp new file mode 100644 index 0000000000..63780afcda --- /dev/null +++ b/src/openrct2/network/UdpSocket.cpp @@ -0,0 +1,322 @@ +/***************************************************************************** + * 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. + *****************************************************************************/ + +#ifndef DISABLE_NETWORK + +# include +# include +# include +# include +# include +# include + +// clang-format off +// MSVC: include here otherwise PI gets defined twice +#include + +#ifdef _WIN32 + // winsock2 must be included before windows.h + #include + #include + + #define LAST_SOCKET_ERROR() WSAGetLastError() + #undef EWOULDBLOCK + #define EWOULDBLOCK WSAEWOULDBLOCK + #ifndef SHUT_RD + #define SHUT_RD SD_RECEIVE + #endif + #ifndef SHUT_RDWR + #define SHUT_RDWR SD_BOTH + #endif + #define FLAG_NO_PIPE 0 +#else + #include + #include + #include + #include + #include + #include + #include + #include "../common.h" + using SOCKET = int32_t; + #define SOCKET_ERROR -1 + #define INVALID_SOCKET -1 + #define LAST_SOCKET_ERROR() errno + #define closesocket close + #define ioctlsocket ioctl + #if defined(__linux__) + #define FLAG_NO_PIPE MSG_NOSIGNAL + #else + #define FLAG_NO_PIPE 0 + #endif // defined(__linux__) +#endif // _WIN32 +// clang-format on + +# include "UdpSocket.h" + +constexpr auto CONNECT_TIMEOUT = std::chrono::milliseconds(3000); + +# ifdef _WIN32 +static bool _wsaInitialised = false; +# endif + +class UdpSocket; + +class SocketException : public std::runtime_error +{ +public: + explicit SocketException(const std::string& message) + : std::runtime_error(message) + { + } +}; + +class UdpSocket final : public IUdpSocket +{ +private: + SOCKET_STATUS _status = SOCKET_STATUS_CLOSED; + uint16_t _listeningPort = 0; + SOCKET _socket = INVALID_SOCKET; + + std::string _hostName; + std::string _error; + +public: + UdpSocket() = default; + + ~UdpSocket() override + { + CloseSocket(); + } + + SOCKET_STATUS GetStatus() override + { + return _status; + } + + const char* GetError() override + { + return _error.empty() ? nullptr : _error.c_str(); + } + + void Listen(uint16_t port) override + { + Listen("", port); + } + + void Listen(const std::string& address, uint16_t port) override + { + if (_status != SOCKET_STATUS_CLOSED) + { + throw std::runtime_error("Socket not closed."); + } + + sockaddr_storage ss{}; + int32_t ss_len; + if (!ResolveAddress(address, port, &ss, &ss_len)) + { + throw SocketException("Unable to resolve address."); + } + + // Create the listening socket + _socket = socket(ss.ss_family, SOCK_STREAM, IPPROTO_TCP); + if (_socket == INVALID_SOCKET) + { + throw SocketException("Unable to create socket."); + } + + // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections + int32_t value = 0; + if (setsockopt(_socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value)) != 0) + { + log_error("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); + } + + value = 1; + if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&value, sizeof(value)) != 0) + { + log_error("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); + } + + try + { + // Bind to address:port and listen + if (bind(_socket, (sockaddr*)&ss, ss_len) != 0) + { + throw SocketException("Unable to bind to socket."); + } + if (listen(_socket, SOMAXCONN) != 0) + { + throw SocketException("Unable to listen on socket."); + } + + if (!SetNonBlocking(_socket, true)) + { + throw SocketException("Failed to set non-blocking mode."); + } + } + catch (const std::exception&) + { + CloseSocket(); + throw; + } + + _listeningPort = port; + _status = SOCKET_STATUS_LISTENING; + } + + size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) override + { + if (_status != SOCKET_STATUS_CONNECTED) + { + throw std::runtime_error("Socket not connected."); + } + + size_t totalSent = 0; + do + { + const char* bufferStart = (const char*)buffer + totalSent; + size_t remainingSize = size - totalSent; + int32_t sentBytes = send(_socket, bufferStart, (int32_t)remainingSize, FLAG_NO_PIPE); + if (sentBytes == SOCKET_ERROR) + { + return totalSent; + } + totalSent += sentBytes; + } while (totalSent < size); + return totalSent; + } + + NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) override + { + if (_status != SOCKET_STATUS_CONNECTED) + { + throw std::runtime_error("Socket not connected."); + } + + int32_t readBytes = recv(_socket, (char*)buffer, (int32_t)size, 0); + if (readBytes == 0) + { + *sizeReceived = 0; + return NETWORK_READPACKET_DISCONNECTED; + } + else if (readBytes == SOCKET_ERROR) + { + *sizeReceived = 0; +# ifndef _WIN32 + // Removing the check for EAGAIN and instead relying on the values being the same allows turning on of + // -Wlogical-op warning. + // This is not true on Windows, see: + // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms737828(v=vs.85).aspx + // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms741580(v=vs.85).aspx + // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx + static_assert( + EWOULDBLOCK == EAGAIN, + "Portability note: your system has different values for EWOULDBLOCK " + "and EAGAIN, please extend the condition below"); +# endif // _WIN32 + if (LAST_SOCKET_ERROR() != EWOULDBLOCK) + { + return NETWORK_READPACKET_DISCONNECTED; + } + else + { + return NETWORK_READPACKET_NO_DATA; + } + } + else + { + *sizeReceived = readBytes; + return NETWORK_READPACKET_SUCCESS; + } + } + + void Close() override + { + CloseSocket(); + } + + const char* GetHostName() const override + { + return _hostName.empty() ? nullptr : _hostName.c_str(); + } + +private: + explicit UdpSocket(SOCKET socket, const std::string& hostName) + { + _socket = socket; + _hostName = hostName; + _status = SOCKET_STATUS_CONNECTED; + } + + void CloseSocket() + { + if (_socket != INVALID_SOCKET) + { + closesocket(_socket); + _socket = INVALID_SOCKET; + } + _status = SOCKET_STATUS_CLOSED; + } + + bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, int32_t* ss_len) + { + std::string serviceName = std::to_string(port); + + addrinfo hints = {}; + hints.ai_family = AF_UNSPEC; + if (address.empty()) + { + hints.ai_flags = AI_PASSIVE; + } + + addrinfo* result = nullptr; + int errorcode = getaddrinfo(address.empty() ? nullptr : address.c_str(), serviceName.c_str(), &hints, &result); + if (errorcode != 0) + { + log_error("Resolving address failed: Code %d.", errorcode); + log_error("Resolution error message: %s.", gai_strerror(errorcode)); + return false; + } + if (result == nullptr) + { + return false; + } + else + { + std::memcpy(ss, result->ai_addr, result->ai_addrlen); + *ss_len = (int32_t)result->ai_addrlen; + freeaddrinfo(result); + return true; + } + } + + static bool SetNonBlocking(SOCKET socket, bool on) + { +# ifdef _WIN32 + u_long nonBlocking = on; + return ioctlsocket(socket, FIONBIO, &nonBlocking) == 0; +# else + int32_t flags = fcntl(socket, F_GETFL, 0); + return fcntl(socket, F_SETFL, on ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0; +# endif + } + + static bool SetSOBroadcast(SOCKET socket, bool enabled) + { + return setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&enabled, sizeof(enabled)) == 0; + } +}; + +std::unique_ptr CreateUdpSocket() +{ + return std::make_unique(); +} + +#endif diff --git a/src/openrct2/network/UdpSocket.h b/src/openrct2/network/UdpSocket.h new file mode 100644 index 0000000000..07beec7a75 --- /dev/null +++ b/src/openrct2/network/UdpSocket.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * 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 "../common.h" + +#include +#include + +enum SOCKET_STATUS +{ + SOCKET_STATUS_CLOSED, + SOCKET_STATUS_RESOLVING, + SOCKET_STATUS_CONNECTING, + SOCKET_STATUS_CONNECTED, + SOCKET_STATUS_LISTENING, +}; + +enum NETWORK_READPACKET +{ + NETWORK_READPACKET_SUCCESS, + NETWORK_READPACKET_NO_DATA, + NETWORK_READPACKET_MORE_DATA, + NETWORK_READPACKET_DISCONNECTED +}; + +/** + * Represents a UDP socket / listener. + */ +interface IUdpSocket +{ +public: + virtual ~IUdpSocket() + { + } + + virtual SOCKET_STATUS GetStatus() abstract; + virtual const char* GetError() abstract; + virtual const char* GetHostName() const abstract; + + virtual void Listen(uint16_t port) abstract; + virtual void Listen(const std::string& address, uint16_t port) abstract; + + virtual size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) abstract; + virtual NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) abstract; + + virtual void Close() abstract; +}; + +std::unique_ptr CreateUdpSocket(); From 694cb7eb3fd78cac81205c0a0882260c1b3c830d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 01:02:20 +0000 Subject: [PATCH 338/506] Implement UDP socket and broadcasting --- src/openrct2-ui/windows/ServerList.cpp | 67 +++++-- src/openrct2/network/Network.cpp | 6 +- .../network/NetworkServerAdvertiser.cpp | 72 ++++++-- src/openrct2/network/UdpSocket.cpp | 172 +++++++++++++----- src/openrct2/network/UdpSocket.h | 16 +- 5 files changed, 248 insertions(+), 85 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 16f665d7e8..fde87fa51a 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -636,29 +637,61 @@ static void join_server(std::string address) } #ifndef DISABLE_HTTP + +static void fetch_lan_servers() +{ + std::string msg = "Are you an OpenRCT2 server?"; + auto udpSocket = CreateUdpSocket(); + auto len = udpSocket->SendData("192.168.1.255", 11754, msg.data(), msg.size()); + if (len == msg.size()) + { + char buffer[256]{}; + size_t recievedLen{}; + std::unique_ptr endpoint; + for (int i = 0; i < 5 * 10; i++) + { + auto p = udpSocket->ReceiveData(buffer, sizeof(buffer), &recievedLen, &endpoint); + if (p == NETWORK_READPACKET_SUCCESS) + { + auto sender = endpoint->GetHostname(); + std::printf(">> Recieved packet from %s\n", sender.c_str()); + std::printf(">> %s\n", buffer); + } + usleep(100 * 1000); + } + } +} + static void fetch_servers() { - std::string masterServerUrl = OPENRCT2_MASTER_SERVER_URL; - if (!gConfigNetwork.master_server_url.empty()) + if (1 == 1) { - masterServerUrl = gConfigNetwork.master_server_url; + fetch_lan_servers(); } - + else { - std::lock_guard guard(_mutex); - _serverEntries.erase( - std::remove_if( - _serverEntries.begin(), _serverEntries.end(), [](const server_entry& server) { return !server.favourite; }), - _serverEntries.end()); - sort_servers(); - } + std::string masterServerUrl = OPENRCT2_MASTER_SERVER_URL; + if (gConfigNetwork.master_server_url.empty() == false) + { + masterServerUrl = gConfigNetwork.master_server_url; + } - Http::Request request; - request.url = masterServerUrl; - request.method = Http::Method::GET; - request.header["Accept"] = "application/json"; - status_text = STR_SERVER_LIST_CONNECTING; - Http::DoAsync(request, fetch_servers_callback); + { + std::lock_guard guard(_mutex); + _serverEntries.erase( + std::remove_if( + _serverEntries.begin(), _serverEntries.end(), [](const server_entry& server) { return !server.favourite; }), + _serverEntries.end()); + sort_servers(); + } + + Http::Request request; + request.url = masterServerUrl; + request.method = Http::Method::GET; + request.header["Accept"] = "application/json"; + status_text = STR_SERVER_LIST_CONNECTING; + Http::DoAsync(request, fetch_servers_callback); + } } static uint32_t get_total_player_count() diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 55376637ec..8a24933a11 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -680,11 +680,7 @@ bool Network::BeginServer(uint16_t port, const std::string& address) status = NETWORK_STATUS_CONNECTED; listening_port = port; _serverState.gamestateSnapshotsEnabled = gConfigNetwork.desync_debugging; - - if (gConfigNetwork.advertise) - { - _advertiser = CreateServerAdvertiser(listening_port); - } + _advertiser = CreateServerAdvertiser(listening_port); if (gConfigNetwork.pause_server_if_no_clients) { diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 1b8623bfb4..f347d193ba 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -18,13 +18,16 @@ # include "../localisation/Date.h" # include "../management/Finance.h" # include "../peep/Peep.h" +# include "../platform/Platform2.h" # include "../platform/platform.h" # include "../util/Util.h" # include "../world/Map.h" # include "../world/Park.h" # include "Http.h" +# include "UdpSocket.h" # include "network.h" +# include # include # include # include @@ -44,6 +47,8 @@ enum MASTER_SERVER_STATUS constexpr int32_t MASTER_SERVER_REGISTER_TIME = 120 * 1000; // 2 minutes constexpr int32_t MASTER_SERVER_HEARTBEAT_TIME = 60 * 1000; // 1 minute +constexpr int32_t LAN_BROADCAST_PORT = 11754; + class NetworkServerAdvertiser final : public INetworkServerAdvertiser { private: @@ -62,11 +67,15 @@ private: // See https://github.com/OpenRCT2/OpenRCT2/issues/6277 and 4953 bool _forceIPv4 = false; + std::unique_ptr _lanListener; + uint32_t _lastListenTime{}; + public: explicit NetworkServerAdvertiser(uint16_t port) { _port = port; _key = GenerateAdvertiseKey(); + _lanListener = CreateUdpSocket(); } ADVERTISE_STATUS GetStatus() const override @@ -76,23 +85,58 @@ public: void Update() override { - switch (_status) + auto ticks = Platform::GetTicks(); + if (ticks > _lastListenTime + 500) { - case ADVERTISE_STATUS::UNREGISTERED: - if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME) + if (_lanListener->GetStatus() != SOCKET_STATUS_LISTENING) + { + _lanListener->Listen(LAN_BROADCAST_PORT); + } + else + { + char buffer[256]; + size_t recievedBytes; + std::unique_ptr endpoint; + auto p = _lanListener->ReceiveData(buffer, sizeof(buffer), &recievedBytes, &endpoint); + if (p == NETWORK_READPACKET_SUCCESS) { - SendRegistration(_forceIPv4); + std::string sender = endpoint->GetHostname(); + std::printf("\r>> Received %zu bytes from %s\n", recievedBytes, sender.c_str()); + + auto body = GetHeartbeatJson(); + auto bodyDump = json_dumps(body, JSON_COMPACT); + size_t sendLen = strlen(bodyDump) + 1; + std::printf("\r>> Sending %zu bytes back to %s\n", sendLen, sender.c_str()); + _lanListener->SendData(*endpoint, bodyDump, sendLen); + free(bodyDump); + json_decref(body); } - break; - case ADVERTISE_STATUS::REGISTERED: - if (platform_get_ticks() > _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME) - { - SendHeartbeat(); - } - break; - // exhaust enum values to satisfy clang - case ADVERTISE_STATUS::DISABLED: - break; + } + _lastListenTime = ticks; + } + + if (gConfigNetwork.advertise) + { + /* + switch (_status) + { + case ADVERTISE_STATUS::UNREGISTERED: + if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME) + { + SendRegistration(_forceIPv4); + } + break; + case ADVERTISE_STATUS::REGISTERED: + if (platform_get_ticks() > _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME) + { + SendHeartbeat(); + } + break; + // exhaust enum values to satisfy clang + case ADVERTISE_STATUS::DISABLED: + break; + } + */ } } diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp index 63780afcda..80c13e2f26 100644 --- a/src/openrct2/network/UdpSocket.cpp +++ b/src/openrct2/network/UdpSocket.cpp @@ -77,12 +77,64 @@ public: } }; +class NetworkEndpoint final : public INetworkEndpoint +{ +private: + sockaddr _address{}; + socklen_t _addressLen{}; + +public: + NetworkEndpoint() + { + } + + NetworkEndpoint(const sockaddr* address, socklen_t addressLen) + { + std::memcpy(&_address, address, addressLen); + _addressLen = addressLen; + } + + const sockaddr& GetAddress() const + { + return _address; + } + + socklen_t GetAddressLen() const + { + return _addressLen; + } + + int32_t GetPort() const + { + if (_address.sa_family == AF_INET) + { + return ((sockaddr_in*)&_address)->sin_port; + } + else + { + return ((sockaddr_in6*)&_address)->sin6_port; + } + } + + std::string GetHostname() override + { + char hostname[256]; + int res = getnameinfo(&_address, _addressLen, hostname, sizeof(hostname), nullptr, 0, NI_NUMERICHOST); + if (res == 0) + { + return hostname; + } + return {}; + } +}; + class UdpSocket final : public IUdpSocket { private: SOCKET_STATUS _status = SOCKET_STATUS_CLOSED; uint16_t _listeningPort = 0; SOCKET _socket = INVALID_SOCKET; + NetworkEndpoint _endpoint; std::string _hostName; std::string _error; @@ -118,32 +170,36 @@ public: } sockaddr_storage ss{}; - int32_t ss_len; + socklen_t ss_len; if (!ResolveAddress(address, port, &ss, &ss_len)) { throw SocketException("Unable to resolve address."); } // Create the listening socket - _socket = socket(ss.ss_family, SOCK_STREAM, IPPROTO_TCP); + _socket = socket(ss.ss_family, SOCK_DGRAM, IPPROTO_UDP); if (_socket == INVALID_SOCKET) { throw SocketException("Unable to create socket."); } // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections - int32_t value = 0; - if (setsockopt(_socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value)) != 0) + if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) { log_error("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); } - value = 1; - if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&value, sizeof(value)) != 0) + if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) { log_error("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); } + // Enable send and receiving of broadcast messages + if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) + { + log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); + } + try { // Bind to address:port and listen @@ -151,10 +207,6 @@ public: { throw SocketException("Unable to bind to socket."); } - if (listen(_socket, SOMAXCONN) != 0) - { - throw SocketException("Unable to listen on socket."); - } if (!SetNonBlocking(_socket, true)) { @@ -173,9 +225,49 @@ public: size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) override { - if (_status != SOCKET_STATUS_CONNECTED) + sockaddr_storage ss{}; + socklen_t ss_len; + if (!ResolveAddress(address, port, &ss, &ss_len)) { - throw std::runtime_error("Socket not connected."); + throw SocketException("Unable to resolve address."); + } + NetworkEndpoint endpoint((const sockaddr*)&ss, ss_len); + return SendData(endpoint, buffer, size); + } + + size_t SendData(const INetworkEndpoint& destination, const void* buffer, size_t size) override + { + if (_socket == INVALID_SOCKET) + { + _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (_socket == INVALID_SOCKET) + { + throw SocketException("Unable to create socket."); + } + + // Enable send and receiving of broadcast messages + if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) + { + log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); + } + + if (!SetNonBlocking(_socket, true)) + { + throw SocketException("Failed to set non-blocking mode."); + } + } + + const auto& dest = dynamic_cast(&destination); + if (dest == nullptr) + { + throw std::invalid_argument("destination is not compatible."); + } + auto ss = &dest->GetAddress(); + auto ss_len = dest->GetAddressLen(); + + if (_status != SOCKET_STATUS_LISTENING) + { + _endpoint = *dest; } size_t totalSent = 0; @@ -183,7 +275,7 @@ public: { const char* bufferStart = (const char*)buffer + totalSent; size_t remainingSize = size - totalSent; - int32_t sentBytes = send(_socket, bufferStart, (int32_t)remainingSize, FLAG_NO_PIPE); + int32_t sentBytes = sendto(_socket, bufferStart, (int32_t)remainingSize, FLAG_NO_PIPE, (const sockaddr*)ss, ss_len); if (sentBytes == SOCKET_ERROR) { return totalSent; @@ -193,46 +285,29 @@ public: return totalSent; } - NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) override + NETWORK_READPACKET ReceiveData( + void* buffer, size_t size, size_t* sizeReceived, std::unique_ptr* sender) override { - if (_status != SOCKET_STATUS_CONNECTED) + sockaddr_in senderAddr{}; + socklen_t senderAddrLen{}; + if (_status != SOCKET_STATUS_LISTENING) { - throw std::runtime_error("Socket not connected."); + senderAddrLen = _endpoint.GetAddressLen(); + std::memcpy(&senderAddr, &_endpoint.GetAddress(), senderAddrLen); } - - int32_t readBytes = recv(_socket, (char*)buffer, (int32_t)size, 0); - if (readBytes == 0) + auto readBytes = recvfrom(_socket, (char*)buffer, (int32_t)size, 0, (sockaddr*)&senderAddr, &senderAddrLen); + if (readBytes <= 0) { *sizeReceived = 0; - return NETWORK_READPACKET_DISCONNECTED; - } - else if (readBytes == SOCKET_ERROR) - { - *sizeReceived = 0; -# ifndef _WIN32 - // Removing the check for EAGAIN and instead relying on the values being the same allows turning on of - // -Wlogical-op warning. - // This is not true on Windows, see: - // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms737828(v=vs.85).aspx - // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms741580(v=vs.85).aspx - // * https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx - static_assert( - EWOULDBLOCK == EAGAIN, - "Portability note: your system has different values for EWOULDBLOCK " - "and EAGAIN, please extend the condition below"); -# endif // _WIN32 - if (LAST_SOCKET_ERROR() != EWOULDBLOCK) - { - return NETWORK_READPACKET_DISCONNECTED; - } - else - { - return NETWORK_READPACKET_NO_DATA; - } + return NETWORK_READPACKET_NO_DATA; } else { *sizeReceived = readBytes; + if (sender != nullptr) + { + *sender = std::make_unique((sockaddr*)&senderAddr, senderAddrLen); + } return NETWORK_READPACKET_SUCCESS; } } @@ -265,7 +340,7 @@ private: _status = SOCKET_STATUS_CLOSED; } - bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, int32_t* ss_len) + bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, socklen_t* ss_len) { std::string serviceName = std::to_string(port); @@ -291,7 +366,7 @@ private: else { std::memcpy(ss, result->ai_addr, result->ai_addrlen); - *ss_len = (int32_t)result->ai_addrlen; + *ss_len = result->ai_addrlen; freeaddrinfo(result); return true; } @@ -308,9 +383,10 @@ private: # endif } - static bool SetSOBroadcast(SOCKET socket, bool enabled) + static bool SetOption(SOCKET socket, int32_t a, int32_t b, bool value) { - return setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&enabled, sizeof(enabled)) == 0; + int32_t ivalue = value ? 1 : 0; + return setsockopt(socket, a, b, (const char*)&ivalue, sizeof(ivalue)) == 0; } }; diff --git a/src/openrct2/network/UdpSocket.h b/src/openrct2/network/UdpSocket.h index 07beec7a75..a2523e3719 100644 --- a/src/openrct2/network/UdpSocket.h +++ b/src/openrct2/network/UdpSocket.h @@ -31,6 +31,18 @@ enum NETWORK_READPACKET NETWORK_READPACKET_DISCONNECTED }; +/** + * Represents an address and port. + */ +interface INetworkEndpoint +{ + virtual ~INetworkEndpoint() + { + } + + virtual std::string GetHostname() abstract; +}; + /** * Represents a UDP socket / listener. */ @@ -49,7 +61,9 @@ public: virtual void Listen(const std::string& address, uint16_t port) abstract; virtual size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) abstract; - virtual NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) abstract; + virtual size_t SendData(const INetworkEndpoint& destination, const void* buffer, size_t size) abstract; + virtual NETWORK_READPACKET ReceiveData( + void* buffer, size_t size, size_t* sizeReceived, std::unique_ptr* sender) abstract; virtual void Close() abstract; }; From 123a8eacad2cbe78d11280745c2a0719a9270b54 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 02:18:50 +0000 Subject: [PATCH 339/506] Get the server list showing LAN servers --- src/openrct2-ui/windows/ServerList.cpp | 74 ++++++++++++------- src/openrct2/core/Json.cpp | 4 +- src/openrct2/core/Json.hpp | 3 +- src/openrct2/network/Network.cpp | 23 +++++- .../network/NetworkServerAdvertiser.cpp | 7 +- src/openrct2/network/UdpSocket.cpp | 4 +- src/openrct2/network/network.h | 2 + 7 files changed, 80 insertions(+), 37 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index fde87fa51a..efd389b2f1 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #ifndef DISABLE_HTTP @@ -147,8 +148,10 @@ static void sort_servers(); static void join_server(std::string address); #ifndef DISABLE_HTTP static void fetch_servers(); +static uint32_t get_total_player_count(); static void fetch_servers_callback(Http::Response& response); static void RefreshServersFromJson(const json_t* jsonServers); +static void AddServerFromJson(const json_t* server); #endif static bool is_version_valid(const std::string& version); @@ -638,28 +641,41 @@ static void join_server(std::string address) #ifndef DISABLE_HTTP -static void fetch_lan_servers() +static void fetch_lan_servers_worker() { std::string msg = "Are you an OpenRCT2 server?"; auto udpSocket = CreateUdpSocket(); auto len = udpSocket->SendData("192.168.1.255", 11754, msg.data(), msg.size()); if (len == msg.size()) { - char buffer[256]{}; + char buffer[1024]{}; size_t recievedLen{}; std::unique_ptr endpoint; for (int i = 0; i < 5 * 10; i++) { - auto p = udpSocket->ReceiveData(buffer, sizeof(buffer), &recievedLen, &endpoint); + auto p = udpSocket->ReceiveData(buffer, sizeof(buffer) - 1, &recievedLen, &endpoint); if (p == NETWORK_READPACKET_SUCCESS) { auto sender = endpoint->GetHostname(); std::printf(">> Recieved packet from %s\n", sender.c_str()); - std::printf(">> %s\n", buffer); + auto jinfo = Json::FromString(std::string_view(buffer)); + AddServerFromJson(jinfo); + json_decref(jinfo); } usleep(100 * 1000); } } + + sort_servers(); + _numPlayersOnline = get_total_player_count(); + status_text = STR_X_PLAYERS_ONLINE; + window_invalidate_by_class(WC_SERVER_LIST); +} + +static void fetch_lan_servers() +{ + std::thread worker(fetch_lan_servers_worker); + worker.detach(); } static void fetch_servers() @@ -757,28 +773,38 @@ static void RefreshServersFromJson(const json_t* jsonServers) for (int32_t i = 0; i < count; i++) { auto server = json_array_get(jsonServers, i); - if (!json_is_object(server)) + if (json_is_object(server)) { - continue; + AddServerFromJson(server); } + } - auto port = json_object_get(server, "port"); - auto name = json_object_get(server, "name"); - auto description = json_object_get(server, "description"); - auto requiresPassword = json_object_get(server, "requiresPassword"); - auto version = json_object_get(server, "version"); - auto players = json_object_get(server, "players"); - auto maxPlayers = json_object_get(server, "maxPlayers"); - auto ip = json_object_get(server, "ip"); - auto ip4 = json_object_get(ip, "v4"); - auto addressIp = json_array_get(ip4, 0); + sort_servers(); + _numPlayersOnline = get_total_player_count(); - if (name == nullptr || version == nullptr) - { - log_verbose("Cowardly refusing to add server without name or version specified."); - continue; - } + status_text = STR_X_PLAYERS_ONLINE; + window_invalidate_by_class(WC_SERVER_LIST); +} +static void AddServerFromJson(const json_t* server) +{ + auto port = json_object_get(server, "port"); + auto name = json_object_get(server, "name"); + auto description = json_object_get(server, "description"); + auto requiresPassword = json_object_get(server, "requiresPassword"); + auto version = json_object_get(server, "version"); + auto players = json_object_get(server, "players"); + auto maxPlayers = json_object_get(server, "maxPlayers"); + auto ip = json_object_get(server, "ip"); + auto ip4 = json_object_get(ip, "v4"); + auto addressIp = json_array_get(ip4, 0); + + if (name == nullptr || version == nullptr) + { + log_verbose("Cowardly refusing to add server without name or version specified."); + } + else + { auto address = String::StdFormat("%s:%d", json_string_value(addressIp), (int32_t)json_integer_value(port)); { std::lock_guard guard(_mutex); @@ -791,12 +817,6 @@ static void RefreshServersFromJson(const json_t* jsonServers) newserver.maxplayers = (uint8_t)json_integer_value(maxPlayers); } } - - sort_servers(); - _numPlayersOnline = get_total_player_count(); - - status_text = STR_X_PLAYERS_ONLINE; - window_invalidate_by_class(WC_SERVER_LIST); } #endif diff --git a/src/openrct2/core/Json.cpp b/src/openrct2/core/Json.cpp index 94b129133a..87fd5a6799 100644 --- a/src/openrct2/core/Json.cpp +++ b/src/openrct2/core/Json.cpp @@ -53,11 +53,11 @@ namespace Json fs.Write(jsonOutput, jsonOutputSize); } - json_t* FromString(const std::string& raw) + json_t* FromString(const std::string_view& raw) { json_t* root; json_error_t error; - root = json_loads(raw.c_str(), 0, &error); + root = json_loadb(raw.data(), raw.size(), 0, &error); if (root == nullptr) { throw JsonException(&error); diff --git a/src/openrct2/core/Json.hpp b/src/openrct2/core/Json.hpp index c3d97fc408..693097ec46 100644 --- a/src/openrct2/core/Json.hpp +++ b/src/openrct2/core/Json.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace Json { @@ -23,7 +24,7 @@ namespace Json json_t* ReadFromFile(const utf8* path, size_t maxSize = MAX_JSON_SIZE); void WriteToFile(const utf8* path, const json_t* json, size_t flags = 0); - json_t* FromString(const std::string& raw); + json_t* FromString(const std::string_view& raw); } // namespace Json class JsonException final : public std::runtime_error diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 8a24933a11..39e24cfaac 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -201,6 +201,7 @@ public: void Server_Send_OBJECTS(NetworkConnection& connection, const std::vector& objects) const; NetworkStats_t GetStats() const; + json_t* GetServerInfoAsJson() const; std::vector> player_list; std::vector> group_list; @@ -1810,11 +1811,8 @@ void Network::Server_Send_SETDISCONNECTMSG(NetworkConnection& connection, const connection.QueuePacket(std::move(packet)); } -void Network::Server_Send_GAMEINFO(NetworkConnection& connection) +json_t* Network::GetServerInfoAsJson() const { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32_t)NETWORK_COMMAND_GAMEINFO; -# ifndef DISABLE_HTTP json_t* obj = json_object(); json_object_set_new(obj, "name", json_string(gConfigNetwork.server_name.c_str())); json_object_set_new(obj, "requiresPassword", json_boolean(_password.size() > 0)); @@ -1824,6 +1822,15 @@ void Network::Server_Send_GAMEINFO(NetworkConnection& connection) json_object_set_new(obj, "description", json_string(gConfigNetwork.server_description.c_str())); json_object_set_new(obj, "greeting", json_string(gConfigNetwork.server_greeting.c_str())); json_object_set_new(obj, "dedicated", json_boolean(gOpenRCT2Headless)); + return obj; +} + +void Network::Server_Send_GAMEINFO(NetworkConnection& connection) +{ + std::unique_ptr packet(NetworkPacket::Allocate()); + *packet << (uint32_t)NETWORK_COMMAND_GAMEINFO; +# ifndef DISABLE_HTTP + json_t* obj = GetServerInfoAsJson(); // Provider details json_t* jsonProvider = json_object(); @@ -4175,6 +4182,10 @@ bool network_gamestate_snapshots_enabled() return network_get_server_state().gamestateSnapshotsEnabled; } +json_t* network_get_server_info_as_json() +{ + return gNetwork.GetServerInfoAsJson(); +} #else int32_t network_get_mode() { @@ -4432,4 +4443,8 @@ NetworkServerState_t network_get_server_state() { return NetworkServerState_t{}; } +json_t* network_get_server_info_as_json() +{ + return nullptr; +} #endif /* DISABLE_NETWORK */ diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index f347d193ba..c60be89ffa 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -103,7 +103,7 @@ public: std::string sender = endpoint->GetHostname(); std::printf("\r>> Received %zu bytes from %s\n", recievedBytes, sender.c_str()); - auto body = GetHeartbeatJson(); + auto body = GetBroadcastJson(); auto bodyDump = json_dumps(body, JSON_COMPACT); size_t sendLen = strlen(bodyDump) + 1; std::printf("\r>> Sending %zu bytes back to %s\n", sendLen, sender.c_str()); @@ -279,6 +279,11 @@ private: return root; } + json_t* GetBroadcastJson() + { + return network_get_server_info_as_json(); + } + static std::string GenerateAdvertiseKey() { // Generate a string of 16 random hex characters (64-integer key as a hex formatted string) diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp index 80c13e2f26..a08bdd97b3 100644 --- a/src/openrct2/network/UdpSocket.cpp +++ b/src/openrct2/network/UdpSocket.cpp @@ -289,7 +289,7 @@ public: void* buffer, size_t size, size_t* sizeReceived, std::unique_ptr* sender) override { sockaddr_in senderAddr{}; - socklen_t senderAddrLen{}; + socklen_t senderAddrLen = sizeof(sockaddr_in); if (_status != SOCKET_STATUS_LISTENING) { senderAddrLen = _endpoint.GetAddressLen(); @@ -345,7 +345,7 @@ private: std::string serviceName = std::to_string(port); addrinfo hints = {}; - hints.ai_family = AF_UNSPEC; + hints.ai_family = AF_INET; if (address.empty()) { hints.ai_flags = AI_PASSIVE; diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index f19a83f8b3..080e567639 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -19,6 +19,7 @@ #include #include +struct json_t; struct GameAction; struct Peep; struct LocationXYZ16; @@ -109,3 +110,4 @@ std::string network_get_version(); NetworkStats_t network_get_stats(); NetworkServerState_t network_get_server_state(); +json_t* network_get_server_info_as_json(); From 7a20874366f83c251f7b5e340feb13ecdc285446 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 02:34:14 +0100 Subject: [PATCH 340/506] Fix Windows build --- src/openrct2-ui/windows/ServerList.cpp | 5 +++-- src/openrct2/network/UdpSocket.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index efd389b2f1..6b64fdb636 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -662,7 +663,7 @@ static void fetch_lan_servers_worker() AddServerFromJson(jinfo); json_decref(jinfo); } - usleep(100 * 1000); + platform_sleep(100); } } @@ -680,7 +681,7 @@ static void fetch_lan_servers() static void fetch_servers() { - if (1 == 1) + if (toupper('A') == 'A') { fetch_lan_servers(); } diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp index a08bdd97b3..2f02c08219 100644 --- a/src/openrct2/network/UdpSocket.cpp +++ b/src/openrct2/network/UdpSocket.cpp @@ -366,7 +366,7 @@ private: else { std::memcpy(ss, result->ai_addr, result->ai_addrlen); - *ss_len = result->ai_addrlen; + *ss_len = (socklen_t)result->ai_addrlen; freeaddrinfo(result); return true; } From 443711380578467bbc90a0b67798d701f201cfe5 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 02:34:45 +0000 Subject: [PATCH 341/506] Fix server list LAN address and port --- src/openrct2-ui/windows/ServerList.cpp | 7 +++++++ src/openrct2/network/NetworkServerAdvertiser.cpp | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 6b64fdb636..e350c909b0 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -660,6 +660,13 @@ static void fetch_lan_servers_worker() auto sender = endpoint->GetHostname(); std::printf(">> Recieved packet from %s\n", sender.c_str()); auto jinfo = Json::FromString(std::string_view(buffer)); + + auto ip4 = json_array(); + json_array_append_new(ip4, json_string(sender.c_str())); + auto ip = json_object(); + json_object_set_new(ip, "v4", ip4); + json_object_set_new(jinfo, "ip", ip); + AddServerFromJson(jinfo); json_decref(jinfo); } diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index c60be89ffa..bdfaa4beda 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -281,7 +281,9 @@ private: json_t* GetBroadcastJson() { - return network_get_server_info_as_json(); + auto root = network_get_server_info_as_json(); + json_object_set(root, "port", json_integer(_port)); + return root; } static std::string GenerateAdvertiseKey() From 3a400a2471b7e15f9a009f859ef285f75d297409 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 13:15:46 +0000 Subject: [PATCH 342/506] Refactor server list --- src/openrct2-ui/windows/ServerList.cpp | 433 ++++++------------------- src/openrct2/network/ServerList.cpp | 262 ++++++++++++++- src/openrct2/network/ServerList.h | 55 +++- 3 files changed, 405 insertions(+), 345 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index e350c909b0..c39dab3b54 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -8,8 +8,7 @@ *****************************************************************************/ #include -#include -#include +#include #include #include #include @@ -27,8 +26,6 @@ #include #include #include -#include -#include #ifndef DISABLE_HTTP using namespace OpenRCT2::Network; @@ -40,20 +37,9 @@ using namespace OpenRCT2::Network; #define WHEIGHT_MAX 800 #define ITEM_HEIGHT (3 + 9 + 3) -class MasterServerException : public std::exception -{ -public: - rct_string_id StatusText; - - MasterServerException(rct_string_id statusText) - : StatusText(statusText) - { - } -}; - static char _playerName[32 + 1]; -static std::vector _serverEntries; -static std::mutex _mutex; +static ServerList _serverList; +static std::future> _fetchFuture; static uint32_t _numPlayersOnline = 0; static rct_string_id status_text = STR_SERVER_LIST_CONNECTING; @@ -141,20 +127,9 @@ static int32_t _hoverButtonIndex = -1; static std::string _version; static void server_list_get_item_button(int32_t buttonIndex, int32_t x, int32_t y, int32_t width, int32_t* outX, int32_t* outY); -static void server_list_load_server_entries(); -static void server_list_save_server_entries(); -static void dispose_server_entry_list(); -static server_entry& add_server_entry(const std::string& address); -static void sort_servers(); static void join_server(std::string address); -#ifndef DISABLE_HTTP -static void fetch_servers(); -static uint32_t get_total_player_count(); -static void fetch_servers_callback(Http::Response& response); -static void RefreshServersFromJson(const json_t* jsonServers); -static void AddServerFromJson(const json_t* server); -#endif -static bool is_version_valid(const std::string& version); +static void server_list_fetch_servers_begin(); +static void server_list_fetch_servers_check(rct_window* w); rct_window* window_server_list_open() { @@ -188,20 +163,18 @@ rct_window* window_server_list_open() safe_strcpy(_playerName, gConfigNetwork.player_name.c_str(), sizeof(_playerName)); - server_list_load_server_entries(); - window->no_list_items = (uint16_t)_serverEntries.size(); + _serverList.ReadAndAddFavourites(); + window->no_list_items = (uint16_t)_serverList.GetCount(); -#ifndef DISABLE_HTTP - fetch_servers(); -#endif + server_list_fetch_servers_begin(); return window; } static void window_server_list_close(rct_window* w) { - std::lock_guard guard(_mutex); - dispose_server_entry_list(); + _serverList = {}; + _fetchFuture = {}; } static void window_server_list_mouseup(rct_window* w, rct_widgetindex widgetIndex) @@ -217,10 +190,10 @@ static void window_server_list_mouseup(rct_window* w, rct_widgetindex widgetInde case WIDX_LIST: { int32_t serverIndex = w->selected_list_item; - if (serverIndex >= 0 && serverIndex < (int32_t)_serverEntries.size()) + if (serverIndex >= 0 && serverIndex < (int32_t)_serverList.GetCount()) { - const auto& server = _serverEntries[serverIndex]; - if (is_version_valid(server.version)) + const auto& server = _serverList.GetServer(serverIndex); + if (server.IsVersionValid()) { join_server(server.address); } @@ -233,9 +206,7 @@ static void window_server_list_mouseup(rct_window* w, rct_widgetindex widgetInde break; } case WIDX_FETCH_SERVERS: -#ifndef DISABLE_HTTP - fetch_servers(); -#endif + server_list_fetch_servers_begin(); break; case WIDX_ADD_SERVER: window_text_input_open(w, widgetIndex, STR_ADD_SERVER, STR_ENTER_HOSTNAME_OR_IP_ADDRESS, STR_NONE, 0, 128); @@ -254,27 +225,26 @@ static void window_server_list_resize(rct_window* w) static void window_server_list_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) { auto serverIndex = w->selected_list_item; - if (serverIndex >= 0 && serverIndex < (int32_t)_serverEntries.size()) + if (serverIndex >= 0 && serverIndex < (int32_t)_serverList.GetCount()) { - auto& server = _serverEntries[serverIndex]; + auto& server = _serverList.GetServer(serverIndex); switch (dropdownIndex) { case DDIDX_JOIN: - if (is_version_valid(server.version)) + if (server.IsVersionValid()) { join_server(server.address); } else { - set_format_arg(0, void*, _serverEntries[serverIndex].version.c_str()); + set_format_arg(0, void*, server.version.c_str()); context_show_error(STR_UNABLE_TO_CONNECT_TO_SERVER, STR_MULTIPLAYER_INCORRECT_SOFTWARE_VERSION); } break; case DDIDX_FAVOURITE: { - std::lock_guard guard(_mutex); server.favourite = !server.favourite; - server_list_save_server_entries(); + _serverList.WriteFavourites(); } break; } @@ -288,6 +258,7 @@ static void window_server_list_update(rct_window* w) window_update_textbox_caret(); widget_invalidate(w, WIDX_PLAYER_NAME_INPUT); } + server_list_fetch_servers_check(w); } static void window_server_list_scroll_getsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) @@ -299,25 +270,25 @@ static void window_server_list_scroll_getsize(rct_window* w, int32_t scrollIndex static void window_server_list_scroll_mousedown(rct_window* w, int32_t scrollIndex, int32_t x, int32_t y) { int32_t serverIndex = w->selected_list_item; - if (serverIndex < 0) - return; - if (serverIndex >= (int32_t)_serverEntries.size()) - return; - - rct_widget* listWidget = &w->widgets[WIDX_LIST]; - int32_t ddx = w->x + listWidget->left + x + 2 - w->scrolls[0].h_left; - int32_t ddy = w->y + listWidget->top + y + 2 - w->scrolls[0].v_top; - - gDropdownItemsFormat[0] = STR_JOIN_GAME; - if (_serverEntries[serverIndex].favourite) + if (serverIndex >= 0 && serverIndex < (int32_t)_serverList.GetCount()) { - gDropdownItemsFormat[1] = STR_REMOVE_FROM_FAVOURITES; + const auto& server = _serverList.GetServer(serverIndex); + + auto listWidget = &w->widgets[WIDX_LIST]; + int32_t ddx = w->x + listWidget->left + x + 2 - w->scrolls[0].h_left; + int32_t ddy = w->y + listWidget->top + y + 2 - w->scrolls[0].v_top; + + gDropdownItemsFormat[0] = STR_JOIN_GAME; + if (server.favourite) + { + gDropdownItemsFormat[1] = STR_REMOVE_FROM_FAVOURITES; + } + else + { + gDropdownItemsFormat[1] = STR_ADD_TO_FAVOURITES; + } + window_dropdown_show_text(ddx, ddy, 0, COLOUR_GREY, 0, 2); } - else - { - gDropdownItemsFormat[1] = STR_ADD_TO_FAVOURITES; - } - window_dropdown_show_text(ddx, ddy, 0, COLOUR_GREY, 0, 2); } static void window_server_list_scroll_mouseover(rct_window* w, int32_t scrollIndex, int32_t x, int32_t y) @@ -392,14 +363,15 @@ static void window_server_list_textinput(rct_window* w, rct_widgetindex widgetIn case WIDX_ADD_SERVER: { - std::lock_guard guard(_mutex); - auto& entry = add_server_entry(text); + ServerListEntry entry; + entry.address = text; + entry.name = text; entry.favourite = true; - sort_servers(); - server_list_save_server_entries(); - } + _serverList.Add(entry); + _serverList.WriteFavourites(); window_invalidate(w); break; + } } } @@ -429,7 +401,7 @@ static void window_server_list_invalidate(rct_window* w) window_server_list_widgets[WIDX_START_SERVER].top = buttonTop; window_server_list_widgets[WIDX_START_SERVER].bottom = buttonBottom; - w->no_list_items = (uint16_t)_serverEntries.size(); + w->no_list_items = (uint16_t)_serverList.GetCount(); } static void window_server_list_paint(rct_window* w, rct_drawpixelinfo* dpi) @@ -449,8 +421,6 @@ static void window_server_list_paint(rct_window* w, rct_drawpixelinfo* dpi) static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex) { - std::lock_guard guard(_mutex); - uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); @@ -464,31 +434,31 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi continue; // if (y + ITEM_HEIGHT < dpi->y) continue; - server_entry* serverDetails = &_serverEntries[i]; + const auto& serverDetails = _serverList.GetServer(i); bool highlighted = i == w->selected_list_item; // Draw hover highlight if (highlighted) { gfx_filter_rect(dpi, 0, y, width, y + ITEM_HEIGHT, PALETTE_DARKEN_1); - _version = serverDetails->version; + _version = serverDetails.version; w->widgets[WIDX_LIST].tooltip = STR_NETWORK_VERSION_TIP; } int32_t colour = w->colours[1]; - if (serverDetails->favourite) + if (serverDetails.favourite) { colour = COLOUR_YELLOW; } // Draw server information - if (highlighted && !serverDetails->description.empty()) + if (highlighted && !serverDetails.description.empty()) { - gfx_draw_string(dpi, serverDetails->description.c_str(), colour, 3, y + 3); + gfx_draw_string(dpi, serverDetails.description.c_str(), colour, 3, y + 3); } else { - gfx_draw_string(dpi, serverDetails->name.c_str(), colour, 3, y + 3); + gfx_draw_string(dpi, serverDetails.name.c_str(), colour, 3, y + 3); } int32_t right = width - 3 - 14; @@ -496,7 +466,7 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi // Draw compatibility icon right -= 10; int32_t compatibilitySpriteId; - if (serverDetails->version.empty()) + if (serverDetails.version.empty()) { // Server not online... compatibilitySpriteId = SPR_G2_RCT1_CLOSE_BUTTON_0; @@ -504,7 +474,7 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi else { // Server online... check version - bool correctVersion = serverDetails->version == network_get_version(); + bool correctVersion = serverDetails.version == network_get_version(); compatibilitySpriteId = correctVersion ? SPR_G2_RCT1_OPEN_BUTTON_2 : SPR_G2_RCT1_CLOSE_BUTTON_2; } gfx_draw_sprite(dpi, compatibilitySpriteId, right, y + 1, 0); @@ -512,7 +482,7 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi // Draw lock icon right -= 8; - if (serverDetails->requiresPassword) + if (serverDetails.requiresPassword) { gfx_draw_sprite(dpi, SPR_G2_LOCKED, right, y + 4, 0); } @@ -521,9 +491,9 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi // Draw number of players char players[32]; players[0] = 0; - if (serverDetails->maxplayers > 0) + if (serverDetails.maxplayers > 0) { - snprintf(players, 32, "%d/%d", serverDetails->players, serverDetails->maxplayers); + snprintf(players, 32, "%d/%d", serverDetails.players, serverDetails.maxplayers); } int32_t numPlayersStringWidth = gfx_get_string_width(players); gfx_draw_string(dpi, players, w->colours[1], right - numPlayersStringWidth, y + 3); @@ -538,81 +508,6 @@ static void server_list_get_item_button(int32_t buttonIndex, int32_t x, int32_t *outY = y + 2; } -static void server_list_load_server_entries() -{ - auto entries = server_list_read(); - { - std::lock_guard guard(_mutex); - dispose_server_entry_list(); - _serverEntries = entries; - sort_servers(); - } -} - -static void server_list_save_server_entries() -{ - // Save just favourite servers - std::vector favouriteServers; - std::copy_if( - _serverEntries.begin(), _serverEntries.end(), std::back_inserter(favouriteServers), - [](const server_entry& entry) { return entry.favourite; }); - server_list_write(favouriteServers); -} - -static void dispose_server_entry_list() -{ - _serverEntries.clear(); - _serverEntries.shrink_to_fit(); -} - -static server_entry& add_server_entry(const std::string& address) -{ - auto entry = std::find_if(std::begin(_serverEntries), std::end(_serverEntries), [address](const server_entry& e) { - return e.address == address; - }); - if (entry != _serverEntries.end()) - { - return *entry; - } - - server_entry newserver; - newserver.address = address; - newserver.name = address; - _serverEntries.push_back(newserver); - return _serverEntries.back(); -} - -static bool server_compare(const server_entry& a, const server_entry& b) -{ - // Order by favourite - if (a.favourite != b.favourite) - { - return a.favourite; - } - - // Then by version - bool serverACompatible = a.version == network_get_version(); - bool serverBCompatible = b.version == network_get_version(); - if (serverACompatible != serverBCompatible) - { - return serverACompatible; - } - - // Then by password protection - if (a.requiresPassword != b.requiresPassword) - { - return !a.requiresPassword; - } - - // Then by name - return String::Compare(a.name, b.name, true) < 0; -} - -static void sort_servers() -{ - std::sort(_serverEntries.begin(), _serverEntries.end(), server_compare); -} - static void join_server(std::string address) { int32_t port = gConfigNetwork.default_port; @@ -640,196 +535,68 @@ static void join_server(std::string address) } } -#ifndef DISABLE_HTTP - -static void fetch_lan_servers_worker() +static void server_list_fetch_servers_begin() { - std::string msg = "Are you an OpenRCT2 server?"; - auto udpSocket = CreateUdpSocket(); - auto len = udpSocket->SendData("192.168.1.255", 11754, msg.data(), msg.size()); - if (len == msg.size()) + if (_fetchFuture.valid()) { - char buffer[1024]{}; - size_t recievedLen{}; - std::unique_ptr endpoint; - for (int i = 0; i < 5 * 10; i++) - { - auto p = udpSocket->ReceiveData(buffer, sizeof(buffer) - 1, &recievedLen, &endpoint); - if (p == NETWORK_READPACKET_SUCCESS) - { - auto sender = endpoint->GetHostname(); - std::printf(">> Recieved packet from %s\n", sender.c_str()); - auto jinfo = Json::FromString(std::string_view(buffer)); - - auto ip4 = json_array(); - json_array_append_new(ip4, json_string(sender.c_str())); - auto ip = json_object(); - json_object_set_new(ip, "v4", ip4); - json_object_set_new(jinfo, "ip", ip); - - AddServerFromJson(jinfo); - json_decref(jinfo); - } - platform_sleep(100); - } + // A fetch is already in progress + return; } - sort_servers(); - _numPlayersOnline = get_total_player_count(); - status_text = STR_X_PLAYERS_ONLINE; - window_invalidate_by_class(WC_SERVER_LIST); -} + _fetchFuture = std::async([] { + // Spin off background fetches + auto lanF = _serverList.FetchLocalServerListAsync(); + auto wanF = _serverList.FetchOnlineServerListAsync(); -static void fetch_lan_servers() -{ - std::thread worker(fetch_lan_servers_worker); - worker.detach(); -} - -static void fetch_servers() -{ - if (toupper('A') == 'A') - { - fetch_lan_servers(); - } - else - { - std::string masterServerUrl = OPENRCT2_MASTER_SERVER_URL; - if (gConfigNetwork.master_server_url.empty() == false) + // Merge or deal with errors + std::vector allEntries; + try + { + auto entries = lanF.get(); + allEntries.insert(allEntries.end(), entries.begin(), entries.end()); + } + catch (const std::exception& e) { - masterServerUrl = gConfigNetwork.master_server_url; } + try + { + auto entries = wanF.get(); + allEntries.insert(allEntries.end(), entries.begin(), entries.end()); + } + catch (const std::exception& e) { - std::lock_guard guard(_mutex); - _serverEntries.erase( - std::remove_if( - _serverEntries.begin(), _serverEntries.end(), [](const server_entry& server) { return !server.favourite; }), - _serverEntries.end()); - sort_servers(); } - Http::Request request; - request.url = masterServerUrl; - request.method = Http::Method::GET; - request.header["Accept"] = "application/json"; - status_text = STR_SERVER_LIST_CONNECTING; - Http::DoAsync(request, fetch_servers_callback); - } -} - -static uint32_t get_total_player_count() -{ - return std::accumulate(_serverEntries.begin(), _serverEntries.end(), 0, [](uint32_t acc, const server_entry& entry) { - return acc + entry.players; + return allEntries; }); } -static void fetch_servers_callback(Http::Response& response) +static void server_list_fetch_servers_check(rct_window* w) { - json_t* root = nullptr; - try + if (_fetchFuture.valid()) { - if (response.status != Http::Status::OK) + auto status = _fetchFuture.wait_for(std::chrono::seconds::zero()); + if (status == std::future_status::ready) { - throw MasterServerException(STR_SERVER_LIST_NO_CONNECTION); - } - - root = Json::FromString(response.body); - auto jsonStatus = json_object_get(root, "status"); - if (!json_is_number(jsonStatus)) - { - throw MasterServerException(STR_SERVER_LIST_INVALID_RESPONSE_JSON_NUMBER); - } - - auto status = (int32_t)json_integer_value(jsonStatus); - if (status != 200) - { - throw MasterServerException(STR_SERVER_LIST_MASTER_SERVER_FAILED); - } - - auto jsonServers = json_object_get(root, "servers"); - if (!json_is_array(jsonServers)) - { - throw MasterServerException(STR_SERVER_LIST_INVALID_RESPONSE_JSON_ARRAY); - } - - RefreshServersFromJson(jsonServers); - } - catch (const MasterServerException& e) - { - status_text = e.StatusText; - window_invalidate_by_class(WC_SERVER_LIST); - } - catch (const std::exception& e) - { - status_text = STR_SERVER_LIST_NO_CONNECTION; - window_invalidate_by_class(WC_SERVER_LIST); - log_warning("Unable to connect to master server: %s", e.what()); - } - - if (root != nullptr) - { - json_decref(root); - root = nullptr; - } -} - -static void RefreshServersFromJson(const json_t* jsonServers) -{ - auto count = (int32_t)json_array_size(jsonServers); - for (int32_t i = 0; i < count; i++) - { - auto server = json_array_get(jsonServers, i); - if (json_is_object(server)) - { - AddServerFromJson(server); - } - } - - sort_servers(); - _numPlayersOnline = get_total_player_count(); - - status_text = STR_X_PLAYERS_ONLINE; - window_invalidate_by_class(WC_SERVER_LIST); -} - -static void AddServerFromJson(const json_t* server) -{ - auto port = json_object_get(server, "port"); - auto name = json_object_get(server, "name"); - auto description = json_object_get(server, "description"); - auto requiresPassword = json_object_get(server, "requiresPassword"); - auto version = json_object_get(server, "version"); - auto players = json_object_get(server, "players"); - auto maxPlayers = json_object_get(server, "maxPlayers"); - auto ip = json_object_get(server, "ip"); - auto ip4 = json_object_get(ip, "v4"); - auto addressIp = json_array_get(ip4, 0); - - if (name == nullptr || version == nullptr) - { - log_verbose("Cowardly refusing to add server without name or version specified."); - } - else - { - auto address = String::StdFormat("%s:%d", json_string_value(addressIp), (int32_t)json_integer_value(port)); - { - std::lock_guard guard(_mutex); - auto& newserver = add_server_entry(address); - newserver.name = json_string_value(name); - newserver.requiresPassword = json_is_true(requiresPassword); - newserver.description = (description == nullptr ? "" : json_string_value(description)); - newserver.version = json_string_value(version); - newserver.players = (uint8_t)json_integer_value(players); - newserver.maxplayers = (uint8_t)json_integer_value(maxPlayers); + try + { + auto entries = _fetchFuture.get(); + _serverList.AddRange(entries); + _numPlayersOnline = _serverList.GetTotalPlayerCount(); + status_text = STR_X_PLAYERS_ONLINE; + } + catch (const MasterServerException& e) + { + status_text = e.StatusText; + } + catch (const std::exception& e) + { + status_text = STR_SERVER_LIST_NO_CONNECTION; + log_warning("Unable to connect to master server: %s", e.what()); + } + _fetchFuture = {}; + window_invalidate(w); } } } - -#endif - -static bool is_version_valid(const std::string& version) -{ - return version.empty() || version == network_get_version(); -} diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index d565ab0d68..4a90db8e2b 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -11,18 +11,122 @@ #include "../Context.h" #include "../PlatformEnvironment.h" +#include "../config/Config.h" #include "../core/FileStream.hpp" +#include "../core/Json.hpp" #include "../core/Memory.hpp" #include "../core/Path.hpp" #include "../core/String.hpp" +#include "../network/Http.h" #include "../platform/platform.h" +#include "UdpSocket.h" +#include "network.h" + +#include +#include using namespace OpenRCT2; +using namespace OpenRCT2::Network; -std::vector server_list_read() +int32_t ServerListEntry::CompareTo(const ServerListEntry& other) const +{ + const auto& a = *this; + const auto& b = other; + + // Order by favourite + if (a.favourite != b.favourite) + { + return a.favourite ? -1 : 1; + } + + // Then by version + bool serverACompatible = a.version == network_get_version(); + bool serverBCompatible = b.version == network_get_version(); + if (serverACompatible != serverBCompatible) + { + return serverACompatible ? 1 : -1; + } + + // Then by password protection + if (a.requiresPassword != b.requiresPassword) + { + return a.requiresPassword ? -1 : 1; + } + + // Then by name + return String::Compare(a.name, b.name, true); +} + +bool ServerListEntry::IsVersionValid() const +{ + return version.empty() || version == network_get_version(); +} + +std::optional ServerListEntry::FromJson(const json_t* server) +{ + auto port = json_object_get(server, "port"); + auto name = json_object_get(server, "name"); + auto description = json_object_get(server, "description"); + auto requiresPassword = json_object_get(server, "requiresPassword"); + auto version = json_object_get(server, "version"); + auto players = json_object_get(server, "players"); + auto maxPlayers = json_object_get(server, "maxPlayers"); + auto ip = json_object_get(server, "ip"); + auto ip4 = json_object_get(ip, "v4"); + auto addressIp = json_array_get(ip4, 0); + + if (name == nullptr || version == nullptr) + { + log_verbose("Cowardly refusing to add server without name or version specified."); + return {}; + } + else + { + ServerListEntry entry; + entry.address = String::StdFormat("%s:%d", json_string_value(addressIp), (int32_t)json_integer_value(port)); + entry.name = (name == nullptr ? "" : json_string_value(name)); + entry.description = (description == nullptr ? "" : json_string_value(description)); + entry.version = json_string_value(version); + entry.requiresPassword = json_is_true(requiresPassword); + entry.players = (uint8_t)json_integer_value(players); + entry.maxplayers = (uint8_t)json_integer_value(maxPlayers); + return entry; + } +} + +void ServerList::Sort() +{ + std::sort(_serverEntries.begin(), _serverEntries.end(), [](const ServerListEntry& a, const ServerListEntry& b) { + return a.CompareTo(b) > 0; + }); +} + +ServerListEntry& ServerList::GetServer(size_t index) +{ + return _serverEntries[index]; +} + +size_t ServerList::GetCount() const +{ + return _serverEntries.size(); +} + +void ServerList::Add(const ServerListEntry& entry) +{ + _serverEntries.push_back(entry); + Sort(); +} + +void ServerList::AddRange(const std::vector& entries) +{ + _serverEntries.insert(_serverEntries.end(), entries.begin(), entries.end()); + Sort(); +} + +std::vector ServerList::ReadFavourites() { log_verbose("server_list_read(...)"); - std::vector entries; + std::vector entries; try { auto env = GetContext()->GetPlatformEnvironment(); @@ -33,7 +137,7 @@ std::vector server_list_read() auto numEntries = fs.ReadValue(); for (size_t i = 0; i < numEntries; i++) { - server_entry serverInfo; + ServerListEntry serverInfo; serverInfo.address = fs.ReadStdString(); serverInfo.name = fs.ReadStdString(); serverInfo.requiresPassword = false; @@ -49,12 +153,32 @@ std::vector server_list_read() catch (const std::exception& e) { log_error("Unable to read server list: %s", e.what()); - entries = std::vector(); + entries = std::vector(); } return entries; } -bool server_list_write(const std::vector& entries) +void ServerList::ReadAndAddFavourites() +{ + _serverEntries.erase( + std::remove_if( + _serverEntries.begin(), _serverEntries.end(), [](const ServerListEntry& entry) { return entry.favourite; }), + _serverEntries.end()); + auto entries = ReadFavourites(); + AddRange(entries); +} + +void ServerList::WriteFavourites() +{ + // Save just favourite servers + std::vector favouriteServers; + std::copy_if( + _serverEntries.begin(), _serverEntries.end(), std::back_inserter(favouriteServers), + [](const ServerListEntry& entry) { return entry.favourite; }); + WriteFavourites(favouriteServers); +} + +bool ServerList::WriteFavourites(const std::vector& entries) { log_verbose("server_list_write(%d, 0x%p)", entries.size(), entries.data()); @@ -80,3 +204,131 @@ bool server_list_write(const std::vector& entries) return false; } } + +std::future> ServerList::FetchLocalServerListAsync() +{ + return std::async([] { + constexpr auto RECV_DELAY_MS = 10; + constexpr auto RECV_WAIT_MS = 2000; + + std::vector entries; + std::string msg = "Are you an OpenRCT2 server?"; + auto udpSocket = CreateUdpSocket(); + auto len = udpSocket->SendData("192.168.1.255", 11754, msg.data(), msg.size()); + if (len != msg.size()) + { + throw std::runtime_error("Unable to broadcast server query."); + } + + char buffer[1024]{}; + size_t recievedLen{}; + std::unique_ptr endpoint; + for (int i = 0; i < (RECV_WAIT_MS / RECV_DELAY_MS); i++) + { + auto p = udpSocket->ReceiveData(buffer, sizeof(buffer) - 1, &recievedLen, &endpoint); + if (p == NETWORK_READPACKET_SUCCESS) + { + auto sender = endpoint->GetHostname(); + std::printf(">> Recieved packet from %s\n", sender.c_str()); + auto jinfo = Json::FromString(std::string_view(buffer)); + + auto ip4 = json_array(); + json_array_append_new(ip4, json_string(sender.c_str())); + auto ip = json_object(); + json_object_set_new(ip, "v4", ip4); + json_object_set_new(jinfo, "ip", ip); + + auto entry = ServerListEntry::FromJson(jinfo); + if (entry.has_value()) + { + entries.push_back(entry.value()); + } + + json_decref(jinfo); + } + platform_sleep(RECV_DELAY_MS); + } + + return entries; + }); +} + +std::future> ServerList::FetchOnlineServerListAsync() +{ +#ifdef DISABLE_HTTP + return std::async(std::launch::deferred, [] { return std::vector(); }); +#else + auto p = std::make_shared>>(); + auto f = p->get_future(); + + std::string masterServerUrl = OPENRCT2_MASTER_SERVER_URL; + if (!gConfigNetwork.master_server_url.empty()) + { + masterServerUrl = gConfigNetwork.master_server_url; + } + + Http::Request request; + request.url = masterServerUrl; + request.method = Http::Method::GET; + request.header["Accept"] = "application/json"; + Http::DoAsync(request, [p](Http::Response& response) -> void { + json_t* root{}; + try + { + if (response.status != Http::Status::OK) + { + throw MasterServerException(STR_SERVER_LIST_NO_CONNECTION); + } + + root = Json::FromString(response.body); + auto jsonStatus = json_object_get(root, "status"); + if (!json_is_number(jsonStatus)) + { + throw MasterServerException(STR_SERVER_LIST_INVALID_RESPONSE_JSON_NUMBER); + } + + auto status = (int32_t)json_integer_value(jsonStatus); + if (status != 200) + { + throw MasterServerException(STR_SERVER_LIST_MASTER_SERVER_FAILED); + } + + auto jServers = json_object_get(root, "servers"); + if (!json_is_array(jServers)) + { + throw MasterServerException(STR_SERVER_LIST_INVALID_RESPONSE_JSON_ARRAY); + } + + std::vector entries; + auto count = json_array_size(jServers); + for (size_t i = 0; i < count; i++) + { + auto jServer = json_array_get(jServers, i); + if (json_is_object(jServer)) + { + auto entry = ServerListEntry::FromJson(jServer); + if (entry.has_value()) + { + entries.push_back(entry.value()); + } + } + } + + p->set_value(entries); + } + catch (...) + { + p->set_exception(std::current_exception()); + } + json_decref(root); + }); + return f; +#endif +} + +uint32_t ServerList::GetTotalPlayerCount() const +{ + return std::accumulate(_serverEntries.begin(), _serverEntries.end(), 0, [](uint32_t acc, const ServerListEntry& entry) { + return acc + entry.players; + }); +} diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index 22afcfbe69..6aaa510157 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -10,21 +10,62 @@ #pragma once #include "../common.h" +#include "../core/Optional.hpp" +#include +#include #include #include -struct server_entry +struct json_t; + +struct ServerListEntry { std::string address; std::string name; std::string description; std::string version; - bool requiresPassword = false; - bool favourite = false; - uint8_t players = 0; - uint8_t maxplayers = 0; + bool requiresPassword{}; + bool favourite{}; + uint8_t players{}; + uint8_t maxplayers{}; + + int32_t CompareTo(const ServerListEntry& other) const; + bool IsVersionValid() const; + + static std::optional FromJson(const json_t* root); }; -std::vector server_list_read(); -bool server_list_write(const std::vector& entries); +class ServerList +{ +private: + std::vector _serverEntries; + + void Sort(); + std::vector ReadFavourites(); + bool WriteFavourites(const std::vector& entries); + +public: + ServerListEntry& GetServer(size_t index); + size_t GetCount() const; + void Add(const ServerListEntry& entry); + void AddRange(const std::vector& entries); + + void ReadAndAddFavourites(); + void WriteFavourites(); + + std::future> FetchLocalServerListAsync(); + std::future> FetchOnlineServerListAsync(); + uint32_t GetTotalPlayerCount() const; +}; + +class MasterServerException : public std::exception +{ +public: + rct_string_id StatusText; + + MasterServerException(rct_string_id statusText) + : StatusText(statusText) + { + } +}; From 4f0a73349681a02e3e6227ed2209aee2104874f2 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 14:12:50 +0000 Subject: [PATCH 343/506] Sort by LAN servers --- src/openrct2/network/ServerList.cpp | 7 +++++++ src/openrct2/network/ServerList.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 4a90db8e2b..c4501b97a6 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -39,6 +39,12 @@ int32_t ServerListEntry::CompareTo(const ServerListEntry& other) const return a.favourite ? -1 : 1; } + // Order by local + if (a.local != b.local) + { + return a.local ? 1 : -1; + } + // Then by version bool serverACompatible = a.version == network_get_version(); bool serverBCompatible = b.version == network_get_version(); @@ -241,6 +247,7 @@ std::future> ServerList::FetchLocalServerListAsync( auto entry = ServerListEntry::FromJson(jinfo); if (entry.has_value()) { + entry.value().local = true; entries.push_back(entry.value()); } diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index 6aaa510157..7a1f6b4ced 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -29,6 +29,7 @@ struct ServerListEntry bool favourite{}; uint8_t players{}; uint8_t maxplayers{}; + bool local{}; int32_t CompareTo(const ServerListEntry& other) const; bool IsVersionValid() const; From 04c04d197e2b52cc700d7cf8b2d88098e62baa9c Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 14:28:10 +0000 Subject: [PATCH 344/506] Refactor broadcasting code and logging --- .../network/NetworkServerAdvertiser.cpp | 59 ++++++++++--------- src/openrct2/network/ServerList.cpp | 9 ++- src/openrct2/network/network.h | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index bdfaa4beda..e593d0db1e 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -47,8 +47,6 @@ enum MASTER_SERVER_STATUS constexpr int32_t MASTER_SERVER_REGISTER_TIME = 120 * 1000; // 2 minutes constexpr int32_t MASTER_SERVER_HEARTBEAT_TIME = 60 * 1000; // 1 minute -constexpr int32_t LAN_BROADCAST_PORT = 11754; - class NetworkServerAdvertiser final : public INetworkServerAdvertiser { private: @@ -84,13 +82,23 @@ public: } void Update() override + { + UpdateLAN(); + if (gConfigNetwork.advertise) + { + UpdateWAN(); + } + } + +private: + void UpdateLAN() { auto ticks = Platform::GetTicks(); if (ticks > _lastListenTime + 500) { if (_lanListener->GetStatus() != SOCKET_STATUS_LISTENING) { - _lanListener->Listen(LAN_BROADCAST_PORT); + _lanListener->Listen(NETWORK_LAN_BROADCAST_PORT); } else { @@ -101,12 +109,12 @@ public: if (p == NETWORK_READPACKET_SUCCESS) { std::string sender = endpoint->GetHostname(); - std::printf("\r>> Received %zu bytes from %s\n", recievedBytes, sender.c_str()); + log_verbose("Received %zu bytes from %s on LAN broadcast port", recievedBytes, sender.c_str()); auto body = GetBroadcastJson(); auto bodyDump = json_dumps(body, JSON_COMPACT); size_t sendLen = strlen(bodyDump) + 1; - std::printf("\r>> Sending %zu bytes back to %s\n", sendLen, sender.c_str()); + log_verbose("Sending %zu bytes back to %s", sendLen, sender.c_str()); _lanListener->SendData(*endpoint, bodyDump, sendLen); free(bodyDump); json_decref(body); @@ -114,33 +122,30 @@ public: } _lastListenTime = ticks; } + } - if (gConfigNetwork.advertise) + void UpdateWAN() + { + switch (_status) { - /* - switch (_status) - { - case ADVERTISE_STATUS::UNREGISTERED: - if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME) - { - SendRegistration(_forceIPv4); - } - break; - case ADVERTISE_STATUS::REGISTERED: - if (platform_get_ticks() > _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME) - { - SendHeartbeat(); - } - break; - // exhaust enum values to satisfy clang - case ADVERTISE_STATUS::DISABLED: - break; - } - */ + case ADVERTISE_STATUS::UNREGISTERED: + if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME) + { + SendRegistration(_forceIPv4); + } + break; + case ADVERTISE_STATUS::REGISTERED: + if (platform_get_ticks() > _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME) + { + SendHeartbeat(); + } + break; + // exhaust enum values to satisfy clang + case ADVERTISE_STATUS::DISABLED: + break; } } -private: void SendRegistration(bool forceIPv4) { _lastAdvertiseTime = platform_get_ticks(); diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index c4501b97a6..a7fe3ca586 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -217,15 +217,18 @@ std::future> ServerList::FetchLocalServerListAsync( constexpr auto RECV_DELAY_MS = 10; constexpr auto RECV_WAIT_MS = 2000; - std::vector entries; + auto broadcastAddress = "192.168.1.255"; + std::string msg = "Are you an OpenRCT2 server?"; auto udpSocket = CreateUdpSocket(); - auto len = udpSocket->SendData("192.168.1.255", 11754, msg.data(), msg.size()); + log_verbose("Broadcasting %zu bytes to the LAN (%s)", msg.size(), broadcastAddress); + auto len = udpSocket->SendData(broadcastAddress, NETWORK_LAN_BROADCAST_PORT, msg.data(), msg.size()); if (len != msg.size()) { throw std::runtime_error("Unable to broadcast server query."); } + std::vector entries; char buffer[1024]{}; size_t recievedLen{}; std::unique_ptr endpoint; @@ -235,7 +238,7 @@ std::future> ServerList::FetchLocalServerListAsync( if (p == NETWORK_READPACKET_SUCCESS) { auto sender = endpoint->GetHostname(); - std::printf(">> Recieved packet from %s\n", sender.c_str()); + log_verbose("Received %zu bytes back from %s", recievedLen, sender.c_str()); auto jinfo = Json::FromString(std::string_view(buffer)); auto ip4 = json_array(); diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 080e567639..0859cd4c42 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -10,6 +10,7 @@ #pragma once #define NETWORK_DEFAULT_PORT 11753 +#define NETWORK_LAN_BROADCAST_PORT 11754 #define MAX_SERVER_DESCRIPTION_LENGTH 256 #include "../common.h" From 51117432f0a148e8cc4a7085c360caee013cc610 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 15:48:35 +0000 Subject: [PATCH 345/506] Improve status messages and prevent duplicates --- src/openrct2-ui/windows/ServerList.cpp | 32 ++++++++++++++++++-------- src/openrct2/network/ServerList.cpp | 30 ++++++++++++++++++++---- src/openrct2/network/ServerList.h | 1 + 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index c39dab3b54..f10826ab62 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #ifndef DISABLE_HTTP using namespace OpenRCT2::Network; @@ -39,9 +40,9 @@ using namespace OpenRCT2::Network; static char _playerName[32 + 1]; static ServerList _serverList; -static std::future> _fetchFuture; +static std::future, rct_string_id>> _fetchFuture; static uint32_t _numPlayersOnline = 0; -static rct_string_id status_text = STR_SERVER_LIST_CONNECTING; +static rct_string_id _statusText = STR_SERVER_LIST_CONNECTING; // clang-format off enum { @@ -416,7 +417,7 @@ static void window_server_list_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string_left( dpi, STR_NETWORK_VERSION, (void*)&versionCStr, COLOUR_WHITE, w->x + 324, w->y + w->widgets[WIDX_START_SERVER].top + 1); - gfx_draw_string_left(dpi, status_text, (void*)&_numPlayersOnline, COLOUR_WHITE, w->x + 8, w->y + w->height - 15); + gfx_draw_string_left(dpi, _statusText, (void*)&_numPlayersOnline, COLOUR_WHITE, w->x + 8, w->y + w->height - 15); } static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex) @@ -543,6 +544,10 @@ static void server_list_fetch_servers_begin() return; } + _serverList.Clear(); + _serverList.ReadAndAddFavourites(); + _statusText = STR_SERVER_LIST_CONNECTING; + _fetchFuture = std::async([] { // Spin off background fetches auto lanF = _serverList.FetchLocalServerListAsync(); @@ -559,16 +564,21 @@ static void server_list_fetch_servers_begin() { } + auto status = STR_NONE; try { auto entries = wanF.get(); allEntries.insert(allEntries.end(), entries.begin(), entries.end()); } + catch (const MasterServerException& e) + { + status = e.StatusText; + } catch (const std::exception& e) { + status = STR_SERVER_LIST_NO_CONNECTION; } - - return allEntries; + return std::make_tuple(allEntries, status); }); } @@ -581,18 +591,22 @@ static void server_list_fetch_servers_check(rct_window* w) { try { - auto entries = _fetchFuture.get(); + auto [entries, statusText] = std::move(_fetchFuture.get()); _serverList.AddRange(entries); _numPlayersOnline = _serverList.GetTotalPlayerCount(); - status_text = STR_X_PLAYERS_ONLINE; + _statusText = STR_X_PLAYERS_ONLINE; + if (statusText != STR_NONE) + { + _statusText = statusText; + } } catch (const MasterServerException& e) { - status_text = e.StatusText; + _statusText = e.StatusText; } catch (const std::exception& e) { - status_text = STR_SERVER_LIST_NO_CONNECTION; + _statusText = STR_SERVER_LIST_NO_CONNECTION; log_warning("Unable to connect to master server: %s", e.what()); } _fetchFuture = {}; diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index a7fe3ca586..d8a0e999cd 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -42,7 +42,7 @@ int32_t ServerListEntry::CompareTo(const ServerListEntry& other) const // Order by local if (a.local != b.local) { - return a.local ? 1 : -1; + return a.local ? -1 : 1; } // Then by version @@ -50,13 +50,19 @@ int32_t ServerListEntry::CompareTo(const ServerListEntry& other) const bool serverBCompatible = b.version == network_get_version(); if (serverACompatible != serverBCompatible) { - return serverACompatible ? 1 : -1; + return serverACompatible ? -1 : 1; } // Then by password protection if (a.requiresPassword != b.requiresPassword) { - return a.requiresPassword ? -1 : 1; + return a.requiresPassword ? 1 : -1; + } + + // Then by number of players + if (a.players != b.players) + { + return a.players > b.players ? -1 : 1; } // Then by name @@ -102,8 +108,19 @@ std::optional ServerListEntry::FromJson(const json_t* server) void ServerList::Sort() { + _serverEntries.erase( + std::unique( + _serverEntries.begin(), _serverEntries.end(), + [](const ServerListEntry& a, const ServerListEntry& b) { + if (a.favourite == b.favourite) + { + return String::Equals(a.address, b.address, true); + } + return false; + }), + _serverEntries.end()); std::sort(_serverEntries.begin(), _serverEntries.end(), [](const ServerListEntry& a, const ServerListEntry& b) { - return a.CompareTo(b) > 0; + return a.CompareTo(b) < 0; }); } @@ -129,6 +146,11 @@ void ServerList::AddRange(const std::vector& entries) Sort(); } +void ServerList::Clear() +{ + _serverEntries.clear(); +} + std::vector ServerList::ReadFavourites() { log_verbose("server_list_read(...)"); diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index 7a1f6b4ced..e6a147cd1b 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -51,6 +51,7 @@ public: size_t GetCount() const; void Add(const ServerListEntry& entry); void AddRange(const std::vector& entries); + void Clear(); void ReadAndAddFavourites(); void WriteFavourites(); From 59ddd7e1ea921745f3c897439ad4bbcec1a7f8f8 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 16:23:58 +0000 Subject: [PATCH 346/506] Get and broadcast to all broadcast address --- src/openrct2/network/ServerList.cpp | 41 +++++++++-- src/openrct2/network/ServerList.h | 2 + src/openrct2/network/UdpSocket.cpp | 109 ++++++++++++++++++++++++++-- src/openrct2/network/UdpSocket.h | 4 +- 4 files changed, 144 insertions(+), 12 deletions(-) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index d8a0e999cd..edcaeb01e4 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -233,16 +233,16 @@ bool ServerList::WriteFavourites(const std::vector& entries) } } -std::future> ServerList::FetchLocalServerListAsync() +std::future> ServerList::FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint) { - return std::async([] { + auto broadcastAddress = broadcastEndpoint.GetHostname(); + return std::async([broadcastAddress] { constexpr auto RECV_DELAY_MS = 10; constexpr auto RECV_WAIT_MS = 2000; - auto broadcastAddress = "192.168.1.255"; - std::string msg = "Are you an OpenRCT2 server?"; auto udpSocket = CreateUdpSocket(); + log_verbose("Broadcasting %zu bytes to the LAN (%s)", msg.size(), broadcastAddress); auto len = udpSocket->SendData(broadcastAddress, NETWORK_LAN_BROADCAST_PORT, msg.data(), msg.size()); if (len != msg.size()) @@ -280,11 +280,42 @@ std::future> ServerList::FetchLocalServerListAsync( } platform_sleep(RECV_DELAY_MS); } - return entries; }); } +std::future> ServerList::FetchLocalServerListAsync() +{ + return std::async([&] { + // Get all possible LAN broadcast addresses + auto broadcastEndpoints = GetBroadcastAddresses(); + + // Spin off a fetch for each broadcast address + std::vector>> futures; + for (const auto& broadcastEndpoint : broadcastEndpoints) + { + auto f = FetchLocalServerListAsync(*broadcastEndpoint); + futures.push_back(std::move(f)); + } + + // Wait and merge all results + std::vector mergedEntries; + for (auto& f : futures) + { + try + { + auto entries = std::move(f.get()); + mergedEntries.insert(mergedEntries.begin(), entries.begin(), entries.end()); + } + catch (...) + { + // Ignore any exceptions from a particular broadcast fetch + } + } + return mergedEntries; + }); +} + std::future> ServerList::FetchOnlineServerListAsync() { #ifdef DISABLE_HTTP diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index e6a147cd1b..c9b44a5746 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -18,6 +18,7 @@ #include struct json_t; +struct INetworkEndpoint; struct ServerListEntry { @@ -45,6 +46,7 @@ private: void Sort(); std::vector ReadFavourites(); bool WriteFavourites(const std::vector& entries); + std::future> FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint); public: ServerListEntry& GetServer(size_t index); diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp index 2f02c08219..3da7991c10 100644 --- a/src/openrct2/network/UdpSocket.cpp +++ b/src/openrct2/network/UdpSocket.cpp @@ -36,13 +36,15 @@ #endif #define FLAG_NO_PIPE 0 #else - #include #include - #include - #include - #include - #include + #include #include + #include + #include + #include + #include + #include + #include #include "../common.h" using SOCKET = int32_t; #define SOCKET_ERROR -1 @@ -116,7 +118,7 @@ public: } } - std::string GetHostname() override + std::string GetHostname() const override { char hostname[256]; int res = getnameinfo(&_address, _addressLen, hostname, sizeof(hostname), nullptr, 0, NI_NUMERICHOST); @@ -395,4 +397,99 @@ std::unique_ptr CreateUdpSocket() return std::make_unique(); } +# ifdef _WIN32 +std::vector GetNetworkInterfaces() +{ + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + { + printf("socket returned -1\n"); + return {}; + } + + DWORD len = 0; + size_t capacity = 2; + std::vector interfaces; + for (;;) + { + interfaces.resize(capacity); + if (WSAIoctl( + sock, SIO_GET_INTERFACE_LIST, nullptr, 0, interfaces.data(), capacity * sizeof(INTERFACE_INFO), &len, nullptr, + nullptr) + == 0) + { + break; + } + if (WSAGetLastError() != WSAEFAULT) + { + closesocket(sock); + return {}; + } + capacity *= 2; + } + interfaces.resize(len / sizeof(INTERFACE_INFO)); + interfaces.shrink_to_fit(); + return interfaces; +} +# endif + +std::vector> GetBroadcastAddresses() +{ + std::vector> baddresses; +# ifdef _WIN32 + auto interfaces = GetNetworkInterfaces(); + for (const auto& ifo : interfaces) + { + if (ifo.iiFlags & IFF_LOOPBACK) + continue; + if (!(ifo.iiFlags & IFF_BROADCAST)) + continue; + + // iiBroadcast is unusable, because it always seems to be set to 255.255.255.255. + sockaddr_storage address{}; + memcpy(&address, &ifo.iiAddress.Address, sizeof(sockaddr)); + ((sockaddr_in*)&address)->sin_addr.s_addr = ifo.iiAddress.AddressIn.sin_addr.s_addr + | ~ifo.iiNetmask.AddressIn.sin_addr.s_addr; + baddresses.push_back(std::make_unique(address, sizeof(sockaddr))); + } +# else + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + { + return baddresses; + } + + char buf[4 * 1024]{}; + ifconf ifconfx{}; + ifconfx.ifc_len = sizeof(buf); + ifconfx.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifconfx) == -1) + { + close(sock); + return baddresses; + } + + const char* buf_end = buf + ifconfx.ifc_len; + for (const char* p = buf; p < buf_end;) + { + auto req = (const ifreq*)p; + if (req->ifr_addr.sa_family == AF_INET) + { + ifreq r; + strcpy(r.ifr_name, req->ifr_name); + if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 && (r.ifr_flags & IFF_BROADCAST) && ioctl(sock, SIOCGIFBRDADDR, &r) != -1) + { + baddresses.push_back(std::make_unique(&r.ifr_broadaddr, sizeof(sockaddr))); + } + } + p += sizeof(ifreq); +# if defined(AF_LINK) && !defined(SUNOS) + p += req->ifr_addr.sa_len - sizeof(struct sockaddr); +# endif + } + close(sock); +# endif + return baddresses; +} + #endif diff --git a/src/openrct2/network/UdpSocket.h b/src/openrct2/network/UdpSocket.h index a2523e3719..35df2ee370 100644 --- a/src/openrct2/network/UdpSocket.h +++ b/src/openrct2/network/UdpSocket.h @@ -13,6 +13,7 @@ #include #include +#include enum SOCKET_STATUS { @@ -40,7 +41,7 @@ interface INetworkEndpoint { } - virtual std::string GetHostname() abstract; + virtual std::string GetHostname() const abstract; }; /** @@ -69,3 +70,4 @@ public: }; std::unique_ptr CreateUdpSocket(); +std::vector> GetBroadcastAddresses(); From 6a4791e39e42540533a99706834d45685ddac3c5 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 16:31:50 +0000 Subject: [PATCH 347/506] Only reply to broadcasts with correct message --- src/openrct2/network/NetworkServerAdvertiser.cpp | 8 ++++---- src/openrct2/network/ServerList.cpp | 2 +- src/openrct2/network/network.h | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index e593d0db1e..fbc61f844c 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -102,11 +102,11 @@ private: } else { - char buffer[256]; - size_t recievedBytes; + char buffer[256]{}; + size_t recievedBytes{}; std::unique_ptr endpoint; - auto p = _lanListener->ReceiveData(buffer, sizeof(buffer), &recievedBytes, &endpoint); - if (p == NETWORK_READPACKET_SUCCESS) + auto p = _lanListener->ReceiveData(buffer, sizeof(buffer) - 1, &recievedBytes, &endpoint); + if (p == NETWORK_READPACKET_SUCCESS && String::Equals(buffer, NETWORK_LAN_BROADCAST_MSG)) { std::string sender = endpoint->GetHostname(); log_verbose("Received %zu bytes from %s on LAN broadcast port", recievedBytes, sender.c_str()); diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index edcaeb01e4..49b8b1243f 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -240,7 +240,7 @@ std::future> ServerList::FetchLocalServerListAsync( constexpr auto RECV_DELAY_MS = 10; constexpr auto RECV_WAIT_MS = 2000; - std::string msg = "Are you an OpenRCT2 server?"; + std::string_view msg = NETWORK_LAN_BROADCAST_MSG; auto udpSocket = CreateUdpSocket(); log_verbose("Broadcasting %zu bytes to the LAN (%s)", msg.size(), broadcastAddress); diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 0859cd4c42..b57dd058cc 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -11,6 +11,7 @@ #define NETWORK_DEFAULT_PORT 11753 #define NETWORK_LAN_BROADCAST_PORT 11754 +#define NETWORK_LAN_BROADCAST_MSG "openrct2.server.query" #define MAX_SERVER_DESCRIPTION_LENGTH 256 #include "../common.h" From 131a6dad3441e38158d69075eefb933fa19b3032 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 16:36:10 +0000 Subject: [PATCH 348/506] Update changelog --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 73674304cb..69033cec49 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Feature: [#2339] Find local servers automatically when fetching servers. - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. - Feature: [#8481] Multi-threaded rendering. From 20f52a8cbe685fbe3d7c00bfa435bcef9c4f59c9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 May 2019 16:54:16 +0000 Subject: [PATCH 349/506] Refactor TcpSocket and UdpSocket --- src/openrct2-ui/windows/ServerList.cpp | 1 - src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkConnection.cpp | 2 +- src/openrct2/network/NetworkConnection.h | 2 +- .../network/NetworkServerAdvertiser.cpp | 2 +- src/openrct2/network/ServerList.cpp | 2 +- .../network/{TcpSocket.cpp => Socket.cpp} | 472 +++++++++++++++-- .../network/{UdpSocket.h => Socket.h} | 37 ++ src/openrct2/network/TcpSocket.h | 71 --- src/openrct2/network/UdpSocket.cpp | 495 ------------------ 10 files changed, 468 insertions(+), 618 deletions(-) rename src/openrct2/network/{TcpSocket.cpp => Socket.cpp} (57%) rename src/openrct2/network/{UdpSocket.h => Socket.h} (64%) delete mode 100644 src/openrct2/network/TcpSocket.h delete mode 100644 src/openrct2/network/UdpSocket.cpp diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index f10826ab62..7976f4bac3 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 39e24cfaac..1e64fe8f11 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -75,7 +75,7 @@ static constexpr uint32_t CHUNK_SIZE = 1024 * 63; # include "NetworkPlayer.h" # include "NetworkServerAdvertiser.h" # include "NetworkUser.h" -# include "TcpSocket.h" +# include "Socket.h" # include # include diff --git a/src/openrct2/network/NetworkConnection.cpp b/src/openrct2/network/NetworkConnection.cpp index ff090665f9..2f8c14725d 100644 --- a/src/openrct2/network/NetworkConnection.cpp +++ b/src/openrct2/network/NetworkConnection.cpp @@ -14,7 +14,7 @@ # include "../core/String.hpp" # include "../localisation/Localisation.h" # include "../platform/platform.h" -# include "TcpSocket.h" +# include "Socket.h" # include "network.h" constexpr size_t NETWORK_DISCONNECT_REASON_BUFFER_SIZE = 256; diff --git a/src/openrct2/network/NetworkConnection.h b/src/openrct2/network/NetworkConnection.h index def4a85304..2872ac6b6f 100644 --- a/src/openrct2/network/NetworkConnection.h +++ b/src/openrct2/network/NetworkConnection.h @@ -14,7 +14,7 @@ # include "NetworkKey.h" # include "NetworkPacket.h" # include "NetworkTypes.h" -# include "TcpSocket.h" +# include "Socket.h" # include # include diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index fbc61f844c..6e5504d8c8 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -24,7 +24,7 @@ # include "../world/Map.h" # include "../world/Park.h" # include "Http.h" -# include "UdpSocket.h" +# include "Socket.h" # include "network.h" # include diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 49b8b1243f..cf2dd67161 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -19,7 +19,7 @@ #include "../core/String.hpp" #include "../network/Http.h" #include "../platform/platform.h" -#include "UdpSocket.h" +#include "Socket.h" #include "network.h" #include diff --git a/src/openrct2/network/TcpSocket.cpp b/src/openrct2/network/Socket.cpp similarity index 57% rename from src/openrct2/network/TcpSocket.cpp rename to src/openrct2/network/Socket.cpp index 51bdc33ff8..fe93b295ea 100644 --- a/src/openrct2/network/TcpSocket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -36,13 +36,15 @@ #endif #define FLAG_NO_PIPE 0 #else - #include #include - #include - #include - #include - #include + #include #include + #include + #include + #include + #include + #include + #include #include "../common.h" using SOCKET = int32_t; #define SOCKET_ERROR -1 @@ -58,7 +60,7 @@ #endif // _WIN32 // clang-format on -# include "TcpSocket.h" +# include "Socket.h" constexpr auto CONNECT_TIMEOUT = std::chrono::milliseconds(3000); @@ -66,8 +68,6 @@ constexpr auto CONNECT_TIMEOUT = std::chrono::milliseconds(3000); static bool _wsaInitialised = false; # endif -class TcpSocket; - class SocketException : public std::runtime_error { public: @@ -77,7 +77,123 @@ public: } }; -class TcpSocket final : public ITcpSocket +class NetworkEndpoint final : public INetworkEndpoint +{ +private: + sockaddr _address{}; + socklen_t _addressLen{}; + +public: + NetworkEndpoint() + { + } + + NetworkEndpoint(const sockaddr* address, socklen_t addressLen) + { + std::memcpy(&_address, address, addressLen); + _addressLen = addressLen; + } + + const sockaddr& GetAddress() const + { + return _address; + } + + socklen_t GetAddressLen() const + { + return _addressLen; + } + + int32_t GetPort() const + { + if (_address.sa_family == AF_INET) + { + return ((sockaddr_in*)&_address)->sin_port; + } + else + { + return ((sockaddr_in6*)&_address)->sin6_port; + } + } + + std::string GetHostname() const override + { + char hostname[256]; + int res = getnameinfo(&_address, _addressLen, hostname, sizeof(hostname), nullptr, 0, NI_NUMERICHOST); + if (res == 0) + { + return hostname; + } + return {}; + } +}; + +class Socket +{ +protected: + static bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, socklen_t* ss_len) + { + return ResolveAddress(AF_UNSPEC, address, port, ss, ss_len); + } + + static bool ResolveAddressIPv4(const std::string& address, uint16_t port, sockaddr_storage* ss, socklen_t* ss_len) + { + return ResolveAddress(AF_INET, address, port, ss, ss_len); + } + + static bool SetNonBlocking(SOCKET socket, bool on) + { +# ifdef _WIN32 + u_long nonBlocking = on; + return ioctlsocket(socket, FIONBIO, &nonBlocking) == 0; +# else + int32_t flags = fcntl(socket, F_GETFL, 0); + return fcntl(socket, F_SETFL, on ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0; +# endif + } + + static bool SetOption(SOCKET socket, int32_t a, int32_t b, bool value) + { + int32_t ivalue = value ? 1 : 0; + return setsockopt(socket, a, b, (const char*)&ivalue, sizeof(ivalue)) == 0; + } + +private: + static bool ResolveAddress( + int32_t family, const std::string& address, uint16_t port, sockaddr_storage* ss, socklen_t* ss_len) + { + std::string serviceName = std::to_string(port); + + addrinfo hints = {}; + hints.ai_family = family; + if (address.empty()) + { + hints.ai_flags = AI_PASSIVE; + } + + addrinfo* result = nullptr; + int errorcode = getaddrinfo(address.empty() ? nullptr : address.c_str(), serviceName.c_str(), &hints, &result); + if (errorcode != 0) + { + log_error("Resolving address failed: Code %d.", errorcode); + log_error("Resolution error message: %s.", gai_strerror(errorcode)); + return false; + } + if (result == nullptr) + { + return false; + } + else + { + std::memcpy(ss, result->ai_addr, result->ai_addrlen); + *ss_len = (socklen_t)result->ai_addrlen; + freeaddrinfo(result); + return true; + } + } +}; + +class TcpSocket final : public ITcpSocket, protected Socket { private: SOCKET_STATUS _status = SOCKET_STATUS_CLOSED; @@ -123,7 +239,7 @@ public: } sockaddr_storage ss{}; - int32_t ss_len; + socklen_t ss_len; if (!ResolveAddress(address, port, &ss, &ss_len)) { throw SocketException("Unable to resolve address."); @@ -209,7 +325,7 @@ public: int32_t rc = getnameinfo( (struct sockaddr*)&client_addr, client_len, hostName, sizeof(hostName), nullptr, 0, NI_NUMERICHOST | NI_NUMERICSERV); - SetTCPNoDelay(socket, true); + SetOption(socket, IPPROTO_TCP, TCP_NODELAY, true); if (rc == 0) { tcpSocket = std::unique_ptr(new TcpSocket(socket, hostName)); @@ -236,7 +352,7 @@ public: _status = SOCKET_STATUS_RESOLVING; sockaddr_storage ss{}; - int32_t ss_len; + socklen_t ss_len; if (!ResolveAddress(address, port, &ss, &ss_len)) { throw SocketException("Unable to resolve address."); @@ -249,7 +365,7 @@ public: throw SocketException("Unable to create socket."); } - SetTCPNoDelay(_socket, true); + SetOption(_socket, IPPROTO_TCP, TCP_NODELAY, true); if (!SetNonBlocking(_socket, true)) { throw SocketException("Failed to set non-blocking mode."); @@ -446,61 +562,221 @@ private: } _status = SOCKET_STATUS_CLOSED; } +}; - bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, int32_t* ss_len) +class UdpSocket final : public IUdpSocket, protected Socket +{ +private: + SOCKET_STATUS _status = SOCKET_STATUS_CLOSED; + uint16_t _listeningPort = 0; + SOCKET _socket = INVALID_SOCKET; + NetworkEndpoint _endpoint; + + std::string _hostName; + std::string _error; + +public: + UdpSocket() = default; + + ~UdpSocket() override { - std::string serviceName = std::to_string(port); + CloseSocket(); + } - addrinfo hints = {}; - hints.ai_family = AF_UNSPEC; - if (address.empty()) + SOCKET_STATUS GetStatus() override + { + return _status; + } + + const char* GetError() override + { + return _error.empty() ? nullptr : _error.c_str(); + } + + void Listen(uint16_t port) override + { + Listen("", port); + } + + void Listen(const std::string& address, uint16_t port) override + { + if (_status != SOCKET_STATUS_CLOSED) { - hints.ai_flags = AI_PASSIVE; + throw std::runtime_error("Socket not closed."); } - addrinfo* result = nullptr; - int errorcode = getaddrinfo(address.empty() ? nullptr : address.c_str(), serviceName.c_str(), &hints, &result); - if (errorcode != 0) + sockaddr_storage ss{}; + socklen_t ss_len; + if (!ResolveAddressIPv4(address, port, &ss, &ss_len)) { - log_error("Resolving address failed: Code %d.", errorcode); - log_error("Resolution error message: %s.", gai_strerror(errorcode)); - return false; + throw SocketException("Unable to resolve address."); } - if (result == nullptr) + + // Create the listening socket + _socket = socket(ss.ss_family, SOCK_DGRAM, IPPROTO_UDP); + if (_socket == INVALID_SOCKET) { - return false; + throw SocketException("Unable to create socket."); + } + + // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections + if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) + { + log_error("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); + } + + if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) + { + log_error("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); + } + + // Enable send and receiving of broadcast messages + if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) + { + log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); + } + + try + { + // Bind to address:port and listen + if (bind(_socket, (sockaddr*)&ss, ss_len) != 0) + { + throw SocketException("Unable to bind to socket."); + } + + if (!SetNonBlocking(_socket, true)) + { + throw SocketException("Failed to set non-blocking mode."); + } + } + catch (const std::exception&) + { + CloseSocket(); + throw; + } + + _listeningPort = port; + _status = SOCKET_STATUS_LISTENING; + } + + size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) override + { + sockaddr_storage ss{}; + socklen_t ss_len; + if (!ResolveAddressIPv4(address, port, &ss, &ss_len)) + { + throw SocketException("Unable to resolve address."); + } + NetworkEndpoint endpoint((const sockaddr*)&ss, ss_len); + return SendData(endpoint, buffer, size); + } + + size_t SendData(const INetworkEndpoint& destination, const void* buffer, size_t size) override + { + if (_socket == INVALID_SOCKET) + { + _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (_socket == INVALID_SOCKET) + { + throw SocketException("Unable to create socket."); + } + + // Enable send and receiving of broadcast messages + if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) + { + log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); + } + + if (!SetNonBlocking(_socket, true)) + { + throw SocketException("Failed to set non-blocking mode."); + } + } + + const auto& dest = dynamic_cast(&destination); + if (dest == nullptr) + { + throw std::invalid_argument("destination is not compatible."); + } + auto ss = &dest->GetAddress(); + auto ss_len = dest->GetAddressLen(); + + if (_status != SOCKET_STATUS_LISTENING) + { + _endpoint = *dest; + } + + size_t totalSent = 0; + do + { + const char* bufferStart = (const char*)buffer + totalSent; + size_t remainingSize = size - totalSent; + int32_t sentBytes = sendto(_socket, bufferStart, (int32_t)remainingSize, FLAG_NO_PIPE, (const sockaddr*)ss, ss_len); + if (sentBytes == SOCKET_ERROR) + { + return totalSent; + } + totalSent += sentBytes; + } while (totalSent < size); + return totalSent; + } + + NETWORK_READPACKET ReceiveData( + void* buffer, size_t size, size_t* sizeReceived, std::unique_ptr* sender) override + { + sockaddr_in senderAddr{}; + socklen_t senderAddrLen = sizeof(sockaddr_in); + if (_status != SOCKET_STATUS_LISTENING) + { + senderAddrLen = _endpoint.GetAddressLen(); + std::memcpy(&senderAddr, &_endpoint.GetAddress(), senderAddrLen); + } + auto readBytes = recvfrom(_socket, (char*)buffer, (int32_t)size, 0, (sockaddr*)&senderAddr, &senderAddrLen); + if (readBytes <= 0) + { + *sizeReceived = 0; + return NETWORK_READPACKET_NO_DATA; } else { - std::memcpy(ss, result->ai_addr, result->ai_addrlen); - *ss_len = (int32_t)result->ai_addrlen; - freeaddrinfo(result); - return true; + *sizeReceived = readBytes; + if (sender != nullptr) + { + *sender = std::make_unique((sockaddr*)&senderAddr, senderAddrLen); + } + return NETWORK_READPACKET_SUCCESS; } } - static bool SetNonBlocking(SOCKET socket, bool on) + void Close() override { -# ifdef _WIN32 - u_long nonBlocking = on; - return ioctlsocket(socket, FIONBIO, &nonBlocking) == 0; -# else - int32_t flags = fcntl(socket, F_GETFL, 0); - return fcntl(socket, F_SETFL, on ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0; -# endif + CloseSocket(); } - static bool SetTCPNoDelay(SOCKET socket, bool enabled) + const char* GetHostName() const override { - return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&enabled, sizeof(enabled)) == 0; + return _hostName.empty() ? nullptr : _hostName.c_str(); + } + +private: + explicit UdpSocket(SOCKET socket, const std::string& hostName) + { + _socket = socket; + _hostName = hostName; + _status = SOCKET_STATUS_CONNECTED; + } + + void CloseSocket() + { + if (_socket != INVALID_SOCKET) + { + closesocket(_socket); + _socket = INVALID_SOCKET; + } + _status = SOCKET_STATUS_CLOSED; } }; -std::unique_ptr CreateTcpSocket() -{ - return std::make_unique(); -} - bool InitialiseWSA() { # ifdef _WIN32 @@ -532,6 +808,110 @@ void DisposeWSA() # endif } +std::unique_ptr CreateTcpSocket() +{ + return std::make_unique(); +} + +std::unique_ptr CreateUdpSocket() +{ + return std::make_unique(); +} + +# ifdef _WIN32 +std::vector GetNetworkInterfaces() +{ + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + { + return {}; + } + + DWORD len = 0; + size_t capacity = 2; + std::vector interfaces; + for (;;) + { + interfaces.resize(capacity); + if (WSAIoctl( + sock, SIO_GET_INTERFACE_LIST, nullptr, 0, interfaces.data(), capacity * sizeof(INTERFACE_INFO), &len, nullptr, + nullptr) + == 0) + { + break; + } + if (WSAGetLastError() != WSAEFAULT) + { + closesocket(sock); + return {}; + } + capacity *= 2; + } + interfaces.resize(len / sizeof(INTERFACE_INFO)); + interfaces.shrink_to_fit(); + return interfaces; +} +# endif + +std::vector> GetBroadcastAddresses() +{ + std::vector> baddresses; +# ifdef _WIN32 + auto interfaces = GetNetworkInterfaces(); + for (const auto& ifo : interfaces) + { + if (ifo.iiFlags & IFF_LOOPBACK) + continue; + if (!(ifo.iiFlags & IFF_BROADCAST)) + continue; + + // iiBroadcast is unusable, because it always seems to be set to 255.255.255.255. + sockaddr_storage address{}; + memcpy(&address, &ifo.iiAddress.Address, sizeof(sockaddr)); + ((sockaddr_in*)&address)->sin_addr.s_addr = ifo.iiAddress.AddressIn.sin_addr.s_addr + | ~ifo.iiNetmask.AddressIn.sin_addr.s_addr; + baddresses.push_back(std::make_unique(address, sizeof(sockaddr))); + } +# else + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + { + return baddresses; + } + + char buf[4 * 1024]{}; + ifconf ifconfx{}; + ifconfx.ifc_len = sizeof(buf); + ifconfx.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifconfx) == -1) + { + close(sock); + return baddresses; + } + + const char* buf_end = buf + ifconfx.ifc_len; + for (const char* p = buf; p < buf_end;) + { + auto req = (const ifreq*)p; + if (req->ifr_addr.sa_family == AF_INET) + { + ifreq r; + strcpy(r.ifr_name, req->ifr_name); + if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 && (r.ifr_flags & IFF_BROADCAST) && ioctl(sock, SIOCGIFBRDADDR, &r) != -1) + { + baddresses.push_back(std::make_unique(&r.ifr_broadaddr, sizeof(sockaddr))); + } + } + p += sizeof(ifreq); +# if defined(AF_LINK) && !defined(SUNOS) + p += req->ifr_addr.sa_len - sizeof(struct sockaddr); +# endif + } + close(sock); +# endif + return baddresses; +} + namespace Convert { uint16_t HostToNetwork(uint16_t value) diff --git a/src/openrct2/network/UdpSocket.h b/src/openrct2/network/Socket.h similarity index 64% rename from src/openrct2/network/UdpSocket.h rename to src/openrct2/network/Socket.h index 35df2ee370..178388aa89 100644 --- a/src/openrct2/network/UdpSocket.h +++ b/src/openrct2/network/Socket.h @@ -44,6 +44,34 @@ interface INetworkEndpoint virtual std::string GetHostname() const abstract; }; +/** + * Represents a TCP socket / connection or listener. + */ +interface ITcpSocket +{ +public: + virtual ~ITcpSocket() + { + } + + virtual SOCKET_STATUS GetStatus() abstract; + virtual const char* GetError() abstract; + virtual const char* GetHostName() const abstract; + + virtual void Listen(uint16_t port) abstract; + virtual void Listen(const std::string& address, uint16_t port) abstract; + virtual std::unique_ptr Accept() abstract; + + virtual void Connect(const std::string& address, uint16_t port) abstract; + virtual void ConnectAsync(const std::string& address, uint16_t port) abstract; + + virtual size_t SendData(const void* buffer, size_t size) abstract; + virtual NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) abstract; + + virtual void Disconnect() abstract; + virtual void Close() abstract; +}; + /** * Represents a UDP socket / listener. */ @@ -69,5 +97,14 @@ public: virtual void Close() abstract; }; +bool InitialiseWSA(); +void DisposeWSA(); +std::unique_ptr CreateTcpSocket(); std::unique_ptr CreateUdpSocket(); std::vector> GetBroadcastAddresses(); + +namespace Convert +{ + uint16_t HostToNetwork(uint16_t value); + uint16_t NetworkToHost(uint16_t value); +} // namespace Convert diff --git a/src/openrct2/network/TcpSocket.h b/src/openrct2/network/TcpSocket.h deleted file mode 100644 index 1e6186f20a..0000000000 --- a/src/openrct2/network/TcpSocket.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** - * 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 "../common.h" - -#include -#include - -enum SOCKET_STATUS -{ - SOCKET_STATUS_CLOSED, - SOCKET_STATUS_RESOLVING, - SOCKET_STATUS_CONNECTING, - SOCKET_STATUS_CONNECTED, - SOCKET_STATUS_LISTENING, -}; - -enum NETWORK_READPACKET -{ - NETWORK_READPACKET_SUCCESS, - NETWORK_READPACKET_NO_DATA, - NETWORK_READPACKET_MORE_DATA, - NETWORK_READPACKET_DISCONNECTED -}; - -/** - * Represents a TCP socket / connection or listener. - */ -interface ITcpSocket -{ -public: - virtual ~ITcpSocket() - { - } - - virtual SOCKET_STATUS GetStatus() abstract; - virtual const char* GetError() abstract; - virtual const char* GetHostName() const abstract; - - virtual void Listen(uint16_t port) abstract; - virtual void Listen(const std::string& address, uint16_t port) abstract; - virtual std::unique_ptr Accept() abstract; - - virtual void Connect(const std::string& address, uint16_t port) abstract; - virtual void ConnectAsync(const std::string& address, uint16_t port) abstract; - - virtual size_t SendData(const void* buffer, size_t size) abstract; - virtual NETWORK_READPACKET ReceiveData(void* buffer, size_t size, size_t* sizeReceived) abstract; - - virtual void Disconnect() abstract; - virtual void Close() abstract; -}; - -std::unique_ptr CreateTcpSocket(); - -bool InitialiseWSA(); -void DisposeWSA(); - -namespace Convert -{ - uint16_t HostToNetwork(uint16_t value); - uint16_t NetworkToHost(uint16_t value); -} // namespace Convert diff --git a/src/openrct2/network/UdpSocket.cpp b/src/openrct2/network/UdpSocket.cpp deleted file mode 100644 index 3da7991c10..0000000000 --- a/src/openrct2/network/UdpSocket.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/***************************************************************************** - * 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. - *****************************************************************************/ - -#ifndef DISABLE_NETWORK - -# include -# include -# include -# include -# include -# include - -// clang-format off -// MSVC: include here otherwise PI gets defined twice -#include - -#ifdef _WIN32 - // winsock2 must be included before windows.h - #include - #include - - #define LAST_SOCKET_ERROR() WSAGetLastError() - #undef EWOULDBLOCK - #define EWOULDBLOCK WSAEWOULDBLOCK - #ifndef SHUT_RD - #define SHUT_RD SD_RECEIVE - #endif - #ifndef SHUT_RDWR - #define SHUT_RDWR SD_BOTH - #endif - #define FLAG_NO_PIPE 0 -#else - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include "../common.h" - using SOCKET = int32_t; - #define SOCKET_ERROR -1 - #define INVALID_SOCKET -1 - #define LAST_SOCKET_ERROR() errno - #define closesocket close - #define ioctlsocket ioctl - #if defined(__linux__) - #define FLAG_NO_PIPE MSG_NOSIGNAL - #else - #define FLAG_NO_PIPE 0 - #endif // defined(__linux__) -#endif // _WIN32 -// clang-format on - -# include "UdpSocket.h" - -constexpr auto CONNECT_TIMEOUT = std::chrono::milliseconds(3000); - -# ifdef _WIN32 -static bool _wsaInitialised = false; -# endif - -class UdpSocket; - -class SocketException : public std::runtime_error -{ -public: - explicit SocketException(const std::string& message) - : std::runtime_error(message) - { - } -}; - -class NetworkEndpoint final : public INetworkEndpoint -{ -private: - sockaddr _address{}; - socklen_t _addressLen{}; - -public: - NetworkEndpoint() - { - } - - NetworkEndpoint(const sockaddr* address, socklen_t addressLen) - { - std::memcpy(&_address, address, addressLen); - _addressLen = addressLen; - } - - const sockaddr& GetAddress() const - { - return _address; - } - - socklen_t GetAddressLen() const - { - return _addressLen; - } - - int32_t GetPort() const - { - if (_address.sa_family == AF_INET) - { - return ((sockaddr_in*)&_address)->sin_port; - } - else - { - return ((sockaddr_in6*)&_address)->sin6_port; - } - } - - std::string GetHostname() const override - { - char hostname[256]; - int res = getnameinfo(&_address, _addressLen, hostname, sizeof(hostname), nullptr, 0, NI_NUMERICHOST); - if (res == 0) - { - return hostname; - } - return {}; - } -}; - -class UdpSocket final : public IUdpSocket -{ -private: - SOCKET_STATUS _status = SOCKET_STATUS_CLOSED; - uint16_t _listeningPort = 0; - SOCKET _socket = INVALID_SOCKET; - NetworkEndpoint _endpoint; - - std::string _hostName; - std::string _error; - -public: - UdpSocket() = default; - - ~UdpSocket() override - { - CloseSocket(); - } - - SOCKET_STATUS GetStatus() override - { - return _status; - } - - const char* GetError() override - { - return _error.empty() ? nullptr : _error.c_str(); - } - - void Listen(uint16_t port) override - { - Listen("", port); - } - - void Listen(const std::string& address, uint16_t port) override - { - if (_status != SOCKET_STATUS_CLOSED) - { - throw std::runtime_error("Socket not closed."); - } - - sockaddr_storage ss{}; - socklen_t ss_len; - if (!ResolveAddress(address, port, &ss, &ss_len)) - { - throw SocketException("Unable to resolve address."); - } - - // Create the listening socket - _socket = socket(ss.ss_family, SOCK_DGRAM, IPPROTO_UDP); - if (_socket == INVALID_SOCKET) - { - throw SocketException("Unable to create socket."); - } - - // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections - if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) - { - log_error("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); - } - - if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) - { - log_error("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); - } - - // Enable send and receiving of broadcast messages - if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) - { - log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); - } - - try - { - // Bind to address:port and listen - if (bind(_socket, (sockaddr*)&ss, ss_len) != 0) - { - throw SocketException("Unable to bind to socket."); - } - - if (!SetNonBlocking(_socket, true)) - { - throw SocketException("Failed to set non-blocking mode."); - } - } - catch (const std::exception&) - { - CloseSocket(); - throw; - } - - _listeningPort = port; - _status = SOCKET_STATUS_LISTENING; - } - - size_t SendData(const std::string& address, uint16_t port, const void* buffer, size_t size) override - { - sockaddr_storage ss{}; - socklen_t ss_len; - if (!ResolveAddress(address, port, &ss, &ss_len)) - { - throw SocketException("Unable to resolve address."); - } - NetworkEndpoint endpoint((const sockaddr*)&ss, ss_len); - return SendData(endpoint, buffer, size); - } - - size_t SendData(const INetworkEndpoint& destination, const void* buffer, size_t size) override - { - if (_socket == INVALID_SOCKET) - { - _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (_socket == INVALID_SOCKET) - { - throw SocketException("Unable to create socket."); - } - - // Enable send and receiving of broadcast messages - if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) - { - log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); - } - - if (!SetNonBlocking(_socket, true)) - { - throw SocketException("Failed to set non-blocking mode."); - } - } - - const auto& dest = dynamic_cast(&destination); - if (dest == nullptr) - { - throw std::invalid_argument("destination is not compatible."); - } - auto ss = &dest->GetAddress(); - auto ss_len = dest->GetAddressLen(); - - if (_status != SOCKET_STATUS_LISTENING) - { - _endpoint = *dest; - } - - size_t totalSent = 0; - do - { - const char* bufferStart = (const char*)buffer + totalSent; - size_t remainingSize = size - totalSent; - int32_t sentBytes = sendto(_socket, bufferStart, (int32_t)remainingSize, FLAG_NO_PIPE, (const sockaddr*)ss, ss_len); - if (sentBytes == SOCKET_ERROR) - { - return totalSent; - } - totalSent += sentBytes; - } while (totalSent < size); - return totalSent; - } - - NETWORK_READPACKET ReceiveData( - void* buffer, size_t size, size_t* sizeReceived, std::unique_ptr* sender) override - { - sockaddr_in senderAddr{}; - socklen_t senderAddrLen = sizeof(sockaddr_in); - if (_status != SOCKET_STATUS_LISTENING) - { - senderAddrLen = _endpoint.GetAddressLen(); - std::memcpy(&senderAddr, &_endpoint.GetAddress(), senderAddrLen); - } - auto readBytes = recvfrom(_socket, (char*)buffer, (int32_t)size, 0, (sockaddr*)&senderAddr, &senderAddrLen); - if (readBytes <= 0) - { - *sizeReceived = 0; - return NETWORK_READPACKET_NO_DATA; - } - else - { - *sizeReceived = readBytes; - if (sender != nullptr) - { - *sender = std::make_unique((sockaddr*)&senderAddr, senderAddrLen); - } - return NETWORK_READPACKET_SUCCESS; - } - } - - void Close() override - { - CloseSocket(); - } - - const char* GetHostName() const override - { - return _hostName.empty() ? nullptr : _hostName.c_str(); - } - -private: - explicit UdpSocket(SOCKET socket, const std::string& hostName) - { - _socket = socket; - _hostName = hostName; - _status = SOCKET_STATUS_CONNECTED; - } - - void CloseSocket() - { - if (_socket != INVALID_SOCKET) - { - closesocket(_socket); - _socket = INVALID_SOCKET; - } - _status = SOCKET_STATUS_CLOSED; - } - - bool ResolveAddress(const std::string& address, uint16_t port, sockaddr_storage* ss, socklen_t* ss_len) - { - std::string serviceName = std::to_string(port); - - addrinfo hints = {}; - hints.ai_family = AF_INET; - if (address.empty()) - { - hints.ai_flags = AI_PASSIVE; - } - - addrinfo* result = nullptr; - int errorcode = getaddrinfo(address.empty() ? nullptr : address.c_str(), serviceName.c_str(), &hints, &result); - if (errorcode != 0) - { - log_error("Resolving address failed: Code %d.", errorcode); - log_error("Resolution error message: %s.", gai_strerror(errorcode)); - return false; - } - if (result == nullptr) - { - return false; - } - else - { - std::memcpy(ss, result->ai_addr, result->ai_addrlen); - *ss_len = (socklen_t)result->ai_addrlen; - freeaddrinfo(result); - return true; - } - } - - static bool SetNonBlocking(SOCKET socket, bool on) - { -# ifdef _WIN32 - u_long nonBlocking = on; - return ioctlsocket(socket, FIONBIO, &nonBlocking) == 0; -# else - int32_t flags = fcntl(socket, F_GETFL, 0); - return fcntl(socket, F_SETFL, on ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0; -# endif - } - - static bool SetOption(SOCKET socket, int32_t a, int32_t b, bool value) - { - int32_t ivalue = value ? 1 : 0; - return setsockopt(socket, a, b, (const char*)&ivalue, sizeof(ivalue)) == 0; - } -}; - -std::unique_ptr CreateUdpSocket() -{ - return std::make_unique(); -} - -# ifdef _WIN32 -std::vector GetNetworkInterfaces() -{ - int sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == -1) - { - printf("socket returned -1\n"); - return {}; - } - - DWORD len = 0; - size_t capacity = 2; - std::vector interfaces; - for (;;) - { - interfaces.resize(capacity); - if (WSAIoctl( - sock, SIO_GET_INTERFACE_LIST, nullptr, 0, interfaces.data(), capacity * sizeof(INTERFACE_INFO), &len, nullptr, - nullptr) - == 0) - { - break; - } - if (WSAGetLastError() != WSAEFAULT) - { - closesocket(sock); - return {}; - } - capacity *= 2; - } - interfaces.resize(len / sizeof(INTERFACE_INFO)); - interfaces.shrink_to_fit(); - return interfaces; -} -# endif - -std::vector> GetBroadcastAddresses() -{ - std::vector> baddresses; -# ifdef _WIN32 - auto interfaces = GetNetworkInterfaces(); - for (const auto& ifo : interfaces) - { - if (ifo.iiFlags & IFF_LOOPBACK) - continue; - if (!(ifo.iiFlags & IFF_BROADCAST)) - continue; - - // iiBroadcast is unusable, because it always seems to be set to 255.255.255.255. - sockaddr_storage address{}; - memcpy(&address, &ifo.iiAddress.Address, sizeof(sockaddr)); - ((sockaddr_in*)&address)->sin_addr.s_addr = ifo.iiAddress.AddressIn.sin_addr.s_addr - | ~ifo.iiNetmask.AddressIn.sin_addr.s_addr; - baddresses.push_back(std::make_unique(address, sizeof(sockaddr))); - } -# else - int sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == -1) - { - return baddresses; - } - - char buf[4 * 1024]{}; - ifconf ifconfx{}; - ifconfx.ifc_len = sizeof(buf); - ifconfx.ifc_buf = buf; - if (ioctl(sock, SIOCGIFCONF, &ifconfx) == -1) - { - close(sock); - return baddresses; - } - - const char* buf_end = buf + ifconfx.ifc_len; - for (const char* p = buf; p < buf_end;) - { - auto req = (const ifreq*)p; - if (req->ifr_addr.sa_family == AF_INET) - { - ifreq r; - strcpy(r.ifr_name, req->ifr_name); - if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 && (r.ifr_flags & IFF_BROADCAST) && ioctl(sock, SIOCGIFBRDADDR, &r) != -1) - { - baddresses.push_back(std::make_unique(&r.ifr_broadaddr, sizeof(sockaddr))); - } - } - p += sizeof(ifreq); -# if defined(AF_LINK) && !defined(SUNOS) - p += req->ifr_addr.sa_len - sizeof(struct sockaddr); -# endif - } - close(sock); -# endif - return baddresses; -} - -#endif From 4b0f2bbceb7fb542a2894d48e2979fa8fc5562b9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 May 2019 11:19:35 +0000 Subject: [PATCH 350/506] Fix disable network / disable http builds --- src/openrct2-ui/WindowManager.cpp | 2 + src/openrct2-ui/windows/ServerList.cpp | 54 ++++++------- src/openrct2-ui/windows/ServerStart.cpp | 26 ++++--- src/openrct2-ui/windows/Window.h | 2 + .../network/NetworkServerAdvertiser.cpp | 78 +++++++++---------- src/openrct2/network/ServerList.cpp | 45 ++++++----- 6 files changed, 106 insertions(+), 101 deletions(-) diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 8c8e497466..d897f0f641 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -100,10 +100,12 @@ public: return window_save_prompt_open(); case WC_SCENERY: return window_scenery_open(); +#ifndef DISABLE_NETWORK case WC_SERVER_LIST: return window_server_list_open(); case WC_SERVER_START: return window_server_start_open(); +#endif case WC_KEYBOARD_SHORTCUT_LIST: return window_shortcut_keys_open(); case WC_STAFF_LIST: diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 7976f4bac3..fa285efcb9 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -7,35 +7,33 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef DISABLE_NETWORK -#ifndef DISABLE_HTTP -using namespace OpenRCT2::Network; -#endif +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include -#define WWIDTH_MIN 500 -#define WHEIGHT_MIN 300 -#define WWIDTH_MAX 1200 -#define WHEIGHT_MAX 800 -#define ITEM_HEIGHT (3 + 9 + 3) +# define WWIDTH_MIN 500 +# define WHEIGHT_MIN 300 +# define WWIDTH_MAX 1200 +# define WHEIGHT_MAX 800 +# define ITEM_HEIGHT (3 + 9 + 3) static char _playerName[32 + 1]; static ServerList _serverList; @@ -613,3 +611,5 @@ static void server_list_fetch_servers_check(rct_window* w) } } } + +#endif diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index 5fc1d49cd0..631ea62f60 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -7,18 +7,20 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../interface/Theme.h" +#ifndef DISABLE_NETWORK -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +# include "../interface/Theme.h" + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include static char _port[7]; static char _name[65]; @@ -345,3 +347,5 @@ static void window_server_start_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string_left(dpi, STR_PASSWORD, nullptr, w->colours[1], w->x + 6, w->y + w->widgets[WIDX_PASSWORD_INPUT].top); gfx_draw_string_left(dpi, STR_MAX_PLAYERS, nullptr, w->colours[1], w->x + 6, w->y + w->widgets[WIDX_MAXPLAYERS].top); } + +#endif diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 8c8d770e81..76c45cb3f4 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -43,8 +43,10 @@ rct_window* window_news_open(); rct_window* window_news_options_open(); rct_window* window_options_open(); rct_window* window_save_prompt_open(); +#ifndef DISABLE_NETWORK rct_window* window_server_list_open(); rct_window* window_server_start_open(); +#endif rct_window* window_shortcut_change_open(int32_t selected_key); rct_window* window_shortcut_keys_open(); rct_window* window_staff_list_open(); diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 6e5504d8c8..bf9c921c51 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -32,10 +32,6 @@ # include # include -# ifndef DISABLE_HTTP - -using namespace OpenRCT2::Network; - enum MASTER_SERVER_STATUS { MASTER_SERVER_STATUS_OK = 200, @@ -52,7 +48,12 @@ class NetworkServerAdvertiser final : public INetworkServerAdvertiser private: uint16_t _port; + std::unique_ptr _lanListener; + uint32_t _lastListenTime{}; + ADVERTISE_STATUS _status = ADVERTISE_STATUS::UNREGISTERED; + +# ifndef DISABLE_HTTP uint32_t _lastAdvertiseTime = 0; uint32_t _lastHeartbeatTime = 0; @@ -64,16 +65,16 @@ private: // See https://github.com/OpenRCT2/OpenRCT2/issues/6277 and 4953 bool _forceIPv4 = false; - - std::unique_ptr _lanListener; - uint32_t _lastListenTime{}; +# endif public: explicit NetworkServerAdvertiser(uint16_t port) { _port = port; - _key = GenerateAdvertiseKey(); _lanListener = CreateUdpSocket(); +# ifndef DISABLE_HTTP + _key = GenerateAdvertiseKey(); +# endif } ADVERTISE_STATUS GetStatus() const override @@ -84,10 +85,12 @@ public: void Update() override { UpdateLAN(); +# ifndef DISABLE_HTTP if (gConfigNetwork.advertise) { UpdateWAN(); } +# endif } private: @@ -106,24 +109,34 @@ private: size_t recievedBytes{}; std::unique_ptr endpoint; auto p = _lanListener->ReceiveData(buffer, sizeof(buffer) - 1, &recievedBytes, &endpoint); - if (p == NETWORK_READPACKET_SUCCESS && String::Equals(buffer, NETWORK_LAN_BROADCAST_MSG)) + if (p == NETWORK_READPACKET_SUCCESS) { std::string sender = endpoint->GetHostname(); log_verbose("Received %zu bytes from %s on LAN broadcast port", recievedBytes, sender.c_str()); - - auto body = GetBroadcastJson(); - auto bodyDump = json_dumps(body, JSON_COMPACT); - size_t sendLen = strlen(bodyDump) + 1; - log_verbose("Sending %zu bytes back to %s", sendLen, sender.c_str()); - _lanListener->SendData(*endpoint, bodyDump, sendLen); - free(bodyDump); - json_decref(body); + if (String::Equals(buffer, NETWORK_LAN_BROADCAST_MSG)) + { + auto body = GetBroadcastJson(); + auto bodyDump = json_dumps(body, JSON_COMPACT); + size_t sendLen = strlen(bodyDump) + 1; + log_verbose("Sending %zu bytes back to %s", sendLen, sender.c_str()); + _lanListener->SendData(*endpoint, bodyDump, sendLen); + free(bodyDump); + json_decref(body); + } } } _lastListenTime = ticks; } } + json_t* GetBroadcastJson() + { + auto root = network_get_server_info_as_json(); + json_object_set(root, "port", json_integer(_port)); + return root; + } + +# ifndef DISABLE_HTTP void UpdateWAN() { switch (_status) @@ -148,6 +161,8 @@ private: void SendRegistration(bool forceIPv4) { + using namespace OpenRCT2::Network; + _lastAdvertiseTime = platform_get_ticks(); // Send the registration request @@ -181,6 +196,8 @@ private: void SendHeartbeat() { + using namespace OpenRCT2::Network; + Http::Request request; request.url = GetMasterServerUrl(); request.method = Http::Method::PUT; @@ -284,13 +301,6 @@ private: return root; } - json_t* GetBroadcastJson() - { - auto root = network_get_server_info_as_json(); - json_object_set(root, "port", json_integer(_port)); - return root; - } - static std::string GenerateAdvertiseKey() { // Generate a string of 16 random hex characters (64-integer key as a hex formatted string) @@ -316,6 +326,7 @@ private: } return result; } +# endif }; std::unique_ptr CreateServerAdvertiser(uint16_t port) @@ -323,23 +334,4 @@ std::unique_ptr CreateServerAdvertiser(uint16_t port) return std::make_unique(port); } -# else // DISABLE_HTTP - -class DummyNetworkServerAdvertiser final : public INetworkServerAdvertiser -{ -public: - virtual ADVERTISE_STATUS GetStatus() const override - { - return ADVERTISE_STATUS::DISABLED; - }; - virtual void Update() override{}; -}; - -std::unique_ptr CreateServerAdvertiser(uint16_t port) -{ - return std::make_unique(); -} - -# endif // DISABLE_HTTP - #endif // DISABLE_NETWORK diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index cf2dd67161..46f181ae3c 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -7,26 +7,27 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "ServerList.h" +#ifndef DISABLE_NETWORK -#include "../Context.h" -#include "../PlatformEnvironment.h" -#include "../config/Config.h" -#include "../core/FileStream.hpp" -#include "../core/Json.hpp" -#include "../core/Memory.hpp" -#include "../core/Path.hpp" -#include "../core/String.hpp" -#include "../network/Http.h" -#include "../platform/platform.h" -#include "Socket.h" -#include "network.h" +# include "ServerList.h" -#include -#include +# include "../Context.h" +# include "../PlatformEnvironment.h" +# include "../config/Config.h" +# include "../core/FileStream.hpp" +# include "../core/Json.hpp" +# include "../core/Memory.hpp" +# include "../core/Path.hpp" +# include "../core/String.hpp" +# include "../network/Http.h" +# include "../platform/platform.h" +# include "Socket.h" +# include "network.h" + +# include +# include using namespace OpenRCT2; -using namespace OpenRCT2::Network; int32_t ServerListEntry::CompareTo(const ServerListEntry& other) const { @@ -243,7 +244,7 @@ std::future> ServerList::FetchLocalServerListAsync( std::string_view msg = NETWORK_LAN_BROADCAST_MSG; auto udpSocket = CreateUdpSocket(); - log_verbose("Broadcasting %zu bytes to the LAN (%s)", msg.size(), broadcastAddress); + log_verbose("Broadcasting %zu bytes to the LAN (%s)", msg.size(), broadcastAddress.c_str()); auto len = udpSocket->SendData(broadcastAddress, NETWORK_LAN_BROADCAST_PORT, msg.data(), msg.size()); if (len != msg.size()) { @@ -318,9 +319,11 @@ std::future> ServerList::FetchLocalServerListAsync( std::future> ServerList::FetchOnlineServerListAsync() { -#ifdef DISABLE_HTTP +# ifdef DISABLE_HTTP return std::async(std::launch::deferred, [] { return std::vector(); }); -#else +# else + using namespace OpenRCT2::Network; + auto p = std::make_shared>>(); auto f = p->get_future(); @@ -386,7 +389,7 @@ std::future> ServerList::FetchOnlineServerListAsync json_decref(root); }); return f; -#endif +# endif } uint32_t ServerList::GetTotalPlayerCount() const @@ -395,3 +398,5 @@ uint32_t ServerList::GetTotalPlayerCount() const return acc + entry.players; }); } + +#endif From 47f48721e8768a9ce969deeb58064123f6ca40b4 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 May 2019 11:36:09 +0000 Subject: [PATCH 351/506] Fix clang build --- src/openrct2-ui/windows/ServerList.cpp | 2 +- src/openrct2/network/ServerList.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index fa285efcb9..dfef1b6bb9 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -588,7 +588,7 @@ static void server_list_fetch_servers_check(rct_window* w) { try { - auto [entries, statusText] = std::move(_fetchFuture.get()); + auto [entries, statusText] = _fetchFuture.get(); _serverList.AddRange(entries); _numPlayersOnline = _serverList.GetTotalPlayerCount(); _statusText = STR_X_PLAYERS_ONLINE; diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 46f181ae3c..262e7162c9 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -305,7 +305,7 @@ std::future> ServerList::FetchLocalServerListAsync( { try { - auto entries = std::move(f.get()); + auto entries = f.get(); mergedEntries.insert(mergedEntries.begin(), entries.begin(), entries.end()); } catch (...) From 52afcb795fbe94215c6bafb794f9f9aab14cd4b5 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 6 May 2019 12:51:01 +0100 Subject: [PATCH 352/506] Fix windows build --- src/openrct2-ui/windows/ServerList.cpp | 4 ++-- src/openrct2/network/Socket.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index dfef1b6bb9..80ce64a33f 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -557,7 +557,7 @@ static void server_list_fetch_servers_begin() auto entries = lanF.get(); allEntries.insert(allEntries.end(), entries.begin(), entries.end()); } - catch (const std::exception& e) + catch (...) { } @@ -571,7 +571,7 @@ static void server_list_fetch_servers_begin() { status = e.StatusText; } - catch (const std::exception& e) + catch (...) { status = STR_SERVER_LIST_NO_CONNECTION; } diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index fe93b295ea..3fc5b80c10 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -819,7 +819,7 @@ std::unique_ptr CreateUdpSocket() } # ifdef _WIN32 -std::vector GetNetworkInterfaces() +static std::vector GetNetworkInterfaces() { int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) @@ -834,8 +834,8 @@ std::vector GetNetworkInterfaces() { interfaces.resize(capacity); if (WSAIoctl( - sock, SIO_GET_INTERFACE_LIST, nullptr, 0, interfaces.data(), capacity * sizeof(INTERFACE_INFO), &len, nullptr, - nullptr) + sock, SIO_GET_INTERFACE_LIST, nullptr, 0, interfaces.data(), (DWORD)(capacity * sizeof(INTERFACE_INFO)), &len, + nullptr, nullptr) == 0) { break; @@ -870,7 +870,7 @@ std::vector> GetBroadcastAddresses() memcpy(&address, &ifo.iiAddress.Address, sizeof(sockaddr)); ((sockaddr_in*)&address)->sin_addr.s_addr = ifo.iiAddress.AddressIn.sin_addr.s_addr | ~ifo.iiNetmask.AddressIn.sin_addr.s_addr; - baddresses.push_back(std::make_unique(address, sizeof(sockaddr))); + baddresses.push_back(std::make_unique((const sockaddr*)&address, (socklen_t)sizeof(sockaddr))); } # else int sock = socket(AF_INET, SOCK_DGRAM, 0); From 26e0264b5dd3aafda5f4ba4739aa44400e91338a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 6 May 2019 19:08:14 +0200 Subject: [PATCH 353/506] Fix Xcode project --- OpenRCT2.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index a7b3e30d16..19504974b2 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -512,7 +512,7 @@ F76C86551EC4E88300FA49E2 /* NetworkServerAdvertiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C84061EC4E7CC00FA49E2 /* NetworkServerAdvertiser.cpp */; }; F76C86581EC4E88300FA49E2 /* NetworkUser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C84091EC4E7CC00FA49E2 /* NetworkUser.cpp */; }; F76C865A1EC4E88300FA49E2 /* ServerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C840B1EC4E7CC00FA49E2 /* ServerList.cpp */; }; - F76C865C1EC4E88300FA49E2 /* TcpSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C840D1EC4E7CC00FA49E2 /* TcpSocket.cpp */; }; + F76C865C1EC4E88300FA49E2 /* Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C840D1EC4E7CC00FA49E2 /* Socket.cpp */; }; F76C86601EC4E88300FA49E2 /* BannerObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C84121EC4E7CC00FA49E2 /* BannerObject.cpp */; }; F76C86621EC4E88300FA49E2 /* EntranceObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C84141EC4E7CC00FA49E2 /* EntranceObject.cpp */; }; F76C86641EC4E88300FA49E2 /* FootpathItemObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C84161EC4E7CC00FA49E2 /* FootpathItemObject.cpp */; }; @@ -1660,8 +1660,8 @@ F76C840A1EC4E7CC00FA49E2 /* NetworkUser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkUser.h; sourceTree = ""; }; F76C840B1EC4E7CC00FA49E2 /* ServerList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ServerList.cpp; sourceTree = ""; }; F76C840C1EC4E7CC00FA49E2 /* ServerList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ServerList.h; sourceTree = ""; }; - F76C840D1EC4E7CC00FA49E2 /* TcpSocket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TcpSocket.cpp; sourceTree = ""; }; - F76C840E1EC4E7CC00FA49E2 /* TcpSocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TcpSocket.h; sourceTree = ""; }; + F76C840D1EC4E7CC00FA49E2 /* Socket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Socket.cpp; sourceTree = ""; }; + F76C840E1EC4E7CC00FA49E2 /* Socket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Socket.h; sourceTree = ""; }; F76C840F1EC4E7CC00FA49E2 /* Twitch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Twitch.cpp; sourceTree = ""; }; F76C84101EC4E7CC00FA49E2 /* twitch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = twitch.h; sourceTree = ""; }; F76C84121EC4E7CC00FA49E2 /* BannerObject.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BannerObject.cpp; sourceTree = ""; }; @@ -2820,8 +2820,8 @@ F76C840A1EC4E7CC00FA49E2 /* NetworkUser.h */, F76C840B1EC4E7CC00FA49E2 /* ServerList.cpp */, F76C840C1EC4E7CC00FA49E2 /* ServerList.h */, - F76C840D1EC4E7CC00FA49E2 /* TcpSocket.cpp */, - F76C840E1EC4E7CC00FA49E2 /* TcpSocket.h */, + F76C840D1EC4E7CC00FA49E2 /* Socket.cpp */, + F76C840E1EC4E7CC00FA49E2 /* Socket.h */, F76C840F1EC4E7CC00FA49E2 /* Twitch.cpp */, F76C84101EC4E7CC00FA49E2 /* twitch.h */, ); @@ -4123,7 +4123,7 @@ 93F76EFF20BFF77B00D4512C /* Paint.Wall.cpp in Sources */, F76C86581EC4E88300FA49E2 /* NetworkUser.cpp in Sources */, F76C865A1EC4E88300FA49E2 /* ServerList.cpp in Sources */, - F76C865C1EC4E88300FA49E2 /* TcpSocket.cpp in Sources */, + F76C865C1EC4E88300FA49E2 /* Socket.cpp in Sources */, C688784B202899B90084B384 /* Intro.cpp in Sources */, C68878FD20289B9B0084B384 /* MiniRollerCoaster.cpp in Sources */, 2A1F4FE0221FF4B0003CA045 /* Twitch.cpp in Sources */, From 9b1321067b0b6230e1a2b81e549c40de50987455 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 6 May 2019 19:21:09 +0200 Subject: [PATCH 354/506] Use opt:: namespace --- src/openrct2/network/ServerList.cpp | 2 +- src/openrct2/network/ServerList.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 262e7162c9..41bbe696b3 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -75,7 +75,7 @@ bool ServerListEntry::IsVersionValid() const return version.empty() || version == network_get_version(); } -std::optional ServerListEntry::FromJson(const json_t* server) +opt::optional ServerListEntry::FromJson(const json_t* server) { auto port = json_object_get(server, "port"); auto name = json_object_get(server, "name"); diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index c9b44a5746..84e4ca2a33 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -35,7 +35,7 @@ struct ServerListEntry int32_t CompareTo(const ServerListEntry& other) const; bool IsVersionValid() const; - static std::optional FromJson(const json_t* root); + static opt::optional FromJson(const json_t* root); }; class ServerList From 6e6fe3c3c1b111b6098798eb4d407db369ab20af Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 6 May 2019 19:55:42 +0200 Subject: [PATCH 355/506] Replace optional.value() with *optional (fix Xcode compilation) Xcode cannot handle the optional.value() notation, but *optional should mean the same. Also see https://en.cppreference.com/w/cpp/utility/optional/operator* --- src/openrct2/network/ServerList.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 41bbe696b3..324d431b3e 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -273,8 +273,8 @@ std::future> ServerList::FetchLocalServerListAsync( auto entry = ServerListEntry::FromJson(jinfo); if (entry.has_value()) { - entry.value().local = true; - entries.push_back(entry.value()); + (*entry).local = true; + entries.push_back(*entry); } json_decref(jinfo); @@ -375,7 +375,7 @@ std::future> ServerList::FetchOnlineServerListAsync auto entry = ServerListEntry::FromJson(jServer); if (entry.has_value()) { - entries.push_back(entry.value()); + entries.push_back(*entry); } } } From 3334d40da499208c274c63f77842239852d06924 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 09:00:23 +0100 Subject: [PATCH 356/506] Explicitly use std::launch::async --- src/openrct2-ui/windows/ServerList.cpp | 2 +- src/openrct2/network/ServerList.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 80ce64a33f..2ee2e1cf1e 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -545,7 +545,7 @@ static void server_list_fetch_servers_begin() _serverList.ReadAndAddFavourites(); _statusText = STR_SERVER_LIST_CONNECTING; - _fetchFuture = std::async([] { + _fetchFuture = std::async(std::launch::async, [] { // Spin off background fetches auto lanF = _serverList.FetchLocalServerListAsync(); auto wanF = _serverList.FetchOnlineServerListAsync(); diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 324d431b3e..544d795892 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -237,7 +237,7 @@ bool ServerList::WriteFavourites(const std::vector& entries) std::future> ServerList::FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint) { auto broadcastAddress = broadcastEndpoint.GetHostname(); - return std::async([broadcastAddress] { + return std::async(std::launch::async, [broadcastAddress] { constexpr auto RECV_DELAY_MS = 10; constexpr auto RECV_WAIT_MS = 2000; @@ -287,7 +287,7 @@ std::future> ServerList::FetchLocalServerListAsync( std::future> ServerList::FetchLocalServerListAsync() { - return std::async([&] { + return std::async(std::launch::async, [&] { // Get all possible LAN broadcast addresses auto broadcastEndpoints = GetBroadcastAddresses(); From f0d1e9c3208c0e37c3b9ed915412af3b54fd04f7 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 17:41:34 +0100 Subject: [PATCH 357/506] Apply some of the code review comments --- src/openrct2/network/ServerList.cpp | 52 +++++++++++++++++------------ src/openrct2/network/Socket.cpp | 4 ++- src/openrct2/network/Socket.h | 8 ++--- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 544d795892..f5106a52ac 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -252,32 +252,40 @@ std::future> ServerList::FetchLocalServerListAsync( } std::vector entries; - char buffer[1024]{}; - size_t recievedLen{}; - std::unique_ptr endpoint; for (int i = 0; i < (RECV_WAIT_MS / RECV_DELAY_MS); i++) { - auto p = udpSocket->ReceiveData(buffer, sizeof(buffer) - 1, &recievedLen, &endpoint); - if (p == NETWORK_READPACKET_SUCCESS) + try { - auto sender = endpoint->GetHostname(); - log_verbose("Received %zu bytes back from %s", recievedLen, sender.c_str()); - auto jinfo = Json::FromString(std::string_view(buffer)); - - auto ip4 = json_array(); - json_array_append_new(ip4, json_string(sender.c_str())); - auto ip = json_object(); - json_object_set_new(ip, "v4", ip4); - json_object_set_new(jinfo, "ip", ip); - - auto entry = ServerListEntry::FromJson(jinfo); - if (entry.has_value()) + // Start with initialised buffer in case we receive a non-terminated string + char buffer[1024]{}; + size_t recievedLen{}; + std::unique_ptr endpoint; + auto p = udpSocket->ReceiveData(buffer, sizeof(buffer) - 1, &recievedLen, &endpoint); + if (p == NETWORK_READPACKET_SUCCESS) { - (*entry).local = true; - entries.push_back(*entry); - } + auto sender = endpoint->GetHostname(); + log_verbose("Received %zu bytes back from %s", recievedLen, sender.c_str()); + auto jinfo = Json::FromString(std::string_view(buffer)); - json_decref(jinfo); + auto ip4 = json_array(); + json_array_append_new(ip4, json_string(sender.c_str())); + auto ip = json_object(); + json_object_set_new(ip, "v4", ip4); + json_object_set_new(jinfo, "ip", ip); + + auto entry = ServerListEntry::FromJson(jinfo); + if (entry.has_value()) + { + (*entry).local = true; + entries.push_back(*entry); + } + + json_decref(jinfo); + } + } + catch (const std::exception& e) + { + log_warning("Error receiving data: %s", e.what()); } platform_sleep(RECV_DELAY_MS); } @@ -320,7 +328,7 @@ std::future> ServerList::FetchLocalServerListAsync( std::future> ServerList::FetchOnlineServerListAsync() { # ifdef DISABLE_HTTP - return std::async(std::launch::deferred, [] { return std::vector(); }); + return {}; # else using namespace OpenRCT2::Network; diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index 3fc5b80c10..6a26622b85 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -827,8 +827,10 @@ static std::vector GetNetworkInterfaces() return {}; } + // Get all the network interfaces, requires a trial and error approch + // until we find the capacity required to store all of them. DWORD len = 0; - size_t capacity = 2; + size_t capacity = 16; std::vector interfaces; for (;;) { diff --git a/src/openrct2/network/Socket.h b/src/openrct2/network/Socket.h index 178388aa89..87d563cf23 100644 --- a/src/openrct2/network/Socket.h +++ b/src/openrct2/network/Socket.h @@ -50,9 +50,7 @@ interface INetworkEndpoint interface ITcpSocket { public: - virtual ~ITcpSocket() - { - } + virtual ~ITcpSocket() = default; virtual SOCKET_STATUS GetStatus() abstract; virtual const char* GetError() abstract; @@ -78,9 +76,7 @@ public: interface IUdpSocket { public: - virtual ~IUdpSocket() - { - } + virtual ~IUdpSocket() = default; virtual SOCKET_STATUS GetStatus() abstract; virtual const char* GetError() abstract; From f8e3abcf4eaa116ece7649f69fc656975c7cdd1f Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 17:47:29 +0100 Subject: [PATCH 358/506] Remove by-reference string_view --- src/openrct2/core/Json.cpp | 2 +- src/openrct2/core/Json.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/core/Json.cpp b/src/openrct2/core/Json.cpp index 87fd5a6799..07c868630b 100644 --- a/src/openrct2/core/Json.cpp +++ b/src/openrct2/core/Json.cpp @@ -53,7 +53,7 @@ namespace Json fs.Write(jsonOutput, jsonOutputSize); } - json_t* FromString(const std::string_view& raw) + json_t* FromString(std::string_view raw) { json_t* root; json_error_t error; diff --git a/src/openrct2/core/Json.hpp b/src/openrct2/core/Json.hpp index 693097ec46..53687b9890 100644 --- a/src/openrct2/core/Json.hpp +++ b/src/openrct2/core/Json.hpp @@ -24,7 +24,7 @@ namespace Json json_t* ReadFromFile(const utf8* path, size_t maxSize = MAX_JSON_SIZE); void WriteToFile(const utf8* path, const json_t* json, size_t flags = 0); - json_t* FromString(const std::string_view& raw); + json_t* FromString(std::string_view raw); } // namespace Json class JsonException final : public std::runtime_error From 73b8310e8e955d022b56aa7627de188e9fd2ee37 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 17:55:48 +0100 Subject: [PATCH 359/506] Refactor creation of UDP socket --- src/openrct2/network/Socket.cpp | 79 +++++++++++++++------------------ 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index 6a26622b85..63e30d47fe 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -613,29 +613,7 @@ public: } // Create the listening socket - _socket = socket(ss.ss_family, SOCK_DGRAM, IPPROTO_UDP); - if (_socket == INVALID_SOCKET) - { - throw SocketException("Unable to create socket."); - } - - // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections - if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) - { - log_error("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); - } - - if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) - { - log_error("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); - } - - // Enable send and receiving of broadcast messages - if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) - { - log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); - } - + _socket = CreateSocket(); try { // Bind to address:port and listen @@ -643,11 +621,6 @@ public: { throw SocketException("Unable to bind to socket."); } - - if (!SetNonBlocking(_socket, true)) - { - throw SocketException("Failed to set non-blocking mode."); - } } catch (const std::exception&) { @@ -675,22 +648,7 @@ public: { if (_socket == INVALID_SOCKET) { - _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (_socket == INVALID_SOCKET) - { - throw SocketException("Unable to create socket."); - } - - // Enable send and receiving of broadcast messages - if (!SetOption(_socket, SOL_SOCKET, SO_BROADCAST, true)) - { - log_error("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); - } - - if (!SetNonBlocking(_socket, true)) - { - throw SocketException("Failed to set non-blocking mode."); - } + _socket = CreateSocket(); } const auto& dest = dynamic_cast(&destination); @@ -766,6 +724,39 @@ private: _status = SOCKET_STATUS_CONNECTED; } + SOCKET CreateSocket() + { + auto sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == INVALID_SOCKET) + { + throw SocketException("Unable to create socket."); + } + + // Enable send and receiving of broadcast messages + if (!SetOption(sock, SOL_SOCKET, SO_BROADCAST, true)) + { + log_warning("SO_BROADCAST failed. %d", LAST_SOCKET_ERROR()); + } + + // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections + if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) + { + log_warning("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); + } + + if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) + { + log_warning("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); + } + + if (!SetNonBlocking(sock, true)) + { + throw SocketException("Failed to set non-blocking mode."); + } + + return sock; + } + void CloseSocket() { if (_socket != INVALID_SOCKET) From 5e94f6385d061a7d9d950f5cc54e6f3ad519a258 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 May 2019 13:59:34 +0100 Subject: [PATCH 360/506] Initialise hostname --- src/openrct2/network/Socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index 63e30d47fe..e0ef79537b 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -118,7 +118,7 @@ public: std::string GetHostname() const override { - char hostname[256]; + char hostname[256]{}; int res = getnameinfo(&_address, _addressLen, hostname, sizeof(hostname), nullptr, 0, NI_NUMERICHOST); if (res == 0) { From dd20ebad49f46d58904e5ea0ed92a9c4d2a13a7b Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 May 2019 00:57:56 +0100 Subject: [PATCH 361/506] Make more methods const --- src/openrct2/network/ServerList.cpp | 12 ++++++------ src/openrct2/network/ServerList.h | 12 ++++++------ src/openrct2/network/Socket.cpp | 12 ++++++------ src/openrct2/network/Socket.h | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index f5106a52ac..d2efbb0fac 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -152,7 +152,7 @@ void ServerList::Clear() _serverEntries.clear(); } -std::vector ServerList::ReadFavourites() +std::vector ServerList::ReadFavourites() const { log_verbose("server_list_read(...)"); std::vector entries; @@ -197,7 +197,7 @@ void ServerList::ReadAndAddFavourites() AddRange(entries); } -void ServerList::WriteFavourites() +void ServerList::WriteFavourites() const { // Save just favourite servers std::vector favouriteServers; @@ -207,7 +207,7 @@ void ServerList::WriteFavourites() WriteFavourites(favouriteServers); } -bool ServerList::WriteFavourites(const std::vector& entries) +bool ServerList::WriteFavourites(const std::vector& entries) const { log_verbose("server_list_write(%d, 0x%p)", entries.size(), entries.data()); @@ -234,7 +234,7 @@ bool ServerList::WriteFavourites(const std::vector& entries) } } -std::future> ServerList::FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint) +std::future> ServerList::FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint) const { auto broadcastAddress = broadcastEndpoint.GetHostname(); return std::async(std::launch::async, [broadcastAddress] { @@ -293,7 +293,7 @@ std::future> ServerList::FetchLocalServerListAsync( }); } -std::future> ServerList::FetchLocalServerListAsync() +std::future> ServerList::FetchLocalServerListAsync() const { return std::async(std::launch::async, [&] { // Get all possible LAN broadcast addresses @@ -325,7 +325,7 @@ std::future> ServerList::FetchLocalServerListAsync( }); } -std::future> ServerList::FetchOnlineServerListAsync() +std::future> ServerList::FetchOnlineServerListAsync() const { # ifdef DISABLE_HTTP return {}; diff --git a/src/openrct2/network/ServerList.h b/src/openrct2/network/ServerList.h index 84e4ca2a33..b0cb5e1bc2 100644 --- a/src/openrct2/network/ServerList.h +++ b/src/openrct2/network/ServerList.h @@ -44,9 +44,9 @@ private: std::vector _serverEntries; void Sort(); - std::vector ReadFavourites(); - bool WriteFavourites(const std::vector& entries); - std::future> FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint); + std::vector ReadFavourites() const; + bool WriteFavourites(const std::vector& entries) const; + std::future> FetchLocalServerListAsync(const INetworkEndpoint& broadcastEndpoint) const; public: ServerListEntry& GetServer(size_t index); @@ -56,10 +56,10 @@ public: void Clear(); void ReadAndAddFavourites(); - void WriteFavourites(); + void WriteFavourites() const; - std::future> FetchLocalServerListAsync(); - std::future> FetchOnlineServerListAsync(); + std::future> FetchLocalServerListAsync() const; + std::future> FetchOnlineServerListAsync() const; uint32_t GetTotalPlayerCount() const; }; diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index e0ef79537b..12fed91b78 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -216,12 +216,12 @@ public: CloseSocket(); } - SOCKET_STATUS GetStatus() override + SOCKET_STATUS GetStatus() const override { return _status; } - const char* GetError() override + const char* GetError() const override { return _error.empty() ? nullptr : _error.c_str(); } @@ -583,12 +583,12 @@ public: CloseSocket(); } - SOCKET_STATUS GetStatus() override + SOCKET_STATUS GetStatus() const override { return _status; } - const char* GetError() override + const char* GetError() const override { return _error.empty() ? nullptr : _error.c_str(); } @@ -739,12 +739,12 @@ private: } // Turn off IPV6_V6ONLY so we can accept both v4 and v6 connections - if (!SetOption(_socket, IPPROTO_IPV6, IPV6_V6ONLY, false)) + if (!SetOption(sock, IPPROTO_IPV6, IPV6_V6ONLY, false)) { log_warning("IPV6_V6ONLY failed. %d", LAST_SOCKET_ERROR()); } - if (!SetOption(_socket, SOL_SOCKET, SO_REUSEADDR, true)) + if (!SetOption(sock, SOL_SOCKET, SO_REUSEADDR, true)) { log_warning("SO_REUSEADDR failed. %d", LAST_SOCKET_ERROR()); } diff --git a/src/openrct2/network/Socket.h b/src/openrct2/network/Socket.h index 87d563cf23..601168b31b 100644 --- a/src/openrct2/network/Socket.h +++ b/src/openrct2/network/Socket.h @@ -52,8 +52,8 @@ interface ITcpSocket public: virtual ~ITcpSocket() = default; - virtual SOCKET_STATUS GetStatus() abstract; - virtual const char* GetError() abstract; + virtual SOCKET_STATUS GetStatus() const abstract; + virtual const char* GetError() const abstract; virtual const char* GetHostName() const abstract; virtual void Listen(uint16_t port) abstract; @@ -78,8 +78,8 @@ interface IUdpSocket public: virtual ~IUdpSocket() = default; - virtual SOCKET_STATUS GetStatus() abstract; - virtual const char* GetError() abstract; + virtual SOCKET_STATUS GetStatus() const abstract; + virtual const char* GetError() const abstract; virtual const char* GetHostName() const abstract; virtual void Listen(uint16_t port) abstract; From 1ac8d9058f908a2558d11a6624adc79278a34ddf Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 May 2019 01:05:11 +0100 Subject: [PATCH 362/506] Colour local servers as green --- src/openrct2-ui/windows/ServerList.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 2ee2e1cf1e..7bc4c7a175 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -448,6 +448,10 @@ static void window_server_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi { colour = COLOUR_YELLOW; } + else if (serverDetails.local) + { + colour = COLOUR_MOSS_GREEN; + } // Draw server information if (highlighted && !serverDetails.description.empty()) From d3b5ac3f07d4ca1f3b725362241c5f650b77ba70 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sun, 12 May 2019 04:00:22 +0000 Subject: [PATCH 363/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/de-DE.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/data/language/de-DE.txt b/data/language/de-DE.txt index 1964b24c41..af9eae6e7d 100644 --- a/data/language/de-DE.txt +++ b/data/language/de-DE.txt @@ -3768,6 +3768,14 @@ STR_6306 :{SMALLFONT}{BLACK}Experimentelle Option, um mehrere Threads für da STR_6307 :Farbschema: {BLACK}{STRINGID} STR_6308 :„{STRINGID}{OUTLINE}{TOPAZ}“{NEWLINE}{STRINGID} STR_6309 :Neu verbinden +STR_6310 :{WINDOW_COLOUR_2}Position: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Nächste: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(Oberfläche) +STR_6313 :(Hang {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Ziel: {BLACK}{INT32}, {INT32} Toleranz {INT32} +STR_6315 :{WINDOW_COLOUR_2}Wegfindungsziel: {BLACK}{INT32}, {INT32}, {INT32} Richt. {INT32} +STR_6316 :{WINDOW_COLOUR_2}Wegfindungshistorie: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} Richtung {INT32} ############# # Scenarios # From 5da95e963d554db256ffab9ac26ea795232f7bb8 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 12 May 2019 09:54:21 +0100 Subject: [PATCH 364/506] Fix GameAction use during pause (#9242) * Use correct flag to allow action while paused. Mistake made during implementing on GameActions * Increment network version --- src/openrct2/actions/BannerSetColourAction.hpp | 2 +- src/openrct2/actions/BannerSetStyleAction.hpp | 2 +- src/openrct2/actions/LargeScenerySetColourAction.hpp | 2 +- src/openrct2/actions/SmallScenerySetColourAction.hpp | 2 +- src/openrct2/network/Network.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2/actions/BannerSetColourAction.hpp b/src/openrct2/actions/BannerSetColourAction.hpp index ff1d1a51d7..fc05c1e749 100644 --- a/src/openrct2/actions/BannerSetColourAction.hpp +++ b/src/openrct2/actions/BannerSetColourAction.hpp @@ -32,7 +32,7 @@ public: uint16_t GetActionFlags() const override { - return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; } void Serialise(DataSerialiser & stream) override diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp index 038a0265b4..82488307bf 100644 --- a/src/openrct2/actions/BannerSetStyleAction.hpp +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -44,7 +44,7 @@ public: uint16_t GetActionFlags() const override { - return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; } void Serialise(DataSerialiser & stream) override diff --git a/src/openrct2/actions/LargeScenerySetColourAction.hpp b/src/openrct2/actions/LargeScenerySetColourAction.hpp index 0888488205..7cfff25de3 100644 --- a/src/openrct2/actions/LargeScenerySetColourAction.hpp +++ b/src/openrct2/actions/LargeScenerySetColourAction.hpp @@ -35,7 +35,7 @@ public: uint16_t GetActionFlags() const override { - return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; } void Serialise(DataSerialiser & stream) override diff --git a/src/openrct2/actions/SmallScenerySetColourAction.hpp b/src/openrct2/actions/SmallScenerySetColourAction.hpp index 8f30ffd604..937ac551a9 100644 --- a/src/openrct2/actions/SmallScenerySetColourAction.hpp +++ b/src/openrct2/actions/SmallScenerySetColourAction.hpp @@ -51,7 +51,7 @@ public: uint16_t GetActionFlags() const override { - return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; } void Serialise(DataSerialiser & stream) override diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 55376637ec..4ca115b4f7 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,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 "26" +#define NETWORK_STREAM_VERSION "27" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 5198df5c25acfe2635d5d2999a7592ec48e11b0a Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 11 May 2019 22:38:57 +0200 Subject: [PATCH 365/506] Improve generation of random advertisment key --- src/openrct2/network/NetworkServerAdvertiser.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 1b8623bfb4..cf90398753 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -27,6 +27,7 @@ # include # include +# include # include # ifndef DISABLE_HTTP @@ -241,10 +242,14 @@ private: static constexpr char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; + + std::random_device rd; + std::uniform_int_distribution<> dist(0, std::size(hexChars) - 1); + char key[17]; for (int32_t i = 0; i < 16; i++) { - int32_t hexCharIndex = util_rand() % std::size(hexChars); + int32_t hexCharIndex = dist(rd); key[i] = hexChars[hexCharIndex]; } key[std::size(key) - 1] = 0; From c6ea47c631b4f4e19099d3d41959fc6af312c5ef Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 12 May 2019 11:32:33 +0200 Subject: [PATCH 366/506] Make util_rand thread safe --- src/openrct2/Context.cpp | 1 - src/openrct2/util/Util.cpp | 8 +------- src/openrct2/util/Util.h | 1 - src/openrct2/world/MapGen.cpp | 2 -- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 11674063fe..59382c20d9 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -426,7 +426,6 @@ namespace OpenRCT2 } gScenarioTicks = 0; - util_srand((uint32_t)time(nullptr)); input_reset_place_obj_modifier(); viewport_init_all(); diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 29d858ee3c..0cd47c5cfb 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -23,8 +23,6 @@ #include #include -static std::mt19937 _prng; - int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres) { // 1 metre squared = 10.7639104 feet squared @@ -529,13 +527,9 @@ bool str_is_null_or_empty(const char* str) return str == nullptr || str[0] == 0; } -void util_srand(int32_t source) -{ - _prng.seed(source); -} - uint32_t util_rand() { + thread_local std::mt19937 _prng(std::random_device{}()); return _prng(); } diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index 3fc0d2f1f0..ec046e8036 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -50,7 +50,6 @@ char* strcasestr(const char* haystack, const char* needle); bool utf8_is_bom(const char* str); bool str_is_null_or_empty(const char* str); -void util_srand(int32_t source); uint32_t util_rand(); uint8_t* util_zlib_deflate(const uint8_t* data, size_t data_in_size, size_t* data_out_size); diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 33dbba1254..b624879531 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -136,8 +136,6 @@ void mapgen_generate(mapgen_settings* settings) int32_t x, y, mapSize, floorTexture, wallTexture, waterLevel; TileElement* tileElement; - util_srand((int32_t)platform_get_ticks()); - mapSize = settings->mapSize; floorTexture = settings->floor; wallTexture = settings->wall; From eb3018b6a94b6207a4c91c84f82bb3e10035f36b Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 12 May 2019 11:32:41 +0200 Subject: [PATCH 367/506] Fix warnings --- src/openrct2/network/NetworkServerAdvertiser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index cf90398753..5658d25c31 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -244,7 +244,7 @@ private: }; std::random_device rd; - std::uniform_int_distribution<> dist(0, std::size(hexChars) - 1); + std::uniform_int_distribution dist(0, static_cast(std::size(hexChars) - 1)); char key[17]; for (int32_t i = 0; i < 16; i++) From 15cb3e18891df10df4c951ebb6b30c7bea92796e Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 May 2019 12:48:56 +0100 Subject: [PATCH 368/506] Remove unnecessary new line characters from log calls (#9237) --- src/openrct2-ui/UiContext.Linux.cpp | 2 +- src/openrct2-ui/UiContext.macOS.mm | 2 +- src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp | 2 +- src/openrct2/GameStateSnapshots.cpp | 2 +- src/openrct2/actions/MazeSetTrackAction.hpp | 2 +- src/openrct2/common.h | 2 +- src/openrct2/interface/Screenshot.cpp | 4 ++-- src/openrct2/network/Network.cpp | 2 +- src/openrct2/paint/VirtualFloor.cpp | 2 +- src/openrct2/platform/Windows.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 8 ++++---- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index bf927707f7..b2e9913f8c 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -265,7 +265,7 @@ namespace OpenRCT2::Ui static int32_t Execute(const std::string& command, std::string* output = nullptr) { # ifndef __EMSCRIPTEN__ - log_verbose("executing \"%s\"...\n", command.c_str()); + log_verbose("executing \"%s\"...", command.c_str()); FILE* fpipe = popen(command.c_str(), "r"); if (fpipe == nullptr) { diff --git a/src/openrct2-ui/UiContext.macOS.mm b/src/openrct2-ui/UiContext.macOS.mm index a07836a712..01c76b7872 100644 --- a/src/openrct2-ui/UiContext.macOS.mm +++ b/src/openrct2-ui/UiContext.macOS.mm @@ -143,7 +143,7 @@ namespace OpenRCT2::Ui private: static int32_t Execute(const std::string& command, std::string* output = nullptr) { - log_verbose("executing \"%s\"...\n", command.c_str()); + log_verbose("executing \"%s\"...", command.c_str()); FILE* fpipe = popen(command.c_str(), "r"); if (fpipe == nullptr) { diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 65b2f09459..af63ac516c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -279,7 +279,7 @@ AtlasTextureInfo TextureCache::AllocateImage(int32_t imageWidth, int32_t imageHe int32_t atlasSize = (int32_t)powf(2, (float)Atlas::CalculateImageSizeOrder(imageWidth, imageHeight)); # ifdef DEBUG - log_verbose("new texture atlas #%d (size %d) allocated\n", atlasIndex, atlasSize); + log_verbose("new texture atlas #%d (size %d) allocated", atlasIndex, atlasSize); # endif _atlases.emplace_back(atlasIndex, atlasSize); diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp index 9307dc3c8a..8349c2961e 100644 --- a/src/openrct2/GameStateSnapshots.cpp +++ b/src/openrct2/GameStateSnapshots.cpp @@ -125,7 +125,7 @@ struct GameStateSnapshots : public IGameStateSnapshots { snapshot.SerialiseSprites(get_sprite(0), MAX_SPRITES, true); - // log_info("Snapshot size: %u bytes\n", (uint32_t)snapshot.storedSprites.GetLength()); + // log_info("Snapshot size: %u bytes", (uint32_t)snapshot.storedSprites.GetLength()); } virtual const GameStateSnapshot_t* GetLinkedSnapshot(uint32_t tick) const override final diff --git a/src/openrct2/actions/MazeSetTrackAction.hpp b/src/openrct2/actions/MazeSetTrackAction.hpp index 7a0767bdd4..80e53ec5bd 100644 --- a/src/openrct2/actions/MazeSetTrackAction.hpp +++ b/src/openrct2/actions/MazeSetTrackAction.hpp @@ -302,7 +302,7 @@ public: map_invalidate_tile_full(floor2(previousSegmentX, 32), floor2(previousSegmentY, 32)); if (tileElement == nullptr) { - log_error("No surface found\n"); + log_error("No surface found"); res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = STR_NONE; return res; diff --git a/src/openrct2/common.h b/src/openrct2/common.h index 68cd3f8c99..2110a4415c 100644 --- a/src/openrct2/common.h +++ b/src/openrct2/common.h @@ -65,7 +65,7 @@ const constexpr auto ror64 = ror; #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) # include -# define STUB() log_warning("Function %s at %s:%d is a stub.\n", __PRETTY_FUNCTION__, __FILE__, __LINE__) +# define STUB() log_warning("Function %s at %s:%d is a stub.", __PRETTY_FUNCTION__, __FILE__, __LINE__) # define _strcmpi _stricmp # define _stricmp(x, y) strcasecmp((x), (y)) # define _strnicmp(x, y, n) strncasecmp((x), (y), (n)) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index ca46599eee..591a465aa3 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -140,7 +140,7 @@ static opt::optional screenshot_get_next_path() auto screenshotDirectory = screenshot_get_directory(); if (!platform_ensure_directory_exists(screenshotDirectory.c_str())) { - log_error("Unable to save screenshots in OpenRCT2 screenshot directory.\n"); + log_error("Unable to save screenshots in OpenRCT2 screenshot directory."); return {}; } @@ -164,7 +164,7 @@ static opt::optional screenshot_get_next_path() } } - log_error("You have too many saved screenshots saved at exactly the same date and time.\n"); + log_error("You have too many saved screenshots saved at exactly the same date and time."); return {}; }; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index f95d040ff4..ac7f7a1807 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -539,7 +539,7 @@ bool Network::BeginClient(const std::string& host, uint16_t port) mode = NETWORK_MODE_CLIENT; - log_info("Connecting to %s:%u\n", host.c_str(), port); + log_info("Connecting to %s:%u", host.c_str(), port); _host = host; _port = port; diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index 5aadd3508a..06fecbd57b 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -149,7 +149,7 @@ void virtual_floor_invalidate() return; } - log_verbose("Min: %d %d, Max: %d %d\n", min_position.x, min_position.y, max_position.x, max_position.y); + log_verbose("Min: %d %d, Max: %d %d", min_position.x, min_position.y, max_position.x, max_position.y); // Invalidate new region if coordinates are set. if (min_position.x != std::numeric_limits::max() && min_position.y != std::numeric_limits::max() diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 5167add70b..e3a0d6f2bc 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -170,7 +170,7 @@ bool platform_lock_single_instance() // Create new mutex status = CreateMutex(nullptr, FALSE, SINGLE_INSTANCE_MUTEX_NAME); if (status == nullptr) - log_error("unable to create mutex\n"); + log_error("unable to create mutex"); return true; } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index e2d6a37b31..14105f77e2 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -115,7 +115,7 @@ public: auto chunkReader = SawyerChunkReader(stream); chunkReader.ReadChunk(&_s6.header, sizeof(_s6.header)); - log_verbose("saved game classic_flag = 0x%02x\n", _s6.header.classic_flag); + log_verbose("saved game classic_flag = 0x%02x", _s6.header.classic_flag); if (isScenario) { if (_s6.header.type != S6_TYPE_SCENARIO) @@ -1434,7 +1434,7 @@ void load_from_sv6(const char* path) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; - log_error("Error loading: %s\n", loadError.what()); + log_error("Error loading: %s", loadError.what()); } catch (const std::exception&) { @@ -1466,13 +1466,13 @@ void load_from_sc6(const char* path) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; - log_error("Error loading: %s\n", loadError.what()); + log_error("Error loading: %s", loadError.what()); } catch (const IOException& loadError) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; - log_error("Error loading: %s\n", loadError.what()); + log_error("Error loading: %s", loadError.what()); } catch (const std::exception&) { From e9e445837f5d5268c0ba6ae85be71460c741ce2b Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 17 Mar 2019 08:25:51 +0000 Subject: [PATCH 369/506] Add landset/buyrights action --- src/openrct2-ui/windows/LandRights.cpp | 47 ++-- src/openrct2-ui/windows/Map.cpp | 17 +- src/openrct2/Editor.cpp | 11 +- src/openrct2/Game.cpp | 4 +- src/openrct2/Game.h | 38 +-- .../actions/GameActionRegistration.cpp | 3 + src/openrct2/actions/LandBuyRightsAction.hpp | 184 ++++++++++++++ src/openrct2/actions/LandSetRightsAction.hpp | 231 ++++++++++++++++++ src/openrct2/world/Footpath.cpp | 5 +- src/openrct2/world/Map.cpp | 55 +---- src/openrct2/world/Map.h | 2 - src/openrct2/world/Park.cpp | 207 ---------------- src/openrct2/world/Park.h | 15 -- 13 files changed, 494 insertions(+), 325 deletions(-) create mode 100644 src/openrct2/actions/LandBuyRightsAction.hpp create mode 100644 src/openrct2/actions/LandSetRightsAction.hpp diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index ff97ba56c3..85b090d743 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -364,11 +365,13 @@ static void window_land_rights_tool_update_land_rights(int16_t x, int16_t y) if (!state_changed) return; - _landRightsCost = game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_NO_SPEND, gMapSelectPositionA.y, - (_landRightsMode == LAND_RIGHTS_MODE_BUY_LAND) ? BUY_LAND_RIGHTS_FLAG_BUY_LAND - : BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, - GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto landBuyRightsAction = LandBuyRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + (_landRightsMode == LAND_RIGHTS_MODE_BUY_LAND) ? LandBuyRightSetting::BuyLand + : LandBuyRightSetting::BuyConstructionRights); + auto res = GameActions::Query(&landBuyRightsAction); + + _landRightsCost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED; } /** @@ -407,21 +410,20 @@ static void window_land_rights_tooldown(rct_window* w, rct_widgetindex widgetInd { if (x != LOCATION_NULL) { - gGameCommandErrorTitle = STR_CANT_BUY_LAND; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, BUY_LAND_RIGHTS_FLAG_BUY_LAND, - GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto landBuyRightsAction = LandBuyRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandBuyRightSetting::BuyLand); + GameActions::Execute(&landBuyRightsAction); } } else { if (x != LOCATION_NULL) { - gGameCommandErrorTitle = STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, - BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, - gMapSelectPositionB.y); + auto landBuyRightsAction = LandBuyRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandBuyRightSetting::BuyConstructionRights); + GameActions::Execute(&landBuyRightsAction); } } } @@ -436,21 +438,20 @@ static void window_land_rights_tooldrag(rct_window* w, rct_widgetindex widgetInd { if (x != LOCATION_NULL) { - gGameCommandErrorTitle = STR_CANT_BUY_LAND; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, BUY_LAND_RIGHTS_FLAG_BUY_LAND, - GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto landBuyRightsAction = LandBuyRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandBuyRightSetting::BuyLand); + GameActions::Execute(&landBuyRightsAction); } } else { if (x != LOCATION_NULL) { - gGameCommandErrorTitle = STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, - BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, GAME_COMMAND_BUY_LAND_RIGHTS, gMapSelectPositionB.x, - gMapSelectPositionB.y); + auto landBuyRightsAction = LandBuyRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandBuyRightSetting::BuyConstructionRights); + GameActions::Execute(&landBuyRightsAction); } } } diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 2e70b6a74f..1d50f6c495 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -505,10 +506,10 @@ static void window_map_tooldrag(rct_window* w, rct_widgetindex widgetIndex, int3 case WIDX_SET_LAND_RIGHTS: if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) { - gGameCommandErrorTitle = 0; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, _activeTool, - GAME_COMMAND_SET_LAND_OWNERSHIP, gMapSelectPositionB.x, gMapSelectPositionB.y); + auto landSetRightsAction = LandSetRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandSetRightSetting::SetOwnershipWithChecks, _activeTool << 4); + GameActions::Execute(&landSetRightsAction); } break; } @@ -614,10 +615,10 @@ static void window_map_scrollmousedown(rct_window* w, int32_t scrollIndex, int32 gMapSelectPositionB.y = mapY + size; map_invalidate_selection_rect(); - gGameCommandErrorTitle = 0; - game_do_command( - gMapSelectPositionA.x, GAME_COMMAND_FLAG_APPLY, gMapSelectPositionA.y, _activeTool, GAME_COMMAND_SET_LAND_OWNERSHIP, - gMapSelectPositionB.x, gMapSelectPositionB.y); + auto landSetRightsAction = LandSetRightsAction( + { gMapSelectPositionA.x, gMapSelectPositionA.y, gMapSelectPositionB.x, gMapSelectPositionB.y }, + LandSetRightSetting::SetOwnershipWithChecks, _activeTool << 4); + GameActions::Execute(&landSetRightsAction); } } diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 511cb2491b..f22d4036a4 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -23,6 +23,8 @@ #include "management/NewsItem.h" #include "object/ObjectManager.h" #include "object/ObjectRepository.h" +#include "actions/LandBuyRightsAction.hpp" +#include "actions/LandSetRightsAction.hpp" #include "peep/Staff.h" #include "rct1/RCT1.h" #include "scenario/Scenario.h" @@ -193,7 +195,14 @@ namespace Editor { int32_t mapSize = gMapSize; - game_do_command(64, 1, 64, 2, GAME_COMMAND_SET_LAND_OWNERSHIP, (mapSize - 3) * 32, (mapSize - 3) * 32); + MapRange range = { 64, 64, (mapSize - 3) * 32, (mapSize - 3) * 32 }; + auto landSetRightsAction = LandSetRightsAction(range, LandSetRightSetting::SetForSale); + landSetRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND); + GameActions::Execute(&landSetRightsAction); + + auto landBuyRightsAction = LandBuyRightsAction(range, LandBuyRightSetting::BuyLand); + landBuyRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND); + GameActions::Execute(&landBuyRightsAction); } /** diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 08d131f8f3..4fae71dd06 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1191,7 +1191,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_buy_land_rights, + nullptr, game_command_place_park_entrance, nullptr, game_command_set_maze_track, @@ -1212,7 +1212,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_land_ownership, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 2627ab9d37..177f165e1a 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -54,18 +54,18 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_ORDERS, // GA GAME_COMMAND_SET_PARK_NAME, // GA GAME_COMMAND_SET_PARK_OPEN, // GA - GAME_COMMAND_BUY_LAND_RIGHTS, - GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA - GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA - GAME_COMMAND_SET_MAZE_TRACK, // GA - GAME_COMMAND_SET_PARK_ENTRANCE_FEE, // GA - GAME_COMMAND_SET_STAFF_COLOUR, // GA - GAME_COMMAND_PLACE_WALL, // GA - GAME_COMMAND_REMOVE_WALL, // 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_BUY_LAND_RIGHTS, // GA + GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA + GAME_COMMAND_REMOVE_PARK_ENTRANCE, // GA + GAME_COMMAND_SET_MAZE_TRACK, // GA + GAME_COMMAND_SET_PARK_ENTRANCE_FEE, // GA + GAME_COMMAND_SET_STAFF_COLOUR, // GA + GAME_COMMAND_PLACE_WALL, // GA + GAME_COMMAND_REMOVE_WALL, // 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, @@ -75,13 +75,13 @@ enum GAME_COMMAND GAME_COMMAND_SET_WALL_COLOUR, // GA GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA GAME_COMMAND_SET_BANNER_COLOUR, // GA - GAME_COMMAND_SET_LAND_OWNERSHIP, - GAME_COMMAND_CLEAR_SCENERY, // GA - GAME_COMMAND_SET_BANNER_NAME, // GA - GAME_COMMAND_SET_SIGN_NAME, // GA - GAME_COMMAND_SET_BANNER_STYLE, // GA - GAME_COMMAND_SET_SIGN_STYLE, // GA - GAME_COMMAND_SET_PLAYER_GROUP, // GA + GAME_COMMAND_SET_LAND_OWNERSHIP, // GA + GAME_COMMAND_CLEAR_SCENERY, // GA + GAME_COMMAND_SET_BANNER_NAME, // GA + GAME_COMMAND_SET_SIGN_NAME, // GA + GAME_COMMAND_SET_BANNER_STYLE, // GA + GAME_COMMAND_SET_SIGN_STYLE, // GA + GAME_COMMAND_SET_PLAYER_GROUP, // GA GAME_COMMAND_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, GAME_COMMAND_CHEAT, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 67fe2817c6..a4740bb520 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -22,9 +22,11 @@ #include "GameAction.h" #include "GuestSetFlagsAction.hpp" #include "GuestSetNameAction.hpp" +#include "LandBuyRightsAction.hpp" #include "LandLowerAction.hpp" #include "LandRaiseAction.hpp" #include "LandSetHeightAction.hpp" +#include "LandSetRightsAction.hpp" #include "LandSmoothAction.hpp" #include "LargeSceneryPlaceAction.hpp" #include "LargeSceneryRemoveAction.hpp" @@ -138,6 +140,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/LandBuyRightsAction.hpp b/src/openrct2/actions/LandBuyRightsAction.hpp new file mode 100644 index 0000000000..573821b266 --- /dev/null +++ b/src/openrct2/actions/LandBuyRightsAction.hpp @@ -0,0 +1,184 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../actions/LandSetHeightAction.hpp" +#include "../audio/audio.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/RideData.h" +#include "../windows/Intent.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" + +enum class LandBuyRightSetting : uint8_t +{ + BuyLand, + BuyConstructionRights, + Count +}; + +DEFINE_GAME_ACTION(LandBuyRightsAction, GAME_COMMAND_BUY_LAND_RIGHTS, GameActionResult) +{ +private: + MapRange _range; + uint8_t _setting = static_cast(LandBuyRightSetting::Count); + + constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_BUY_LAND, STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE }; + +public: + LandBuyRightsAction() + { + } + LandBuyRightsAction(MapRange range, LandBuyRightSetting setting) + : _range(range) + , _setting(static_cast(setting)) + { + } + + LandBuyRightsAction(CoordsXY coord, LandBuyRightSetting setting) + : _range(coord.x, coord.y, coord.x, coord.y) + , _setting(static_cast(setting)) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_range) << DS_TAG(_setting); + } + + 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(); + + MapRange normRange = _range.Normalise(); + // Keep big coordinates within map boundaries + auto aX = std::max(32, normRange.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, normRange.GetRight()); + auto aY = std::max(32, normRange.GetTop()); + auto bY = std::min(gMapSizeMaxXY, normRange.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + CoordsXYZ centre{ (validRange.GetLeft() + validRange.GetRight()) / 2 + 16, + (validRange.GetTop() + validRange.GetBottom()) / 2 + 16, 0 }; + centre.z = tile_element_height(centre.x, centre.y); + + res->Position = centre; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; + + // Game command modified to accept selection size + for (auto y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (auto x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + auto result = map_buy_land_rights_for_tile({ x, y }, isExecuting); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + } + } + } + if (isExecuting) + { + map_count_remaining_land_rights(); + } + return res; + } + + GameActionResult::Ptr map_buy_land_rights_for_tile(const CoordsXY loc, bool isExecuting) const + { + if (_setting >= static_cast(LandBuyRightSetting::Count)) + { + log_warning("Tried calling buy land rights with an incorrect setting. setting = %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[0], STR_NONE); + } + + SurfaceElement* surfaceElement = map_get_surface_element_at(loc)->AsSurface(); + if (surfaceElement == nullptr) + { + log_error("Could not find surface. x = %d, y = %d", loc.x, loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[_setting], STR_NONE); + } + + auto res = MakeResult(); + switch (static_cast(_setting)) + { + case LandBuyRightSetting::BuyLand: // 0 + if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) != 0) + { // If the land is already owned + return res; + } + + if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 + || (surfaceElement->GetOwnership() & OWNERSHIP_AVAILABLE) == 0) + { + return MakeResult(GA_ERROR::NOT_OWNED, _ErrorTitles[_setting], STR_LAND_NOT_FOR_SALE); + } + if (isExecuting) + { + surfaceElement->SetOwnership(OWNERSHIP_OWNED); + update_park_fences_around_tile(loc); + } + res->Cost = gLandPrice; + return res; + + case LandBuyRightSetting::BuyConstructionRights: // 2 + if ((surfaceElement->GetOwnership() & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0) + { // If the land or construction rights are already owned + return res; + } + + if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 + || (surfaceElement->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0) + { + return MakeResult(GA_ERROR::NOT_OWNED, _ErrorTitles[_setting], STR_CONSTRUCTION_RIGHTS_NOT_FOR_SALE); + } + + if (isExecuting) + { + surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16); + } + res->Cost = gConstructionRightsPrice; + return res; + + default: + log_warning("Tried calling buy land rights with an incorrect setting. setting = %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, _ErrorTitles[0], STR_NONE); + } + } +}; diff --git a/src/openrct2/actions/LandSetRightsAction.hpp b/src/openrct2/actions/LandSetRightsAction.hpp new file mode 100644 index 0000000000..392f353bdb --- /dev/null +++ b/src/openrct2/actions/LandSetRightsAction.hpp @@ -0,0 +1,231 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../OpenRCT2.h" +#include "../actions/LandSetHeightAction.hpp" +#include "../audio/audio.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/RideData.h" +#include "../windows/Intent.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" + +enum class LandSetRightSetting : uint8_t +{ + UnownLand, + UnownConstructionRights, + SetForSale, + SetConstructionRightsForSale, + SetOwnershipWithChecks, + Count +}; + +DEFINE_GAME_ACTION(LandSetRightsAction, GAME_COMMAND_SET_LAND_OWNERSHIP, GameActionResult) +{ +private: + MapRange _range; + uint8_t _setting = static_cast(LandSetRightSetting::Count); + uint8_t _ownership; + +public: + LandSetRightsAction() + { + } + LandSetRightsAction(MapRange range, LandSetRightSetting setting, uint8_t ownership = 0) + : _range(range) + , _setting(static_cast(setting)) + , _ownership(ownership) + { + } + + LandSetRightsAction(CoordsXY coord, LandSetRightSetting setting, uint8_t ownership = 0) + : _range(coord.x, coord.y, coord.x, coord.y) + , _setting(static_cast(setting)) + , _ownership(ownership) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::EDITOR_ONLY; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_range) << DS_TAG(_setting) << DS_TAG(_ownership); + } + + 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(); + + MapRange normRange = _range.Normalise(); + // Keep big coordinates within map boundaries + auto aX = std::max(32, normRange.GetLeft()); + auto bX = std::min(gMapSizeMaxXY, normRange.GetRight()); + auto aY = std::max(32, normRange.GetTop()); + auto bY = std::min(gMapSizeMaxXY, normRange.GetBottom()); + + MapRange validRange = MapRange{ aX, aY, bX, bY }; + + CoordsXYZ centre{ (validRange.GetLeft() + validRange.GetRight()) / 2 + 16, + (validRange.GetTop() + validRange.GetBottom()) / 2 + 16, 0 }; + centre.z = tile_element_height(centre.x, centre.y); + + res->Position = centre; + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; + + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) + { + return MakeResult(GA_ERROR::NOT_IN_EDITOR_MODE, STR_NONE, STR_LAND_NOT_FOR_SALE); + } + + // Game command modified to accept selection size + for (auto y = validRange.GetTop(); y <= validRange.GetBottom(); y += 32) + { + for (auto x = validRange.GetLeft(); x <= validRange.GetRight(); x += 32) + { + auto result = map_buy_land_rights_for_tile({ x, y }, isExecuting); + if (result->Error == GA_ERROR::OK) + { + res->Cost += result->Cost; + } + } + } + + if (isExecuting) + { + map_count_remaining_land_rights(); + audio_play_sound_at_location(SOUND_PLACE_ITEM, centre.x, centre.y, centre.z); + } + return res; + } + + GameActionResult::Ptr map_buy_land_rights_for_tile(const CoordsXY loc, bool isExecuting) const + { + SurfaceElement* surfaceElement = map_get_surface_element_at(loc)->AsSurface(); + if (surfaceElement == nullptr) + { + log_error("Could not find surface. x = %d, y = %d", loc.x, loc.y); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE, STR_NONE); + } + + auto res = MakeResult(); + switch (static_cast(_setting)) + { + case LandSetRightSetting::UnownLand: + if (isExecuting) + { + surfaceElement->SetOwnership( + surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); + update_park_fences_around_tile(loc); + } + return res; + case LandSetRightSetting::UnownConstructionRights: + if (isExecuting) + { + surfaceElement->SetOwnership(surfaceElement->GetOwnership() & ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16); + } + return res; + case LandSetRightSetting::SetForSale: + if (isExecuting) + { + surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_AVAILABLE); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16); + } + return res; + case LandSetRightSetting::SetConstructionRightsForSale: + if (isExecuting) + { + surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(loc.x, loc.y, baseHeight, baseHeight + 16); + } + return res; + case LandSetRightSetting::SetOwnershipWithChecks: + { + if (_ownership == surfaceElement->GetOwnership()) + { + return res; + } + + TileElement* tileElement = map_get_first_element_at(loc.x / 32, loc.y / 32); + do + { + if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) + continue; + + if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE) + continue; + + // Do not allow ownership of park entrance. + if (_ownership == OWNERSHIP_OWNED || _ownership == OWNERSHIP_AVAILABLE) + return res; + + // Allow construction rights available / for sale on park entrances on surface. + // There is no need to check the height if _ownership is 0 (unowned and no rights available). + if (_ownership == OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED + || _ownership == OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) + { + if (tileElement->base_height - 3 > surfaceElement->base_height + || tileElement->base_height < surfaceElement->base_height) + return res; + } + } while (!(tileElement++)->IsLastForTile()); + + res->Cost = gLandPrice; + if (isExecuting) + { + if (_ownership != OWNERSHIP_UNOWNED) + { + gPeepSpawns.erase( + std::remove_if( + gPeepSpawns.begin(), gPeepSpawns.end(), + [x = loc.x, y = loc.y](const auto& spawn) { + return floor2(spawn.x, 32) == x && floor2(spawn.y, 32) == y; + }), + gPeepSpawns.end()); + } + surfaceElement->SetOwnership(_ownership); + update_park_fences_around_tile(loc); + gMapLandRightsUpdateSuccess = true; + } + return res; + } + default: + log_warning("Tried calling set land rights with an incorrect setting. setting = %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE, STR_NONE); + } + } +}; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 762ed93d09..30bc3b0249 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -7,6 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "../actions/LandSetRightsAction.hpp" #include "../Cheats.h" #include "../Context.h" #include "../Game.h" @@ -1238,7 +1239,9 @@ static void footpath_fix_ownership(int32_t x, int32_t y) ownership = OWNERSHIP_UNOWNED; } - map_buy_land_rights(x, y, x, y, BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, (ownership << 4) | GAME_COMMAND_FLAG_APPLY); + auto landSetRightsAction = LandSetRightsAction({ x, y }, LandSetRightSetting::SetOwnershipWithChecks, ownership); + landSetRightsAction.SetFlags(GAME_COMMAND_FLAG_NO_SPEND); + GameActions::Execute(&landSetRightsAction); } static bool get_next_direction(int32_t edges, int32_t* direction) diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index e612c344a5..88d59b0a14 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -19,6 +19,7 @@ #include "../actions/LandLowerAction.hpp" #include "../actions/LandRaiseAction.hpp" #include "../actions/LandSetHeightAction.hpp" +#include "../actions/LandSetRightsAction.hpp" #include "../actions/LargeSceneryRemoveAction.hpp" #include "../actions/ParkEntranceRemoveAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" @@ -924,52 +925,6 @@ int32_t tile_element_get_corner_height(const TileElement* tileElement, int32_t d return map_get_corner_height(z, slope, direction); } -static money32 map_set_land_ownership(uint8_t flags, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t newOwnership) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - return 0; - - // Clamp to maximum addressable element to prevent long loop spamming the log - x1 = std::clamp(x1, 32, gMapSizeUnits - 32); - y1 = std::clamp(y1, 32, gMapSizeUnits - 32); - x2 = std::clamp(x2, 32, gMapSizeUnits - 32); - y2 = std::clamp(y2, 32, gMapSizeUnits - 32); - gMapLandRightsUpdateSuccess = false; - map_buy_land_rights(x1, y1, x2, y2, BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, flags | (newOwnership << 8)); - - if (!gMapLandRightsUpdateSuccess) - return 0; - - int16_t x = std::clamp(x1, 32, gMapSizeUnits - 32); - int16_t y = std::clamp(y1, 32, gMapSizeUnits - 32); - - x += 16; - y += 16; - - int16_t z = tile_element_height(x, y); - audio_play_sound_at_location(SOUND_PLACE_ITEM, x, y, z); - return 0; -} - -/** - * - * rct2: 0x006648E3 - */ -void game_command_set_land_ownership( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t flags = *ebx & 0xFF; - - *ebx = map_set_land_ownership(flags, *eax & 0xFFFF, *ecx & 0xFFFF, *edi & 0xFFFF, *ebp & 0xFFFF, *edx & 0xFF); - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - map_count_remaining_land_rights(); - } -} - uint8_t map_get_lowest_land_height(int32_t xMin, int32_t xMax, int32_t yMin, int32_t yMax) { xMin = std::max(xMin, 32); @@ -1648,7 +1603,13 @@ void map_remove_out_of_range_elements() { if (x == 0 || y == 0 || x >= mapMaxXY || y >= mapMaxXY) { - map_buy_land_rights(x, y, x, y, BUY_LAND_RIGHTS_FLAG_UNOWN_TILE, GAME_COMMAND_FLAG_APPLY); + // Note this purposely does not use LandSetRightsAction as X Y coordinates are outside of normal range. + auto surfaceElement = map_get_surface_element_at({ x, y }); + if (surfaceElement != nullptr) + { + surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); + update_park_fences_around_tile({ x, y }); + } clear_elements_at(x, y); } } diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index b8a6bb281d..8b00d2ba35 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -188,8 +188,6 @@ 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); money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t clear, int32_t flags); -void game_command_set_land_ownership( - 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( diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 39c17944df..06ae680b0c 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -203,213 +203,6 @@ void park_set_name(const char* name) } } -static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t setting, int32_t flags) -{ - SurfaceElement* surfaceElement = map_get_surface_element_at({ x, y })->AsSurface(); - if (surfaceElement == nullptr) - return MONEY32_UNDEFINED; - - switch (setting) - { - case BUY_LAND_RIGHTS_FLAG_BUY_LAND: // 0 - if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) != 0) - { // If the land is already owned - return 0; - } - - if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 - || (surfaceElement->GetOwnership() & OWNERSHIP_AVAILABLE) == 0) - { - gGameCommandErrorText = STR_LAND_NOT_FOR_SALE; - return MONEY32_UNDEFINED; - } - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership(OWNERSHIP_OWNED); - update_park_fences_around_tile({ x, y }); - } - return gLandPrice; - case BUY_LAND_RIGHTS_FLAG_UNOWN_TILE: // 1 - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership( - surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); - update_park_fences_around_tile({ x, y }); - } - return 0; - case BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS: // 2 - if ((surfaceElement->GetOwnership() & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0) - { // If the land or construction rights are already owned - return 0; - } - - if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 - || (surfaceElement->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0) - { - gGameCommandErrorText = STR_CONSTRUCTION_RIGHTS_NOT_FOR_SALE; - return MONEY32_UNDEFINED; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - return gConstructionRightsPrice; - case BUY_LAND_RIGHTS_FLAG_UNOWN_CONSTRUCTION_RIGHTS: // 3 - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership(surfaceElement->GetOwnership() & ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - return 0; - case BUY_LAND_RIGHTS_FLAG_SET_FOR_SALE: // 4 - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_AVAILABLE); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - return 0; - case BUY_LAND_RIGHTS_FLAG_SET_CONSTRUCTION_RIGHTS_FOR_SALE: // 5 - if (flags & GAME_COMMAND_FLAG_APPLY) - { - surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - return 0; - case BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS: - { - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) - { - return MONEY32_UNDEFINED; - } - - if (x <= 0 || y <= 0) - { - gGameCommandErrorText = STR_TOO_CLOSE_TO_EDGE_OF_MAP; - return MONEY32_UNDEFINED; - } - - if (x >= gMapSizeUnits || y >= gMapSizeUnits) - { - gGameCommandErrorText = STR_TOO_CLOSE_TO_EDGE_OF_MAP; - return MONEY32_UNDEFINED; - } - - uint8_t newOwnership = (flags & 0xFF00) >> 4; - if (newOwnership == surfaceElement->GetOwnership()) - { - return 0; - } - - TileElement* tileElement = map_get_first_element_at(x / 32, y / 32); - do - { - if (tileElement->GetType() == TILE_ELEMENT_TYPE_ENTRANCE - && tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_PARK_ENTRANCE) - { - // Do not allow ownership of park entrance. - if (newOwnership == OWNERSHIP_OWNED || newOwnership == OWNERSHIP_AVAILABLE) - return 0; - // Allow construction rights available / for sale on park entrances on surface. - // There is no need to check the height if newOwnership is 0 (unowned and no rights available). - if ((newOwnership == OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED - || newOwnership == OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) - && (tileElement->base_height - 3 > surfaceElement->base_height - || tileElement->base_height < surfaceElement->base_height)) - return 0; - } - } while (!(tileElement++)->IsLastForTile()); - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return gLandPrice; - } - - if ((newOwnership & 0xF0) != 0) - { - gPeepSpawns.erase( - std::remove_if( - gPeepSpawns.begin(), gPeepSpawns.end(), - [x, y](const auto& spawn) { return floor2(spawn.x, 32) == x && floor2(spawn.y, 32) == y; }), - gPeepSpawns.end()); - } - surfaceElement->SetOwnership(newOwnership); - update_park_fences_around_tile({ x, y }); - gMapLandRightsUpdateSuccess = true; - return 0; - } - default: - log_warning("Tried calling map_buy_land_rights_for_tile() with an incorrect setting!"); - assert(false); - return MONEY32_UNDEFINED; - } -} - -int32_t map_buy_land_rights(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t setting, int32_t flags) -{ - int32_t x, y, z; - money32 totalCost, cost; - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE; - - if (x1 == 0 && y1 == 0) - { - x1 = x0; - y1 = y0; - } - - x = (x0 + x1) / 2 + 16; - y = (y0 + y1) / 2 + 16; - z = tile_element_height(x, y); - gCommandPosition.x = x; - gCommandPosition.y = y; - gCommandPosition.z = z; - - // Game command modified to accept selection size - totalCost = 0; - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0 || game_is_not_paused() || gCheatsBuildInPauseMode) - { - for (y = y0; y <= y1; y += 32) - { - for (x = x0; x <= x1; x += 32) - { - cost = map_buy_land_rights_for_tile(x, y, setting, flags); - if (cost != MONEY32_UNDEFINED) - { - totalCost += cost; - } - } - } - } - - return totalCost; -} - -/** - * - * rct2: 0x006649BD - */ -void game_command_buy_land_rights( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t flags = *ebx & 0xFFFF; - - *ebx = map_buy_land_rights((*eax & 0xFFFF), (*ecx & 0xFFFF), (*edi & 0xFFFF), (*ebp & 0xFFFF), (*edx & 0x00FF), flags); - - // Too expensive to always call in map_buy_land_rights. - // It's already counted when the park is loaded, after - // that it should only be called for user actions. - if (flags & GAME_COMMAND_FLAG_APPLY) - { - map_count_remaining_land_rights(); - } -} - void set_forced_park_rating(int32_t rating) { _forcedParkRating = rating; diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index 4b7199ebf8..7d938d36e0 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -87,17 +87,6 @@ namespace OpenRCT2 }; } // namespace OpenRCT2 -enum -{ - BUY_LAND_RIGHTS_FLAG_BUY_LAND, - BUY_LAND_RIGHTS_FLAG_UNOWN_TILE, - BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS, - BUY_LAND_RIGHTS_FLAG_UNOWN_CONSTRUCTION_RIGHTS, - BUY_LAND_RIGHTS_FLAG_SET_FOR_SALE, - BUY_LAND_RIGHTS_FLAG_SET_CONSTRUCTION_RIGHTS_FOR_SALE, - BUY_LAND_RIGHTS_FLAG_SET_OWNERSHIP_WITH_CHECKS, // Used in scenario editor -}; - extern rct_string_id gParkName; extern uint32_t gParkNameArgs; extern uint32_t gParkFlags; @@ -137,12 +126,8 @@ int32_t park_entrance_get_index(int32_t x, int32_t y, int32_t z); void park_set_name(const char* name); void park_set_entrance_fee(money32 value); -int32_t map_buy_land_rights(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t setting, int32_t flags); - void game_command_set_park_entrance_fee( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_buy_land_rights( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money16 park_get_entrance_fee(); From a8ae81519c907cf4fe98152e85ece3208997c567 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 20 Mar 2019 20:33:06 +0100 Subject: [PATCH 370/506] Add LandBuyRightsAction.hpp to Xcode project. --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 19504974b2..8fecaa1f50 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -119,6 +119,7 @@ 9346F9DC208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; }; 9346F9DD208A191900C77D91 /* GuestPathfinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */; }; 937A92152242CDAA00B09278 /* LandSmoothAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */; }; + 937A92132242CCB300B09278 /* LandBuyRightsAction.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */; }; 939A359A20C12FC800630B3F /* Paint.Litter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359720C12FC700630B3F /* Paint.Litter.cpp */; }; 939A359B20C12FC800630B3F /* Paint.Misc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939A359820C12FC700630B3F /* Paint.Misc.cpp */; }; 939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 939A359920C12FC700630B3F /* Paint.Sprite.h */; }; @@ -1243,6 +1244,7 @@ 9350B52820B46E0900897BC5 /* ftrender.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftrender.h; sourceTree = ""; }; 9350B52920B46E0900897BC5 /* ft2build.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ft2build.h; sourceTree = ""; }; 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandSmoothAction.hpp; sourceTree = ""; }; + 937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LandBuyRightsAction.hpp; sourceTree = ""; }; 939A359720C12FC700630B3F /* Paint.Litter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Litter.cpp; sourceTree = ""; }; 939A359820C12FC700630B3F /* Paint.Misc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Paint.Misc.cpp; sourceTree = ""; }; 939A359920C12FC700630B3F /* Paint.Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Paint.Sprite.h; sourceTree = ""; }; @@ -2155,6 +2157,7 @@ C9C630BD2235A9C6009AD16E /* FootpathPlaceFromTrackAction.hpp */, C9C630BB2235A7F9009AD16E /* WaterLowerAction.hpp */, C9C630BC2235A7F9009AD16E /* WaterRaiseAction.hpp */, + 937A92122242CCB300B09278 /* LandBuyRightsAction.hpp */, C9C630BA2235A7E7009AD16E /* LandLowerAction.hpp */, C9C630B92235A7E7009AD16E /* LandRaiseAction.hpp */, 937A92142242CDAA00B09278 /* LandSmoothAction.hpp */, @@ -3535,6 +3538,7 @@ 2A43D2C02225B91A00E8F73B /* RideSetVehiclesAction.hpp in Headers */, 2ADE2F1C2244187B002598AF /* ParkSetNameAction.hpp in Headers */, 2AA050322209A8E300D3A922 /* StaffSetCostumeAction.hpp in Headers */, + 937A92132242CCB300B09278 /* LandBuyRightsAction.hpp in Headers */, 2A61CAF72229E5720095AD67 /* FootpathPlaceAction.hpp in Headers */, 2A43D2C22225B91A00E8F73B /* LoadOrQuitAction.hpp in Headers */, C62D838B1FD36D6F008C04F1 /* EditorObjectSelectionSession.h in Headers */, From b9a70d02a3a32a05e96af48e9d348935643af364 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 11 May 2019 14:11:34 +0100 Subject: [PATCH 371/506] Make suggested changes Implement suggestions Fix formatting --- src/openrct2-ui/windows/Map.cpp | 2 +- src/openrct2/Editor.cpp | 4 ++-- src/openrct2/actions/GameActionRegistration.cpp | 1 + src/openrct2/actions/LandBuyRightsAction.hpp | 5 ++--- src/openrct2/actions/LandSetRightsAction.hpp | 10 ++++++---- src/openrct2/world/Footpath.cpp | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 1d50f6c495..5a8fe57aab 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index f22d4036a4..6d3f97833e 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -16,6 +16,8 @@ #include "GameState.h" #include "OpenRCT2.h" #include "ParkImporter.h" +#include "actions/LandBuyRightsAction.hpp" +#include "actions/LandSetRightsAction.hpp" #include "audio/audio.h" #include "interface/Viewport.h" #include "localisation/Localisation.h" @@ -23,8 +25,6 @@ #include "management/NewsItem.h" #include "object/ObjectManager.h" #include "object/ObjectRepository.h" -#include "actions/LandBuyRightsAction.hpp" -#include "actions/LandSetRightsAction.hpp" #include "peep/Staff.h" #include "rct1/RCT1.h" #include "scenario/Scenario.h" diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index a4740bb520..990a303e72 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -137,6 +137,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/LandBuyRightsAction.hpp b/src/openrct2/actions/LandBuyRightsAction.hpp index 573821b266..0ac03002ad 100644 --- a/src/openrct2/actions/LandBuyRightsAction.hpp +++ b/src/openrct2/actions/LandBuyRightsAction.hpp @@ -41,9 +41,8 @@ private: constexpr static rct_string_id _ErrorTitles[] = { STR_CANT_BUY_LAND, STR_CANT_BUY_CONSTRUCTION_RIGHTS_HERE }; public: - LandBuyRightsAction() - { - } + LandBuyRightsAction() = default; + LandBuyRightsAction(MapRange range, LandBuyRightSetting setting) : _range(range) , _setting(static_cast(setting)) diff --git a/src/openrct2/actions/LandSetRightsAction.hpp b/src/openrct2/actions/LandSetRightsAction.hpp index 392f353bdb..533dfb775b 100644 --- a/src/openrct2/actions/LandSetRightsAction.hpp +++ b/src/openrct2/actions/LandSetRightsAction.hpp @@ -40,12 +40,11 @@ DEFINE_GAME_ACTION(LandSetRightsAction, GAME_COMMAND_SET_LAND_OWNERSHIP, GameAct private: MapRange _range; uint8_t _setting = static_cast(LandSetRightSetting::Count); - uint8_t _ownership; + uint8_t _ownership = 0; public: - LandSetRightsAction() - { - } + LandSetRightsAction() = default; + LandSetRightsAction(MapRange range, LandSetRightSetting setting, uint8_t ownership = 0) : _range(range) , _setting(static_cast(setting)) @@ -183,6 +182,9 @@ private: TileElement* tileElement = map_get_first_element_at(loc.x / 32, loc.y / 32); do { + if (tileElement == nullptr) + break; + if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) continue; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 30bc3b0249..b17302dc67 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -7,13 +7,13 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../actions/LandSetRightsAction.hpp" #include "../Cheats.h" #include "../Context.h" #include "../Game.h" #include "../OpenRCT2.h" #include "../actions/FootpathPlaceAction.hpp" #include "../actions/FootpathRemoveAction.hpp" +#include "../actions/LandSetRightsAction.hpp" #include "../core/Guard.hpp" #include "../localisation/Localisation.h" #include "../management/Finance.h" From 4de6071fb4a468c17b2ea028f446e950ac997edf Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 12 May 2019 19:03:03 +0100 Subject: [PATCH 372/506] 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 ac7f7a1807..4864e554d7 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,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 "27" +#define NETWORK_STREAM_VERSION "28" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 058475f445990b74323c1fcc8ea529ec6d11ec06 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 13 May 2019 04:00:25 +0000 Subject: [PATCH 373/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/en-US.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/language/en-US.txt b/data/language/en-US.txt index f09be14734..97cb8211d3 100644 --- a/data/language/en-US.txt +++ b/data/language/en-US.txt @@ -405,7 +405,7 @@ STR_1726 :Land not for sale! STR_1727 :Construction rights not for sale! STR_1728 :Can't buy construction rights here... STR_1729 :Land not owned by park! -STR_1730 :{RED}Closed - - + STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Build STR_1733 :Mode @@ -923,6 +923,7 @@ STR_6166 :{SMALLFONT}{BLACK}Synchronizes each frame displayed to the monitor' STR_6206 :Gray stucco STR_6212 :Gray sandstone STR_6274 :Can't set color scheme... +STR_6307 :Color scheme: {BLACK}{STRINGID} ############# # Scenarios # From 0ff19f071f44a0474b9f5dd60d9106488a3046aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 13 May 2019 21:34:58 +0200 Subject: [PATCH 374/506] Fix #9240: crash when passing directory instead of save file --- distribution/changelog.txt | 1 + src/openrct2/core/FileStream.hpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 69033cec49..151425bcb3 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -38,6 +38,7 @@ - Fix: [#9000] Show correct error message if not enough money available. - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. +- Fix: [#9240] Crash when passing directory instead of save file. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/core/FileStream.hpp b/src/openrct2/core/FileStream.hpp index ae33e05d7c..c2bc81c918 100644 --- a/src/openrct2/core/FileStream.hpp +++ b/src/openrct2/core/FileStream.hpp @@ -15,6 +15,9 @@ #include "String.hpp" #include +#ifndef _WIN32 +# include +#endif enum { @@ -73,7 +76,12 @@ public: free(pathW); free(modeW); #else - _file = fopen(path, mode); + struct stat fileStat; + // Only allow regular files to be opened as its possible to open directories. + if (stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) + { + _file = fopen(path, mode); + } #endif if (_file == nullptr) { From 2ea1fcc69d759fc81cb4837946f94951e1bd6020 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 13 May 2019 22:16:14 +0200 Subject: [PATCH 375/506] Remove unused declarations and functions --- src/openrct2/actions/TrackRemoveAction.hpp | 4 + src/openrct2/peep/Staff.h | 4 - src/openrct2/ride/Ride.h | 8 - src/openrct2/ride/Track.cpp | 318 --------------------- src/openrct2/ride/Track.h | 3 - src/openrct2/world/Footpath.h | 2 - src/openrct2/world/Map.h | 3 - 7 files changed, 4 insertions(+), 338 deletions(-) diff --git a/src/openrct2/actions/TrackRemoveAction.hpp b/src/openrct2/actions/TrackRemoveAction.hpp index 5ad20a6b4b..696fce916e 100644 --- a/src/openrct2/actions/TrackRemoveAction.hpp +++ b/src/openrct2/actions/TrackRemoveAction.hpp @@ -19,6 +19,10 @@ #include "../world/Surface.h" #include "GameAction.h" +/** + * + * rct2: 0x006C5B69 + */ DEFINE_GAME_ACTION(TrackRemoveAction, GAME_COMMAND_REMOVE_TRACK, GameActionResult) { private: diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 696c66c7d9..2685a68334 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -71,10 +71,6 @@ extern colour_t gStaffHandymanColour; extern colour_t gStaffMechanicColour; extern colour_t gStaffSecurityColour; -void game_command_hire_new_staff_member( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_callback_hire_new_staff_member( - 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_staff_name( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_pickup_staff( diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index e447717917..b2a4fbabae 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1098,8 +1098,6 @@ int32_t ride_get_random_colour_preset_index(uint8_t ride_type); money32 ride_get_common_price(Ride* forRide); rct_ride_name get_ride_naming(const uint8_t rideType, rct_ride_entry* rideEntry); void game_command_create_ride(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_callback_ride_construct_new( - int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp); void game_command_demolish_ride( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 ride_create_command(int32_t type, int32_t subType, int32_t flags, ride_id_t* outRideIndex, uint8_t* outRideColour); @@ -1167,12 +1165,6 @@ enum class RideSetSetting : uint8_t; money32 set_operating_setting(ride_id_t rideId, RideSetSetting setting, uint8_t value); money32 set_operating_setting_nested(ride_id_t rideId, RideSetSetting setting, uint8_t value, uint8_t flags); -void game_command_set_ride_vehicles( - 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_ride_entrance_or_exit( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - void sub_6CB945(Ride* ride); void sub_6C94D8(); diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index f0eac99893..6a9920433a 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -944,324 +944,6 @@ bool track_remove_station_element(int32_t x, int32_t y, int32_t z, int32_t direc return true; } -static money32 track_remove( - uint8_t type, uint8_t sequence, int16_t originX, int16_t originY, int16_t originZ, uint8_t rotation, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; - gCommandPosition.x = originX + 16; - gCommandPosition.y = originY + 16; - gCommandPosition.z = originZ; - int16_t trackpieceZ = originZ; - - switch (type) - { - case TRACK_ELEM_BEGIN_STATION: - case TRACK_ELEM_MIDDLE_STATION: - type = TRACK_ELEM_END_STATION; - break; - } - - if (!(flags & (1 << 3)) && game_is_paused() && !gCheatsBuildInPauseMode) - { - gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; - return MONEY32_UNDEFINED; - } - - bool found = false; - bool isGhost = flags & GAME_COMMAND_FLAG_GHOST; - TileElement* tileElement = map_get_first_element_at(originX / 32, originY / 32); - if (tileElement == nullptr) - { - log_warning("Invalid coordinates for track removal. x = %d, y = %d", originX, originY); - return MONEY32_UNDEFINED; - } - do - { - if (tileElement->base_height * 8 != originZ) - continue; - - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - - if ((tileElement->GetDirection()) != rotation) - continue; - - if (tileElement->AsTrack()->GetSequenceIndex() != sequence) - continue; - - if (tileElement->IsGhost() != isGhost) - continue; - - uint8_t track_type = tileElement->AsTrack()->GetTrackType(); - switch (track_type) - { - case TRACK_ELEM_BEGIN_STATION: - case TRACK_ELEM_MIDDLE_STATION: - track_type = TRACK_ELEM_END_STATION; - break; - } - - if (track_type != type) - continue; - - found = true; - break; - } while (!(tileElement++)->IsLastForTile()); - - if (!found) - { - return MONEY32_UNDEFINED; - } - - if (tileElement->AsTrack()->IsIndestructible()) - { - gGameCommandErrorText = STR_YOU_ARE_NOT_ALLOWED_TO_REMOVE_THIS_SECTION; - return MONEY32_UNDEFINED; - } - - ride_id_t rideIndex = tileElement->AsTrack()->GetRideIndex(); - type = tileElement->AsTrack()->GetTrackType(); - bool isLiftHill = tileElement->AsTrack()->HasChain(); - - Ride* ride = get_ride(rideIndex); - const rct_preview_track* trackBlock = get_track_def_from_ride(ride, type); - trackBlock += tileElement->AsTrack()->GetSequenceIndex(); - - uint8_t originDirection = tileElement->GetDirection(); - switch (originDirection) - { - case 0: - originX -= trackBlock->x; - originY -= trackBlock->y; - break; - case 1: - originX -= trackBlock->y; - originY += trackBlock->x; - break; - case 2: - originX += trackBlock->x; - originY += trackBlock->y; - break; - case 3: - originX += trackBlock->y; - originY -= trackBlock->x; - break; - } - - originZ -= trackBlock->z; - - money32 cost = 0; - - trackBlock = get_track_def_from_ride(ride, type); - for (; trackBlock->index != 255; trackBlock++) - { - int16_t x = originX, y = originY, z = originZ; - - switch (originDirection) - { - case 0: - x += trackBlock->x; - y += trackBlock->y; - break; - case 1: - x += trackBlock->y; - y -= trackBlock->x; - break; - case 2: - x -= trackBlock->x; - y -= trackBlock->y; - break; - case 3: - x -= trackBlock->y; - y += trackBlock->x; - break; - } - - z += trackBlock->z; - - map_invalidate_tile_full(x, y); - - trackpieceZ = z; - - found = false; - tileElement = map_get_first_element_at(x / 32, y / 32); - do - { - if (tileElement == nullptr) - break; - - if (tileElement->base_height != z / 8) - continue; - - if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - - if (tileElement->GetDirection() != rotation) - continue; - - if (tileElement->AsTrack()->GetSequenceIndex() != trackBlock->index) - continue; - - if (tileElement->AsTrack()->GetTrackType() != type) - continue; - - if (tileElement->IsGhost() != isGhost) - continue; - - found = true; - break; - } while (!(tileElement++)->IsLastForTile()); - - if (!found) - { - log_error("Track map element part not found!"); - return MONEY32_UNDEFINED; - } - - int32_t entranceDirections; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE)) - { - entranceDirections = FlatRideTrackSequenceProperties[type][0]; - } - else - { - entranceDirections = TrackSequenceProperties[type][0]; - } - - if (entranceDirections & TRACK_SEQUENCE_FLAG_ORIGIN && (tileElement->AsTrack()->GetSequenceIndex() == 0)) - { - if (!track_remove_station_element(x, y, z / 8, rotation, rideIndex, 0)) - { - return MONEY32_UNDEFINED; - } - } - - TileElement* surfaceElement = map_get_surface_element_at({ x, y }); - if (surfaceElement == nullptr) - { - return MONEY32_UNDEFINED; - } - - int8_t _support_height = tileElement->base_height - surfaceElement->base_height; - if (_support_height < 0) - { - _support_height = 10; - } - - cost += (_support_height / 2) * RideTrackCosts[ride->type].support_price; - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - continue; - - if (entranceDirections & (1 << 4) && (tileElement->AsTrack()->GetSequenceIndex() == 0)) - { - if (!track_remove_station_element(x, y, z / 8, rotation, rideIndex, GAME_COMMAND_FLAG_APPLY)) - { - return MONEY32_UNDEFINED; - } - } - - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_TRACK_MUST_BE_ON_WATER)) - { - surfaceElement->AsSurface()->SetHasTrackThatNeedsWater(false); - } - - invalidate_test_results(ride); - footpath_queue_chain_reset(); - if (!gCheatsDisableClearanceChecks || !(tileElement->IsGhost())) - { - footpath_remove_edges_at(x, y, tileElement); - } - tile_element_remove(tileElement); - sub_6CB945(ride); - if (!(flags & GAME_COMMAND_FLAG_GHOST)) - { - ride->UpdateMaxVehicles(); - } - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - switch (type) - { - case TRACK_ELEM_ON_RIDE_PHOTO: - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_ON_RIDE_PHOTO; - break; - case TRACK_ELEM_CABLE_LIFT_HILL: - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CABLE_LIFT_HILL_COMPONENT_USED; - break; - case TRACK_ELEM_BLOCK_BRAKES: - ride->num_block_brakes--; - if (ride->num_block_brakes == 0) - { - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_OPERATING; - ride->mode = RIDE_MODE_CONTINUOUS_CIRCUIT; - if (ride->type == RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER) - { - ride->mode = RIDE_MODE_POWERED_LAUNCH; - } - } - break; - } - - switch (type) - { - case TRACK_ELEM_25_DEG_UP_TO_FLAT: - case TRACK_ELEM_60_DEG_UP_TO_FLAT: - case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT: - case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT: - if (!isLiftHill) - break; - [[fallthrough]]; - case TRACK_ELEM_CABLE_LIFT_HILL: - ride->num_block_brakes--; - break; - } - } - - money32 price = RideTrackCosts[ride->type].track_price; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE)) - { - price *= FlatRideTrackPricing[type]; - } - else - { - price *= TrackPricing[type]; - } - price >>= 16; - price = (price + cost) / 2; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED) - price *= -7; - else - price *= -10; - - if (gGameCommandNestLevel == 1) - { - LocationXYZ16 coord; - coord.x = originX + 16; - coord.y = originY + 16; - coord.z = trackpieceZ; - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - if (gParkFlags & PARK_FLAGS_NO_MONEY) - return 0; - else - return price; -} - -/** - * - * rct2: 0x006C5B69 - */ -void game_command_remove_track( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - *ebx = track_remove( - *edx & 0xFF, (*edx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edi & 0xFFFF, (*ebx >> 8) & 0xFF, *ebx & 0xFF); -} - void track_circuit_iterator_begin(track_circuit_iterator* it, CoordsXYE first) { it->last = first; diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 1ecbaabc4e..5bed1870b5 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -547,9 +547,6 @@ int32_t track_get_actual_bank_3(rct_vehicle* vehicle, TileElement* tileElement); bool track_add_station_element(int32_t x, int32_t y, int32_t z, int32_t direction, ride_id_t rideIndex, int32_t flags); bool track_remove_station_element(int32_t x, int32_t y, int32_t z, int32_t direction, ride_id_t rideIndex, int32_t flags); -void game_command_remove_track( - 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_maze_track( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 maze_set_track( diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 8cd5f1967d..0feee82a0b 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -176,8 +176,6 @@ TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z); struct PathElement; PathElement* map_get_footpath_element_slope(int32_t x, int32_t y, int32_t z, int32_t slope); void footpath_interrupt_peeps(int32_t x, int32_t y, int32_t z); -void game_command_remove_footpath( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 footpath_remove(int32_t x, int32_t y, int32_t z, int32_t flags); money32 footpath_provisional_set(int32_t type, int32_t x, int32_t y, int32_t z, int32_t slope); void footpath_provisional_remove(); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 8b00d2ba35..5ea4bbfb77 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -186,12 +186,9 @@ bool map_can_construct_with_clear_at( int32_t map_can_construct_at(int32_t x, int32_t y, int32_t zLow, int32_t zHigh, QuarterTile bl); 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); -money32 map_clear_scenery(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t clear, int32_t flags); 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( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); 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 From 170307cd0f30d07ac656fec2cf383719e9cedf20 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 13 May 2019 22:16:30 +0200 Subject: [PATCH 376/506] Remove redundant semicolons after for loops --- src/openrct2/paint/sprite/Paint.Peep.cpp | 2 +- src/openrct2/paint/tile_element/Paint.Entrance.cpp | 2 +- src/openrct2/ride/thrill/RotoDrop.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2/paint/sprite/Paint.Peep.cpp b/src/openrct2/paint/sprite/Paint.Peep.cpp index 69d33e5d4a..ffac5bf987 100644 --- a/src/openrct2/paint/sprite/Paint.Peep.cpp +++ b/src/openrct2/paint/sprite/Paint.Peep.cpp @@ -48,7 +48,7 @@ void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection break; default: return; - }; + } lightfx_add_3d_light( peep->sprite_index, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, peep_x, peep_y, peep_z, LIGHTFX_LIGHT_TYPE_SPOT_1); diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 23774ce176..9ea0ed6093 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -63,7 +63,7 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, lightfx_add_3d_light_magic_from_drawing_tile( session->MapPosition, 0, 16, height + 16, LIGHTFX_LIGHT_TYPE_LANTERN_2); break; - }; + } } #endif diff --git a/src/openrct2/ride/thrill/RotoDrop.cpp b/src/openrct2/ride/thrill/RotoDrop.cpp index 8caa763862..2c07534575 100644 --- a/src/openrct2/ride/thrill/RotoDrop.cpp +++ b/src/openrct2/ride/thrill/RotoDrop.cpp @@ -78,7 +78,7 @@ void vehicle_visual_roto_drop( image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_1(riding_peep_sprites[i]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } - }; + } assert(vehicleEntry->effect_visual == 1); // Although called in original code, effect_visual (splash effects) are not used for many rides and does not make sense so From 8d9645a3820a3ff7182525289bd41bae31213786 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 13 May 2019 22:22:14 +0200 Subject: [PATCH 377/506] Remove comment --- src/openrct2/actions/TrackRemoveAction.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/openrct2/actions/TrackRemoveAction.hpp b/src/openrct2/actions/TrackRemoveAction.hpp index 696fce916e..5ad20a6b4b 100644 --- a/src/openrct2/actions/TrackRemoveAction.hpp +++ b/src/openrct2/actions/TrackRemoveAction.hpp @@ -19,10 +19,6 @@ #include "../world/Surface.h" #include "GameAction.h" -/** - * - * rct2: 0x006C5B69 - */ DEFINE_GAME_ACTION(TrackRemoveAction, GAME_COMMAND_REMOVE_TRACK, GameActionResult) { private: From 4e23c42d38999408fbe62ac6c4040ea67a30ef31 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 13 May 2019 22:51:41 +0200 Subject: [PATCH 378/506] Remove stub functions from new_game_command_table[] --- src/openrct2/Game.cpp | 40 +++++------ src/openrct2/actions/GameActionCompat.cpp | 85 ----------------------- src/openrct2/peep/Peep.h | 2 - src/openrct2/peep/Staff.h | 2 - src/openrct2/ride/Ride.h | 7 -- src/openrct2/ride/Track.h | 2 - src/openrct2/world/Map.h | 2 - 7 files changed, 20 insertions(+), 120 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 4fae71dd06..7a45d61cc6 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1161,24 +1161,6 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_create_ride, - game_command_demolish_ride, - game_command_set_ride_status, - nullptr, - game_command_set_ride_name, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - game_command_set_guest_name, - game_command_set_staff_name, nullptr, nullptr, nullptr, @@ -1192,9 +1174,27 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_place_park_entrance, nullptr, - game_command_set_maze_track, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, game_command_set_park_entrance_fee, nullptr, nullptr, diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index 7d71693de3..4f64632808 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -35,17 +35,6 @@ money32 place_park_entrance(int16_t x, int16_t y, int16_t z, uint8_t direction) } } -/** - * - * rct2: 0x006666E7 - */ -void game_command_place_park_entrance( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_PLACE_PARK_ENTRANCE DEPRECATED"); -} - /** * * rct2: 0x00666F4E @@ -135,17 +124,6 @@ money32 ride_create_command(int32_t type, int32_t subType, int32_t flags, ride_i return res->Cost; } -/** - * - * rct2: 0x006B3F0F - */ -void game_command_create_ride( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_CREATE_RIDE DEPRECATED"); -} - #pragma endregion #pragma region RideSetStatusAction @@ -156,17 +134,6 @@ void ride_set_status(Ride* ride, int32_t status) GameActions::Execute(&gameAction); } -/** - * - * rct2: 0x006B4EA6 - */ -void game_command_set_ride_status( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_SET_RIDE_STATUS DEPRECATED"); -} - #pragma endregion #pragma region RideSetNameAction @@ -176,17 +143,6 @@ void ride_set_name(Ride* ride, const char* name, uint32_t flags) gameAction.SetFlags(flags); GameActions::Execute(&gameAction); } - -/** - * - * rct2: 0x006B578B - */ -void game_command_set_ride_name( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_SET_RIDE_NAME DEPRECATED"); -} #pragma endregion #pragma region RideModifyAction @@ -197,17 +153,6 @@ void ride_action_modify(Ride* ride, int32_t modifyType, int32_t flags) GameActions::Execute(&gameAction); } - -/** - * - * rct2: 0x006B49D9 - */ -void game_command_demolish_ride( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_DEMOLISH_RIDE DEPRECATED"); -} #pragma endregion #pragma region GuestSetName @@ -217,18 +162,6 @@ void guest_set_name(uint16_t spriteIndex, const char* name) auto gameAction = GuestSetNameAction(spriteIndex, name); GameActions::Execute(&gameAction); } - -/** - * - * rct2: 0x00698D6C - */ -void game_command_set_guest_name( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_SET_GUEST_NAME DEPRECATED"); -} - #pragma endregion #pragma region StaffSetName @@ -238,13 +171,6 @@ void staff_set_name(uint16_t spriteIndex, const char* name) auto gameAction = StaffSetNameAction(spriteIndex, name); GameActions::Execute(&gameAction); } - -void game_command_set_staff_name( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_SET_STAFF_NAME DEPRECATED"); -} #pragma endregion #pragma region PlacePeepSpawn @@ -283,15 +209,4 @@ money32 maze_set_track( return res->Cost; } - -/** - * - * rct2: 0x006CD8CE - */ -void game_command_set_maze_track( - [[maybe_unused]] int32_t* eax, [[maybe_unused]] int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, - [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - Guard::Assert(false, "GAME_COMMAND_SET_MAZE_TRACK DEPRECATED"); -} #pragma endregion diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index ad23880ec5..439d2a4cff 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -976,8 +976,6 @@ void peep_update_names(bool realNames); void guest_set_name(uint16_t spriteIndex, const char* name); void peep_handle_easteregg_name(Peep* peep); -void game_command_set_guest_name( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep); void peep_reset_pathfind_goal(Peep* peep); diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 2685a68334..05c214797d 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -71,8 +71,6 @@ extern colour_t gStaffHandymanColour; extern colour_t gStaffMechanicColour; extern colour_t gStaffSecurityColour; -void game_command_set_staff_name( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_pickup_staff( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index b2a4fbabae..34bbbc86c3 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1088,18 +1088,11 @@ void ride_prepare_breakdown(Ride* ride, int32_t breakdownReason); TileElement* ride_get_station_start_track_element(Ride* ride, int32_t stationIndex); TileElement* ride_get_station_exit_element(int32_t x, int32_t y, int32_t z); void ride_set_status(Ride* ride, int32_t status); -void game_command_set_ride_status( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void ride_set_name(Ride* ride, const char* name, uint32_t flags); -void game_command_set_ride_name( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); int32_t ride_get_refund_price(const Ride* ride); int32_t ride_get_random_colour_preset_index(uint8_t ride_type); money32 ride_get_common_price(Ride* forRide); rct_ride_name get_ride_naming(const uint8_t rideType, rct_ride_entry* rideEntry); -void game_command_create_ride(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_demolish_ride( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 ride_create_command(int32_t type, int32_t subType, int32_t flags, ride_id_t* outRideIndex, uint8_t* outRideColour); void ride_set_name_to_default(Ride* ride, rct_ride_entry* rideEntry); diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 5bed1870b5..f24e71a354 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -547,8 +547,6 @@ int32_t track_get_actual_bank_3(rct_vehicle* vehicle, TileElement* tileElement); bool track_add_station_element(int32_t x, int32_t y, int32_t z, int32_t direction, ride_id_t rideIndex, int32_t flags); bool track_remove_station_element(int32_t x, int32_t y, int32_t z, int32_t direction, ride_id_t rideIndex, int32_t flags); -void game_command_set_maze_track( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); money32 maze_set_track( uint16_t x, uint16_t y, uint16_t z, uint8_t flags, bool initialPlacement, uint8_t direction, ride_id_t rideIndex, uint8_t mode); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 5ea4bbfb77..b50068d3cd 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_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_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 From 5e39640837682f553f64f081d63c0c46eb5eabcd Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 14 May 2019 18:39:14 +0200 Subject: [PATCH 379/506] Also remove game_command_set_park_entrance_fee from new_game_command_table --- src/openrct2/Game.cpp | 2 +- src/openrct2/actions/GameActionCompat.cpp | 9 --------- src/openrct2/world/Park.h | 4 ---- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 7a45d61cc6..cb7f865879 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1195,7 +1195,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_park_entrance_fee, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index 4f64632808..9002b26a38 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -65,15 +65,6 @@ void park_set_entrance_fee(money32 fee) auto gameAction = SetParkEntranceFeeAction((money16)fee); GameActions::Execute(&gameAction); } - -void game_command_set_park_entrance_fee( - [[maybe_unused]] int* eax, [[maybe_unused]] int* ebx, [[maybe_unused]] int* ecx, [[maybe_unused]] int* edx, - [[maybe_unused]] int* esi, int* edi, [[maybe_unused]] int* ebp) -{ - money16 fee = (money16)(*edi & 0xFFFF); - auto gameAction = SetParkEntranceFeeAction(fee); - GameActions::Execute(&gameAction); -} #pragma endregion #pragma region RideCreateAction diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index 7d938d36e0..64e68cc679 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -125,10 +125,6 @@ void park_set_open(bool open); int32_t park_entrance_get_index(int32_t x, int32_t y, int32_t z); void park_set_name(const char* name); void park_set_entrance_fee(money32 value); - -void game_command_set_park_entrance_fee( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - money16 park_get_entrance_fee(); bool park_ride_prices_unlocked(); From 4dc77bf121e88d8786a107ac49e1fdd40566a875 Mon Sep 17 00:00:00 2001 From: joshtucker132 <46719255+joshtucker132@users.noreply.github.com> Date: Tue, 14 May 2019 15:38:31 -0400 Subject: [PATCH 380/506] Feature #8791: Improved tile element flag manipulation in Tile Inspector --- data/language/en-GB.txt | 3 + distribution/changelog.txt | 1 + src/openrct2-ui/windows/TileInspector.cpp | 100 +++++++++++++++------- src/openrct2/localisation/StringIds.h | 3 + src/openrct2/world/Map.cpp | 21 +++++ src/openrct2/world/TileInspector.cpp | 73 ++++++++++++++++ src/openrct2/world/TileInspector.h | 7 ++ 7 files changed, 175 insertions(+), 33 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 2eeb90605d..0f82efe2c3 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3766,6 +3766,9 @@ STR_6315 :{WINDOW_COLOUR_2}Pathfind Goal: {BLACK}{INT32}, {INT32}, {INT32} di STR_6316 :{WINDOW_COLOUR_2}Pathfind history: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} STR_6318 :Network desync detected.{NEWLINE}Log file: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Block Brake Closed +STR_6320 :{WINDOW_COLOUR_2}Indestructible +STR_6321 :{WINDOW_COLOUR_2}Addition is broken ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 151425bcb3..989bc5daca 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Feature: [#8558] Guest debugging tab. - Feature: [#8659] Banner and sign texts are now shown in tooltips. - Feature: [#8687] New multiplayer toolbar icon showing network status with reconnect option. +- Feature: [#8791] Improved tile element flag manipulation in Tile Inspector. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Feature: [#9154] Change map toolbar icon with current viewport rotation. diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 1b1ebbbc09..69b79b6755 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -110,7 +110,6 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_COLUMN_BASEHEIGHT, WIDX_COLUMN_CLEARANCEHEIGHT, WIDX_COLUMN_GHOSTFLAG, - WIDX_COLUMN_BROKENFLAG, WIDX_COLUMN_LASTFLAG, WIDX_GROUPBOX_DETAILS, WIDX_GROUPBOX_PROPERTIES, @@ -133,6 +132,7 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_PATH_SPINNER_HEIGHT = PAGE_WIDGETS, WIDX_PATH_SPINNER_HEIGHT_INCREASE, WIDX_PATH_SPINNER_HEIGHT_DECREASE, + WIDX_PATH_CHECK_BROKEN, WIDX_PATH_CHECK_SLOPED, WIDX_PATH_CHECK_EDGE_NE, // Note: This is NOT named after the world orientation, but after the way WIDX_PATH_CHECK_EDGE_E, // it looks in the window (top corner is north). Their order is important, @@ -149,6 +149,8 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_TRACK_SPINNER_HEIGHT_INCREASE, WIDX_TRACK_SPINNER_HEIGHT_DECREASE, WIDX_TRACK_CHECK_CHAIN_LIFT, + WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED, + WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE, // Scenery WIDX_SCENERY_SPINNER_HEIGHT = PAGE_WIDGETS, @@ -214,11 +216,10 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { // Column offsets for the table headers #define COL_X_TYPE 3 // Type -#define COL_X_BH (COL_X_TYPE + 300) // Base height +#define COL_X_BH (COL_X_TYPE + 312) // Base height #define COL_X_CH (COL_X_BH + 20) // Clearance height #define COL_X_GF (COL_X_CH + 20) // Ghost flag -#define COL_X_BF (COL_X_GF + 12) // Broken flag -#define COL_X_LF (COL_X_BF + 12) // Last for tile flag +#define COL_X_LF (COL_X_GF + 12) // Last for tile flag #define PADDING_BOTTOM 15 #define GROUPBOX_PADDING 6 @@ -263,8 +264,7 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { { WWT_TABLE_HEADER, 1, COL_X_TYPE, COL_X_BH - 1, 42, 42 + 13, STR_NONE, STR_NONE }, /* Type */ \ { WWT_TABLE_HEADER, 1, COL_X_BH, COL_X_CH - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_BASE_HEIGHT }, /* Base height */ \ { WWT_TABLE_HEADER, 1, COL_X_CH, COL_X_GF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_CLEARANCE_HEIGHT }, /* Clearance height */ \ - { WWT_TABLE_HEADER, 1, COL_X_GF, COL_X_BF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_GHOST }, /* Ghost flag */ \ - { WWT_TABLE_HEADER, 1, COL_X_BF, COL_X_LF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_BROKEN }, /* Broken flag */ \ + { WWT_TABLE_HEADER, 1, COL_X_GF, COL_X_LF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_GHOST }, /* Ghost flag */ \ { WWT_TABLE_HEADER, 1, COL_X_LF, WW - 3, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_LAST }, /* Last of tile flag */ \ { WWT_GROUPBOX, 1, 6, WW - 6, -1, -1, STR_NONE, STR_NONE }, /* Details group box */ \ { WWT_GROUPBOX, 1, 6, WW - 6, -1, -1, STR_TILE_INSPECTOR_GROUPBOX_PROPERTIES, STR_NONE } /* Properties group box */ @@ -293,13 +293,14 @@ static rct_widget SurfaceWidgets[] = { }; #define PAT_GBPB PADDING_BOTTOM // Path group box properties bottom -#define PAT_GBPT (PAT_GBPB + 16 + 4 * 21) // Path group box properties top +#define PAT_GBPT (PAT_GBPB + 16 + 5 * 21) // Path group box properties top #define PAT_GBDB (PAT_GBPT + GROUPBOX_PADDING) // Path group box info bottom #define PAT_GBDT (PAT_GBDB + 20 + 2 * 11) // Path group box info top static rct_widget PathWidgets[] = { MAIN_TILE_INSPECTOR_WIDGETS, SPINNER_WIDGETS (1, GBBL(1), GBBR(1), GBBT(WH - PAT_GBPT, 0) + 3, GBBB(WH - PAT_GBPT, 0) - 3, STR_NONE, STR_NONE), // WIDX_PATH_SPINNER_HEIGHT{,_INCREASE,_DECREASE} - { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 1), STR_TILE_INSPECTOR_PATH_SLOPED, STR_NONE }, // WIDX_PATH_CHECK_SLOPED + { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 1), STR_TILE_INSPECTOR_PATH_BROKEN, STR_NONE }, // WIDX_PATH_CHECK_BROKEN + { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 2), STR_TILE_INSPECTOR_PATH_SLOPED, STR_NONE }, // WIDX_PATH_CHECK_SLOPED { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 3, GBBT(WH - PAT_GBPT, 2) + 7 * 1), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_NE { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 4, GBBT(WH - PAT_GBPT, 2) + 7 * 2), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_E { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 3, GBBT(WH - PAT_GBPT, 2) + 7 * 3), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_SE @@ -312,7 +313,7 @@ static rct_widget PathWidgets[] = { }; #define TRA_GBPB PADDING_BOTTOM // Track group box properties bottom -#define TRA_GBPT (TRA_GBPB + 16 + 3 * 21) // Track group box properties top +#define TRA_GBPT (TRA_GBPB + 16 + 5 * 21) // Track group box properties top #define TRA_GBDB (TRA_GBPT + GROUPBOX_PADDING) // Track group box info bottom #define TRA_GBDT (TRA_GBDB + 20 + 7 * 11) // Track group box info top static rct_widget TrackWidgets[] = { @@ -320,6 +321,8 @@ static rct_widget TrackWidgets[] = { { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 0), STR_TILE_INSPECTOR_TRACK_ENTIRE_TRACK_PIECE, STR_NONE }, // WIDX_TRACK_CHECK_APPLY_TO_ALL SPINNER_WIDGETS (1, GBBL(1), GBBR(1), GBBT(WH - TRA_GBPT, 1) + 3, GBBB(WH - TRA_GBPT, 1) - 3, STR_NONE, STR_NONE), // WIDX_TRACK_SPINNER_HEIGHT{,_INCREASE,_DECREASE} { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 2), STR_TILE_INSPECTOR_TRACK_CHAIN_LIFT, STR_NONE }, // WIDX_TRACK_CHECK_CHAIN_LIFT + { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 3), STR_TILE_INSPECTOR_TRACK_BLOCK_BRAKE, STR_NONE }, // WIDX_PATH_CHECK_BLOCK_BRAKE_CLOSED + { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 4), STR_TILE_INSPECTOR_TRACK_IS_INDESTRUCTIBLE, STR_NONE }, // WIDX_PATH_CHECK_IS_INDESTRUCTIBLE { WIDGETS_END }, }; @@ -501,8 +504,8 @@ static rct_window_event_list TileInspectorWindowEvents = { static uint64_t PageEnabledWidgets[] = { (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_SURFACE_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_SURFACE_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_SURFACE_BUTTON_REMOVE_FENCES) | (1ULL << WIDX_SURFACE_BUTTON_RESTORE_FENCES) | (1ULL << WIDX_SURFACE_CHECK_CORNER_N) | (1ULL << WIDX_SURFACE_CHECK_CORNER_E) | (1ULL << WIDX_SURFACE_CHECK_CORNER_S) | (1ULL << WIDX_SURFACE_CHECK_CORNER_W) | (1ULL << WIDX_SURFACE_CHECK_DIAGONAL), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_PATH_CHECK_SLOPED) | (1ULL << WIDX_PATH_CHECK_EDGE_N) | (1ULL << WIDX_PATH_CHECK_EDGE_NE) | (1ULL << WIDX_PATH_CHECK_EDGE_E) | (1ULL << WIDX_PATH_CHECK_EDGE_SE) | (1ULL << WIDX_PATH_CHECK_EDGE_S) | (1ULL << WIDX_PATH_CHECK_EDGE_SW) | (1ULL << WIDX_PATH_CHECK_EDGE_W) | (1ULL << WIDX_PATH_CHECK_EDGE_NW), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_TRACK_CHECK_APPLY_TO_ALL) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_TRACK_CHECK_CHAIN_LIFT), + (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_PATH_CHECK_SLOPED) | (1ULL << WIDX_PATH_CHECK_BROKEN) | (1ULL << WIDX_PATH_CHECK_EDGE_N) | (1ULL << WIDX_PATH_CHECK_EDGE_NE) | (1ULL << WIDX_PATH_CHECK_EDGE_E) | (1ULL << WIDX_PATH_CHECK_EDGE_SE) | (1ULL << WIDX_PATH_CHECK_EDGE_S) | (1ULL << WIDX_PATH_CHECK_EDGE_SW) | (1ULL << WIDX_PATH_CHECK_EDGE_W) | (1ULL << WIDX_PATH_CHECK_EDGE_NW), + (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_TRACK_CHECK_APPLY_TO_ALL) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_TRACK_CHECK_CHAIN_LIFT) | (1ULL << WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED) | (1ULL << WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_SCENERY_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_SCENERY_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_N) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_E) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_S) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_W) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_N) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_E) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_S) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_W), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_ENTRANCE_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_ENTRANCE_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_ENTRANCE_BUTTON_MAKE_USABLE), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_WALL_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_WALL_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_WALL_DROPDOWN_SLOPE) | (1ULL << WIDX_WALL_DROPDOWN_SLOPE_BUTTON), @@ -710,6 +713,13 @@ static void window_tile_inspector_path_set_sloped(int32_t elementIndex, bool slo elementIndex, GAME_COMMAND_MODIFY_TILE, sloped, 0); } +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); +} + static void window_tile_inspector_path_toggle_edge(int32_t elementIndex, int32_t cornerIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); @@ -751,6 +761,21 @@ static void window_tile_inspector_track_block_set_lift(int32_t elementIndex, boo elementIndex, GAME_COMMAND_MODIFY_TILE, entireTrackBlock, chain); } +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); +} + +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); +} + 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 @@ -867,6 +892,9 @@ static void window_tile_inspector_mouseup(rct_window* w, rct_widgetindex widgetI case WIDX_PATH_CHECK_SLOPED: window_tile_inspector_path_set_sloped(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsSloped()); break; + case WIDX_PATH_CHECK_BROKEN: + window_tile_inspector_path_set_broken(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsBroken()); + break; case WIDX_PATH_CHECK_EDGE_E: case WIDX_PATH_CHECK_EDGE_S: case WIDX_PATH_CHECK_EDGE_W: @@ -910,6 +938,14 @@ static void window_tile_inspector_mouseup(rct_window* w, rct_widgetindex widgetI window_tile_inspector_track_block_set_lift(windowTileInspectorSelectedIndex, entireTrackBlock, newLift); break; } + case WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED: + window_tile_inspector_track_set_block_brake( + windowTileInspectorSelectedIndex, !tileElement->AsTrack()->BlockBrakeClosed()); + break; + case WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE: + window_tile_inspector_track_set_indestructible( + windowTileInspectorSelectedIndex, !tileElement->AsTrack()->IsIndestructible()); + break; } // switch widget index break; @@ -1495,25 +1531,28 @@ static void window_tile_inspector_invalidate(rct_window* w) w->widgets[WIDX_PATH_SPINNER_HEIGHT_INCREASE].bottom = GBBB(propertiesAnchor, 0) - 4; w->widgets[WIDX_PATH_SPINNER_HEIGHT_DECREASE].top = GBBT(propertiesAnchor, 0) + 4; w->widgets[WIDX_PATH_SPINNER_HEIGHT_DECREASE].bottom = GBBB(propertiesAnchor, 0) - 4; - w->widgets[WIDX_PATH_CHECK_SLOPED].top = GBBT(propertiesAnchor, 1) + 2; - w->widgets[WIDX_PATH_CHECK_SLOPED].bottom = GBBT(propertiesAnchor, 1) + 15; - w->widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 2) + 7 * 0; + w->widgets[WIDX_PATH_CHECK_BROKEN].top = GBBT(propertiesAnchor, 1); + w->widgets[WIDX_PATH_CHECK_BROKEN].bottom = GBBB(propertiesAnchor, 1); + w->widgets[WIDX_PATH_CHECK_SLOPED].top = GBBT(propertiesAnchor, 2); + w->widgets[WIDX_PATH_CHECK_SLOPED].bottom = GBBB(propertiesAnchor, 2); + w->widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 3) + 7 * 0; w->widgets[WIDX_PATH_CHECK_EDGE_N].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_N].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 2) + 7 * 1; + w->widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 3) + 7 * 1; w->widgets[WIDX_PATH_CHECK_EDGE_NE].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_NE].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 2) + 7 * 2; + w->widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 3) + 7 * 2; w->widgets[WIDX_PATH_CHECK_EDGE_E].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_E].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 2) + 7 * 3; + w->widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 3) + 7 * 3; w->widgets[WIDX_PATH_CHECK_EDGE_SE].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_SE].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 2) + 7 * 4; + w->widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 3) + 7 * 4; w->widgets[WIDX_PATH_CHECK_EDGE_S].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_S].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 2) + 7 * 3; + w->widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 3) + 7 * 3; w->widgets[WIDX_PATH_CHECK_EDGE_SW].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_SW].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 2) + 7 * 2; + w->widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 3) + 7 * 2; w->widgets[WIDX_PATH_CHECK_EDGE_W].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_W].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 2) + 7 * 1; + w->widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 3) + 7 * 1; w->widgets[WIDX_PATH_CHECK_EDGE_NW].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_NW].top + 13; widget_set_checkbox_value(w, WIDX_PATH_CHECK_SLOPED, tileElement->AsPath()->IsSloped()); + widget_set_checkbox_value(w, WIDX_PATH_CHECK_BROKEN, tileElement->AsPath()->IsBroken()); widget_set_checkbox_value( w, WIDX_PATH_CHECK_EDGE_NE, tileElement->AsPath()->GetEdges() & (1 << ((0 - get_current_rotation()) & 3))); widget_set_checkbox_value( @@ -1542,8 +1581,14 @@ static void window_tile_inspector_invalidate(rct_window* w) w->widgets[WIDX_TRACK_SPINNER_HEIGHT_DECREASE].bottom = GBBB(propertiesAnchor, 1) - 4; w->widgets[WIDX_TRACK_CHECK_CHAIN_LIFT].top = GBBT(propertiesAnchor, 2); w->widgets[WIDX_TRACK_CHECK_CHAIN_LIFT].bottom = GBBB(propertiesAnchor, 2); + w->widgets[WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED].top = GBBT(propertiesAnchor, 3); + w->widgets[WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED].bottom = GBBB(propertiesAnchor, 3); + w->widgets[WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE].top = GBBT(propertiesAnchor, 4); + w->widgets[WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE].bottom = GBBB(propertiesAnchor, 4); widget_set_checkbox_value(w, WIDX_TRACK_CHECK_APPLY_TO_ALL, windowTileInspectorApplyToAll); widget_set_checkbox_value(w, WIDX_TRACK_CHECK_CHAIN_LIFT, tileElement->AsTrack()->HasChain()); + widget_set_checkbox_value(w, WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED, tileElement->AsTrack()->BlockBrakeClosed()); + widget_set_checkbox_value(w, WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE, tileElement->AsTrack()->IsIndestructible()); break; case TILE_INSPECTOR_PAGE_SCENERY: { @@ -1711,12 +1756,6 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) dpi, STR_TILE_INSPECTOR_FLAG_GHOST_SHORT, gCommonFormatArgs, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left); } - if ((widget = &w->widgets[WIDX_COLUMN_BROKENFLAG])->type != WWT_EMPTY) - { - gfx_draw_string_left_clipped( - dpi, STR_TILE_INSPECTOR_FLAG_BROKEN_SHORT, gCommonFormatArgs, w->colours[1], w->x + widget->left + 1, - w->y + widget->top + 1, widget->right - widget->left); - } if ((widget = &w->widgets[WIDX_COLUMN_LASTFLAG])->type != WWT_EMPTY) { gfx_draw_string_left_clipped( @@ -2200,7 +2239,6 @@ static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* const int32_t baseHeight = tileElement->base_height; const int32_t clearanceHeight = tileElement->clearance_height; const bool ghost = tileElement->IsGhost(); - const bool broken = tileElement->AsPath() == nullptr ? false : tileElement->AsPath()->IsBroken(); const bool last = tileElement->IsLastForTile(); const rct_string_id stringFormat = (selectedRow || hoveredRow) ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID; @@ -2222,17 +2260,13 @@ static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* set_format_arg(2, int32_t, clearanceHeight); gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_CH, y); - // Checkmarks for ghost, broken en last for tile + // Checkmarks for ghost and last for tile set_format_arg(0, rct_string_id, STR_STRING); set_format_arg(2, char*, CheckBoxMarkString); if (ghost) { gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_GF, y); } - if (broken) - { - gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_BF, y); - } if (last) { gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_LF, y); diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 9764813223..d0fa8b27ca 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3939,6 +3939,9 @@ enum STR_MULTITHREADING_TIP = 6306, STR_TILE_INSPECTOR_COLOUR_SCHEME = 6307, + STR_TILE_INSPECTOR_TRACK_BLOCK_BRAKE = 6319, + STR_TILE_INSPECTOR_TRACK_IS_INDESTRUCTIBLE = 6320, + STR_TILE_INSPECTOR_PATH_BROKEN = 6321, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID = 6308, diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 88d59b0a14..8117a00413 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2323,6 +2323,13 @@ void game_command_modify_tile( *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; @@ -2358,6 +2365,20 @@ void game_command_modify_tile( *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; diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 20f67bb87b..630389d180 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -625,6 +625,30 @@ int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementInde return 0; } +int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, int32_t flags) +{ + TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); + + if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + pathElement->AsPath()->SetIsBroken(broken); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, int32_t flags) { TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); @@ -973,6 +997,55 @@ int32_t tile_inspector_track_set_chain( return 0; } +int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, int32_t flags) +{ + TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + + if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + trackElement->AsTrack()->SetBlockBrakeClosed(blockBrake); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + +int32_t tile_inspector_track_set_indestructible( + int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, int32_t flags) +{ + TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + + if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + trackElement->AsTrack()->SetIsIndestructible(isIndestructible); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + int32_t tile_inspector_scenery_set_quarter_location( int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags) { diff --git a/src/openrct2/world/TileInspector.h b/src/openrct2/world/TileInspector.h index ab759f963f..90262a2959 100644 --- a/src/openrct2/world/TileInspector.h +++ b/src/openrct2/world/TileInspector.h @@ -39,6 +39,7 @@ enum TILE_INSPECTOR_INSTRUCTION_TYPE 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, @@ -48,6 +49,8 @@ enum TILE_INSPECTOR_INSTRUCTION_TYPE 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); @@ -61,10 +64,14 @@ int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool enabl 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( From 7793001f5d088b401a7612f26baba0135bb2677e Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 14 May 2019 20:54:54 +0100 Subject: [PATCH 381/506] Implement BalloonPressAction Furthering reducing the number of game commands and moving them to the Game Action framework --- .../interface/ViewportInteraction.cpp | 10 +-- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- src/openrct2/actions/BalloonPressAction.hpp | 61 +++++++++++++++++++ .../actions/GameActionRegistration.cpp | 2 + src/openrct2/network/Network.cpp | 2 +- src/openrct2/world/Balloon.cpp | 25 -------- src/openrct2/world/Sprite.h | 2 - 8 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 src/openrct2/actions/BalloonPressAction.hpp diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 310dbcb54d..fb7d288f88 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -161,10 +162,11 @@ int32_t viewport_interaction_left_click(int32_t x, int32_t y) switch (info.sprite->generic.type) { case SPRITE_MISC_BALLOON: - game_do_command( - info.sprite->balloon.sprite_index, GAME_COMMAND_FLAG_APPLY, 0, 0, - GAME_COMMAND_BALLOON_PRESS, 0, 0); - break; + { + auto balloonPress = BalloonPressAction(info.sprite->AsBalloon()->sprite_index); + GameActions::Execute(&balloonPress); + } + break; case SPRITE_MISC_DUCK: duck_press(&info.sprite->duck); break; diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index cb7f865879..2fb6fc2489 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1224,7 +1224,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, game_command_pickup_guest, game_command_pickup_staff, - game_command_balloon_press, + nullptr, game_command_modify_tile, game_command_edit_scenario_options, NULL, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 177f165e1a..266e1dc925 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -87,7 +87,7 @@ enum GAME_COMMAND GAME_COMMAND_CHEAT, GAME_COMMAND_PICKUP_GUEST, GAME_COMMAND_PICKUP_STAFF, - GAME_COMMAND_BALLOON_PRESS, + GAME_COMMAND_BALLOON_PRESS, // GA GAME_COMMAND_MODIFY_TILE, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, GAME_COMMAND_PLACE_PEEP_SPAWN, // GA, TODO: refactor to separate array for just game actions diff --git a/src/openrct2/actions/BalloonPressAction.hpp b/src/openrct2/actions/BalloonPressAction.hpp new file mode 100644 index 0000000000..087f0f6501 --- /dev/null +++ b/src/openrct2/actions/BalloonPressAction.hpp @@ -0,0 +1,61 @@ +/***************************************************************************** + * 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/Sprite.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(BalloonPressAction, GAME_COMMAND_BALLOON_PRESS, GameActionResult) +{ + uint16_t _spriteIndex = SPRITE_INDEX_NULL; + +public: + BalloonPressAction() = default; + BalloonPressAction(uint16_t spriteIndex) + : _spriteIndex(spriteIndex) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_spriteIndex); + } + + GameActionResult::Ptr Query() const override + { + rct_sprite* sprite = try_get_sprite(_spriteIndex); + if (sprite == nullptr || !sprite->IsBalloon()) + { + log_error("Tried getting invalid sprite for balloon: %u", _spriteIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + rct_sprite* sprite = try_get_sprite(_spriteIndex); + if (sprite == nullptr || !sprite->IsBalloon()) + { + log_error("Tried getting invalid sprite for balloon: %u", _spriteIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + sprite->AsBalloon()->Press(); + + return MakeResult(); + } +}; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 990a303e72..8bd8e40d2c 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -7,6 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "BalloonPressAction.hpp" #include "BannerPlaceAction.hpp" #include "BannerRemoveAction.hpp" #include "BannerSetColourAction.hpp" @@ -84,6 +85,7 @@ namespace GameActions { void Register() { + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 4864e554d7..560435b051 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,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 "28" +#define NETWORK_STREAM_VERSION "29" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Balloon.cpp b/src/openrct2/world/Balloon.cpp index 3e1b982150..628b9746ef 100644 --- a/src/openrct2/world/Balloon.cpp +++ b/src/openrct2/world/Balloon.cpp @@ -84,24 +84,6 @@ void rct_balloon::Pop() audio_play_sound_at_location(SOUND_BALLOON_POP, x, y, z); } -static money32 game_command_balloon_press(uint16_t spriteIndex, uint8_t flags) -{ - rct_sprite* sprite = try_get_sprite(spriteIndex); - if (sprite == nullptr || !sprite->IsBalloon()) - { - log_error("Tried getting invalid sprite for balloon: %u", spriteIndex); - return MONEY32_UNDEFINED; - } - else - { - if (flags & GAME_COMMAND_FLAG_APPLY) - { - sprite->AsBalloon()->Press(); - } - return 0; - } -} - void create_balloon(int32_t x, int32_t y, int32_t z, int32_t colour, bool isPopped) { rct_sprite* sprite = create_sprite(2); @@ -124,10 +106,3 @@ void balloon_update(rct_balloon* balloon) { balloon->Update(); } - -void game_command_balloon_press( - int32_t* eax, int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - *ebx = game_command_balloon_press(*eax & 0xFFFF, *ebx & 0xFF); -} diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 6662a7dd64..7d41dd68a2 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -229,8 +229,6 @@ void sprite_position_tween_reset(); /////////////////////////////////////////////////////////////// void create_balloon(int32_t x, int32_t y, int32_t z, int32_t colour, bool isPopped); void balloon_update(rct_balloon* balloon); -void game_command_balloon_press( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); /////////////////////////////////////////////////////////////// // Duck From 1eb7f4d8c657360b730067202327078e5c45428a Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 12 May 2019 18:54:41 +0100 Subject: [PATCH 382/506] Implement Modify Group and Kick Player Actions. Further work on the Game Actions porting --- src/openrct2-ui/windows/Multiplayer.cpp | 41 ++-- src/openrct2-ui/windows/Player.cpp | 8 +- src/openrct2/Game.cpp | 4 +- src/openrct2/Game.h | 6 +- .../actions/GameActionRegistration.cpp | 4 + .../actions/NetworkModifyGroupAction.hpp | 81 ++++++++ src/openrct2/actions/PlayerKickAction.hpp | 50 +++++ src/openrct2/network/Network.cpp | 182 +++++++----------- src/openrct2/network/network.h | 10 +- 9 files changed, 245 insertions(+), 141 deletions(-) create mode 100644 src/openrct2/actions/NetworkModifyGroupAction.hpp create mode 100644 src/openrct2/actions/PlayerKickAction.hpp diff --git a/src/openrct2-ui/windows/Multiplayer.cpp b/src/openrct2-ui/windows/Multiplayer.cpp index a9db4551f3..de0d4f77f5 100644 --- a/src/openrct2-ui/windows/Multiplayer.cpp +++ b/src/openrct2-ui/windows/Multiplayer.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -741,11 +742,17 @@ static void window_multiplayer_groups_mouseup(rct_window* w, rct_widgetindex wid } break; case WIDX_ADD_GROUP: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_MODIFY_GROUPS, 0, 0); - break; + { + auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::AddGroup); + GameActions::Execute(&networkModifyGroup); + } + break; case WIDX_REMOVE_GROUP: - game_do_command(1 | (_selectedGroup << 8), GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_MODIFY_GROUPS, 0, 0); - break; + { + auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::RemoveGroup, _selectedGroup); + GameActions::Execute(&networkModifyGroup); + } + break; case WIDX_RENAME_GROUP:; int32_t groupIndex = network_get_group_index(_selectedGroup); const utf8* groupName = network_get_group_name(groupIndex); @@ -788,10 +795,12 @@ static void window_multiplayer_groups_dropdown(rct_window* w, rct_widgetindex wi switch (widgetIndex) { case WIDX_DEFAULT_GROUP_DROPDOWN: - game_do_command( - 4 | (network_get_group_id(dropdownIndex) << 8), GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_MODIFY_GROUPS, 0, - 0); - break; + { + auto networkModifyGroup = NetworkModifyGroupAction( + ModifyGroupType::SetDefault, network_get_group_id(dropdownIndex)); + GameActions::Execute(&networkModifyGroup); + } + break; case WIDX_SELECTED_GROUP_DROPDOWN: _selectedGroup = network_get_group_id(dropdownIndex); break; @@ -838,7 +847,8 @@ static void window_multiplayer_groups_scrollmousedown(rct_window* w, int32_t scr w->selected_list_item = index; window_invalidate(w); - game_do_command(2 | (_selectedGroup << 8), GAME_COMMAND_FLAG_APPLY, index, 0, GAME_COMMAND_MODIFY_GROUPS, 0, 0); + auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::SetPermissions, _selectedGroup, "", index, PermissionState::Toggle); + GameActions::Execute(&networkModifyGroup); } static void window_multiplayer_groups_scrollmouseover(rct_window* w, int32_t scrollIndex, int32_t x, int32_t y) @@ -861,15 +871,10 @@ static void window_multiplayer_groups_text_input(rct_window* w, rct_widgetindex if (text == nullptr) return; - game_do_command( - 3 | (_selectedGroup << 8) | (1 << 16), GAME_COMMAND_FLAG_APPLY, w->number, *((int32_t*)(text + 0)), - GAME_COMMAND_MODIFY_GROUPS, *((int32_t*)(text + 8)), *((int32_t*)(text + 4))); - game_do_command( - 3 | (_selectedGroup << 8) | (2 << 16), GAME_COMMAND_FLAG_APPLY, w->number, *((int32_t*)(text + 12)), - GAME_COMMAND_MODIFY_GROUPS, *((int32_t*)(text + 20)), *((int32_t*)(text + 16))); - game_do_command( - 3 | (_selectedGroup << 8) | (0 << 16), GAME_COMMAND_FLAG_APPLY, w->number, *((int32_t*)(text + 24)), - GAME_COMMAND_MODIFY_GROUPS, *((int32_t*)(text + 32)), *((int32_t*)(text + 28))); + + auto networkModifyGroup = NetworkModifyGroupAction( + ModifyGroupType::SetName, _selectedGroup, text); + GameActions::Execute(&networkModifyGroup); } static void window_multiplayer_groups_invalidate(rct_window* w) diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index ec560a8009..a1794e3167 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -284,8 +285,11 @@ void window_player_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex) } break; case WIDX_KICK: - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_KICK_PLAYER, 0, 0); - break; + { + auto kickPlayerAction = PlayerKickAction(w->number); + GameActions::Execute(&kickPlayerAction); + } + break; } } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 2fb6fc2489..d9ccf3738a 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1219,8 +1219,8 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_modify_groups, - game_command_kick_player, + nullptr, + nullptr, nullptr, game_command_pickup_guest, game_command_pickup_staff, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 266e1dc925..4a897eda5b 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -82,9 +82,9 @@ enum GAME_COMMAND GAME_COMMAND_SET_BANNER_STYLE, // GA GAME_COMMAND_SET_SIGN_STYLE, // GA GAME_COMMAND_SET_PLAYER_GROUP, // GA - GAME_COMMAND_MODIFY_GROUPS, - GAME_COMMAND_KICK_PLAYER, - GAME_COMMAND_CHEAT, + GAME_COMMAND_MODIFY_GROUPS, // GA + GAME_COMMAND_KICK_PLAYER, // GA + GAME_COMMAND_CHEAT, // GA GAME_COMMAND_PICKUP_GUEST, GAME_COMMAND_PICKUP_STAFF, GAME_COMMAND_BALLOON_PRESS, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 8bd8e40d2c..9da6c6dffe 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -34,6 +34,7 @@ #include "LargeScenerySetColourAction.hpp" #include "LoadOrQuitAction.hpp" #include "MazeSetTrackAction.hpp" +#include "NetworkModifyGroupAction.hpp" #include "ParkEntranceRemoveAction.hpp" #include "ParkMarketingAction.hpp" #include "ParkSetDateAction.hpp" @@ -44,6 +45,7 @@ #include "PauseToggleAction.hpp" #include "PlaceParkEntranceAction.hpp" #include "PlacePeepSpawnAction.hpp" +#include "PlayerKickAction.hpp" #include "PlayerSetGroupAction.hpp" #include "RideCreateAction.hpp" #include "RideDemolishAction.hpp" @@ -99,6 +101,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); @@ -107,6 +110,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/NetworkModifyGroupAction.hpp b/src/openrct2/actions/NetworkModifyGroupAction.hpp new file mode 100644 index 0000000000..ec01c6d357 --- /dev/null +++ b/src/openrct2/actions/NetworkModifyGroupAction.hpp @@ -0,0 +1,81 @@ +/***************************************************************************** + * 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 "../network/network.h" +#include "GameAction.h" + +enum class ModifyGroupType : uint8_t +{ + AddGroup, + RemoveGroup, + SetPermissions, + SetName, + SetDefault, + Count +}; + +enum class PermissionState : uint8_t +{ + Toggle, + SetAll, + ClearAll, + Count +}; + +DEFINE_GAME_ACTION(NetworkModifyGroupAction, GAME_COMMAND_MODIFY_GROUPS, GameActionResult) +{ +private: + uint8_t _type{ static_cast(ModifyGroupType::Count) }; + uint8_t _groupId{ std::numeric_limits::max() }; + std::string _name; + uint32_t _permissionIndex{ std::numeric_limits::max() }; + uint8_t _permissionState{ static_cast(PermissionState::Count) }; + +public: + NetworkModifyGroupAction() + { + } + + NetworkModifyGroupAction(ModifyGroupType type, uint8_t groupId = std::numeric_limits::max(), const std::string name = "", uint32_t permissionIndex = 0, PermissionState permissionState = PermissionState::Count ) + : _type(static_cast(type)) + , _groupId(groupId) + , _name(name) + , _permissionIndex(permissionIndex) + , _permissionState(static_cast(permissionState)) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_type) << DS_TAG(_groupId) << DS_TAG(_name) << DS_TAG(_permissionIndex) << DS_TAG(_permissionState); + } + + GameActionResult::Ptr Query() const override + { + return network_modify_groups( + GetPlayer(), static_cast(_type), _groupId, _name, _permissionIndex, + static_cast(_permissionState), false); + } + + GameActionResult::Ptr Execute() const override + { + return network_modify_groups( + GetPlayer(), static_cast(_type), _groupId, _name, _permissionIndex, + static_cast(_permissionState), true); + } +}; diff --git a/src/openrct2/actions/PlayerKickAction.hpp b/src/openrct2/actions/PlayerKickAction.hpp new file mode 100644 index 0000000000..e2bf69dc75 --- /dev/null +++ b/src/openrct2/actions/PlayerKickAction.hpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * 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 "../network/network.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(PlayerKickAction, GAME_COMMAND_KICK_PLAYER, GameActionResult) +{ +private: + NetworkPlayerId_t _playerId{ -1 }; + +public: + PlayerKickAction() + { + } + + PlayerKickAction(NetworkPlayerId_t playerId) + : _playerId(playerId) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_playerId); + } + GameActionResult::Ptr Query() const override + { + return network_kick_player(GetPlayer(), _playerId, false); + } + + GameActionResult::Ptr Execute() const override + { + return network_kick_player(GetPlayer(), _playerId, true); + } +}; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 560435b051..4c3b041987 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -15,6 +15,7 @@ #include "../OpenRCT2.h" #include "../PlatformEnvironment.h" #include "../actions/LoadOrQuitAction.hpp" +#include "../actions/NetworkModifyGroupAction.hpp" #include "../core/Guard.hpp" #include "../platform/platform.h" #include "../ui/UiContext.h" @@ -3639,30 +3640,24 @@ GameActionResult::Ptr network_set_player_group( return std::make_unique(); } -void game_command_modify_groups( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) +GameActionResult::Ptr network_modify_groups( + NetworkPlayerId_t actionPlayerId, ModifyGroupType type, uint8_t groupId, const std::string& name, uint32_t permissionIndex, + PermissionState permissionState, bool isExecuting) { - uint8_t action = (uint8_t)*eax; - uint8_t groupid = (uint8_t)(*eax >> 8); - uint8_t nameChunkIndex = (uint8_t)(*eax >> 16); - - switch (action) + switch (type) { - case 0: - { // add group - if (*ebx & GAME_COMMAND_FLAG_APPLY) + case ModifyGroupType::AddGroup: + { + if (isExecuting) { NetworkGroup* newgroup = gNetwork.AddGroup(); if (!newgroup) { - gGameCommandErrorTitle = STR_CANT_DO_THIS; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::UNKNOWN, STR_CANT_DO_THIS); } // Log add player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(game_command_playerid); + NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); if (game_command_player) { char log_msg[256]; @@ -3676,30 +3671,24 @@ void game_command_modify_groups( } } break; - case 1: - { // remove group - if (groupid == 0) + case ModifyGroupType::RemoveGroup: + { + if (groupId == 0) { - gGameCommandErrorTitle = STR_THIS_GROUP_CANNOT_BE_MODIFIED; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::DISALLOWED, STR_THIS_GROUP_CANNOT_BE_MODIFIED); } for (auto it = gNetwork.player_list.begin(); it != gNetwork.player_list.end(); it++) { - if ((*it)->Group == groupid) + if ((*it)->Group == groupId) { - gGameCommandErrorTitle = STR_CANT_REMOVE_GROUP_THAT_PLAYERS_BELONG_TO; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_REMOVE_GROUP_THAT_PLAYERS_BELONG_TO); } } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { // Log remove player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(game_command_playerid); - NetworkGroup* group = gNetwork.GetGroupByID(groupid); + NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); + NetworkGroup* group = gNetwork.GetGroupByID(groupId); if (game_command_player && group) { char log_msg[256]; @@ -3711,45 +3700,37 @@ void game_command_modify_groups( network_append_server_log(log_msg); } - gNetwork.RemoveGroup(groupid); + gNetwork.RemoveGroup(groupId); } } break; - case 2: - { // set permissions - int32_t index = *ecx; - bool all = *edx & 1; - bool allvalue = (*edx >> 1) & 1; - if (groupid == 0) + case ModifyGroupType::SetPermissions: + { + if (groupId == 0) { // cant change admin group permissions - gGameCommandErrorTitle = STR_THIS_GROUP_CANNOT_BE_MODIFIED; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::DISALLOWED, STR_THIS_GROUP_CANNOT_BE_MODIFIED); } NetworkGroup* mygroup = nullptr; - NetworkPlayer* player = gNetwork.GetPlayerByID(game_command_playerid); - if (player && !all) + NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); + if (player && permissionState == PermissionState::Toggle) { mygroup = gNetwork.GetGroupByID(player->Group); - if (!mygroup || !mygroup->CanPerformAction(index)) + if (!mygroup || !mygroup->CanPerformAction(permissionIndex)) { - gGameCommandErrorTitle = STR_CANT_MODIFY_PERMISSION_THAT_YOU_DO_NOT_HAVE_YOURSELF; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_MODIFY_PERMISSION_THAT_YOU_DO_NOT_HAVE_YOURSELF); } } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { - NetworkGroup* group = gNetwork.GetGroupByID(groupid); + NetworkGroup* group = gNetwork.GetGroupByID(groupId); if (group) { - if (all) + if (permissionState != PermissionState::Toggle) { if (mygroup) { - if (allvalue) + if (permissionState == PermissionState::SetAll) { group->ActionsAllowed = mygroup->ActionsAllowed; } @@ -3761,7 +3742,7 @@ void game_command_modify_groups( } else { - group->ToggleActionPermission(index); + group->ToggleActionPermission(permissionIndex); } } @@ -3776,77 +3757,55 @@ void game_command_modify_groups( } } break; - case 3: - { // set group name - NetworkGroup* group = gNetwork.GetGroupByID(groupid); + case ModifyGroupType::SetName: + { + NetworkGroup* group = gNetwork.GetGroupByID(groupId); const char* oldName = group->GetName().c_str(); - static char newName[128]; - size_t nameChunkOffset = nameChunkIndex - 1; - if (nameChunkIndex == 0) - nameChunkOffset = 2; - nameChunkOffset *= 12; - nameChunkOffset = (std::min)(nameChunkOffset, std::size(newName) - 12); - std::memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 0), edx, sizeof(uint32_t)); - std::memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 4), ebp, sizeof(uint32_t)); - std::memcpy((void*)((uintptr_t)newName + (uintptr_t)nameChunkOffset + 8), edi, sizeof(uint32_t)); - - if (nameChunkIndex != 0) + if (strcmp(oldName, name.c_str()) == 0) { - *ebx = 0; - return; + return std::make_unique(); } - if (strcmp(oldName, newName) == 0) + if (name.empty()) { - *ebx = 0; - return; + return std::make_unique( + GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_GROUP, STR_INVALID_GROUP_NAME); } - if (newName[0] == 0) - { - gGameCommandErrorTitle = STR_CANT_RENAME_GROUP; - gGameCommandErrorText = STR_INVALID_GROUP_NAME; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (group) { // Log edit player group name event - NetworkPlayer* player = gNetwork.GetPlayerByID(game_command_playerid); + NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); char log_msg[256]; const char* args[3] = { player->Name.c_str(), oldName, - newName, + name.c_str(), }; format_string(log_msg, 256, STR_LOG_EDIT_PLAYER_GROUP_NAME, args); network_append_server_log(log_msg); - group->SetName(newName); + group->SetName(name); } } } break; - case 4: - { // set default group - if (groupid == 0) + case ModifyGroupType::SetDefault: + { + if (groupId == 0) { - gGameCommandErrorTitle = STR_CANT_SET_TO_THIS_GROUP; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_SET_TO_THIS_GROUP); } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { - gNetwork.SetDefaultGroup(groupid); + gNetwork.SetDefaultGroup(groupId); // Log edit default player group event - NetworkPlayer* player = gNetwork.GetPlayerByID(game_command_playerid); - NetworkGroup* group = gNetwork.GetGroupByID(groupid); + NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); + NetworkGroup* group = gNetwork.GetGroupByID(groupId); char log_msg[256]; const char* args[2] = { player->Name.c_str(), @@ -3861,35 +3820,29 @@ void game_command_modify_groups( gNetwork.SaveGroups(); - *ebx = 0; + return std::make_unique(); } -void game_command_kick_player( - int32_t* eax, int32_t* ebx, [[maybe_unused]] int32_t* ecx, [[maybe_unused]] int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) +GameActionResult::Ptr network_kick_player(NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting) { - uint8_t playerid = (uint8_t)*eax; - NetworkPlayer* player = gNetwork.GetPlayerByID(playerid); - NetworkPlayer* kicker = gNetwork.GetPlayerByID(game_command_playerid); + NetworkPlayer* player = gNetwork.GetPlayerByID(playerId); + NetworkPlayer* kicker = gNetwork.GetPlayerByID(actionPlayerId); if (player == nullptr) { // Player might be already removed by the PLAYERLIST command, need to refactor non-game commands executing too early. - return; + return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } if (player && player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) { - gGameCommandErrorTitle = STR_CANT_KICK_THE_HOST; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_KICK_THE_HOST); } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + if (isExecuting) { if (gNetwork.GetMode() == NETWORK_MODE_SERVER) { - gNetwork.KickPlayer(playerid); + gNetwork.KickPlayer(playerId); NetworkUserManager* networkUserManager = &gNetwork._userManager; networkUserManager->Load(); @@ -3909,7 +3862,7 @@ void game_command_kick_player( network_append_server_log(log_msg); } } - *ebx = 0; + return std::make_unique(); } uint8_t network_get_default_group() @@ -4329,12 +4282,15 @@ GameActionResult::Ptr network_set_player_group( { return std::make_unique(); } -void game_command_modify_groups( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) +GameActionResult::Ptr network_modify_groups( + NetworkPlayerId_t actionPlayerId, ModifyGroupType type, uint8_t groupId, const std::string& name, uint32_t permissionIndex, + PermissionState permissionState, bool isExecuting) { + return std::make_unique(); } -void game_command_kick_player(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) +GameActionResult::Ptr network_kick_player(NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting) { + return std::make_unique(); } uint8_t network_get_default_group() { diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index b57dd058cc..96284b7d4f 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -26,6 +26,8 @@ struct GameAction; struct Peep; struct LocationXYZ16; class GameActionResult; +enum class ModifyGroupType : uint8_t; +enum class PermissionState : uint8_t; namespace OpenRCT2 { @@ -75,9 +77,11 @@ int32_t network_get_num_groups(); const char* network_get_group_name(uint32_t index); std::unique_ptr network_set_player_group( NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting); -void game_command_modify_groups( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_kick_player(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); +std::unique_ptr network_modify_groups( + NetworkPlayerId_t actionPlayerId, ModifyGroupType type, uint8_t groupId, const std::string& name, uint32_t permissionIndex, + PermissionState permissionState, bool isExecuting); +std::unique_ptr network_kick_player( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting); uint8_t network_get_default_group(); int32_t network_get_num_actions(); rct_string_id network_get_action_name_string_id(uint32_t index); From e72195d16eb5e9244105895e44ca679bd5461571 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 13 May 2019 19:49:06 +0100 Subject: [PATCH 383/506] Make suggested changes --- .../actions/NetworkModifyGroupAction.hpp | 4 +- src/openrct2/actions/PlayerKickAction.hpp | 8 +- src/openrct2/network/Network.cpp | 91 ++----------------- src/openrct2/network/network.h | 3 +- 4 files changed, 15 insertions(+), 91 deletions(-) diff --git a/src/openrct2/actions/NetworkModifyGroupAction.hpp b/src/openrct2/actions/NetworkModifyGroupAction.hpp index ec01c6d357..780b5949e3 100644 --- a/src/openrct2/actions/NetworkModifyGroupAction.hpp +++ b/src/openrct2/actions/NetworkModifyGroupAction.hpp @@ -40,9 +40,7 @@ private: uint8_t _permissionState{ static_cast(PermissionState::Count) }; public: - NetworkModifyGroupAction() - { - } + NetworkModifyGroupAction() = default; NetworkModifyGroupAction(ModifyGroupType type, uint8_t groupId = std::numeric_limits::max(), const std::string name = "", uint32_t permissionIndex = 0, PermissionState permissionState = PermissionState::Count ) : _type(static_cast(type)) diff --git a/src/openrct2/actions/PlayerKickAction.hpp b/src/openrct2/actions/PlayerKickAction.hpp index e2bf69dc75..1478e9be9d 100644 --- a/src/openrct2/actions/PlayerKickAction.hpp +++ b/src/openrct2/actions/PlayerKickAction.hpp @@ -18,9 +18,7 @@ private: NetworkPlayerId_t _playerId{ -1 }; public: - PlayerKickAction() - { - } + PlayerKickAction() = default; PlayerKickAction(NetworkPlayerId_t playerId) : _playerId(playerId) @@ -40,11 +38,11 @@ public: } GameActionResult::Ptr Query() const override { - return network_kick_player(GetPlayer(), _playerId, false); + return network_kick_player(_playerId, false); } GameActionResult::Ptr Execute() const override { - return network_kick_player(GetPlayer(), _playerId, true); + return network_kick_player(_playerId, true); } }; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 4c3b041987..7a68d6ba24 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -3651,23 +3651,10 @@ GameActionResult::Ptr network_modify_groups( if (isExecuting) { NetworkGroup* newgroup = gNetwork.AddGroup(); - if (!newgroup) + if (newgroup == nullptr) { return std::make_unique(GA_ERROR::UNKNOWN, STR_CANT_DO_THIS); } - - // Log add player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); - if (game_command_player) - { - char log_msg[256]; - const char* args[2] = { - game_command_player->Name.c_str(), - newgroup->GetName().c_str(), - }; - format_string(log_msg, 256, STR_LOG_ADD_PLAYER_GROUP, args); - network_append_server_log(log_msg); - } } } break; @@ -3677,29 +3664,15 @@ GameActionResult::Ptr network_modify_groups( { return std::make_unique(GA_ERROR::DISALLOWED, STR_THIS_GROUP_CANNOT_BE_MODIFIED); } - for (auto it = gNetwork.player_list.begin(); it != gNetwork.player_list.end(); it++) + for (const auto &it : gNetwork.player_list) { - if ((*it)->Group == groupId) + if ((it.get())->Group == groupId) { return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_REMOVE_GROUP_THAT_PLAYERS_BELONG_TO); } } if (isExecuting) { - // Log remove player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); - NetworkGroup* group = gNetwork.GetGroupByID(groupId); - if (game_command_player && group) - { - char log_msg[256]; - const char* args[2] = { - game_command_player->Name.c_str(), - group->GetName().c_str(), - }; - format_string(log_msg, 256, STR_LOG_REMOVE_PLAYER_GROUP, args); - network_append_server_log(log_msg); - } - gNetwork.RemoveGroup(groupId); } } @@ -3712,10 +3685,10 @@ GameActionResult::Ptr network_modify_groups( } NetworkGroup* mygroup = nullptr; NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); - if (player && permissionState == PermissionState::Toggle) + if (player != nullptr && permissionState == PermissionState::Toggle) { mygroup = gNetwork.GetGroupByID(player->Group); - if (!mygroup || !mygroup->CanPerformAction(permissionIndex)) + if (mygroup == nullptr || !mygroup->CanPerformAction(permissionIndex)) { return std::make_unique( GA_ERROR::DISALLOWED, STR_CANT_MODIFY_PERMISSION_THAT_YOU_DO_NOT_HAVE_YOURSELF); @@ -3724,11 +3697,11 @@ GameActionResult::Ptr network_modify_groups( if (isExecuting) { NetworkGroup* group = gNetwork.GetGroupByID(groupId); - if (group) + if (group != nullptr) { if (permissionState != PermissionState::Toggle) { - if (mygroup) + if (mygroup != nullptr) { if (permissionState == PermissionState::SetAll) { @@ -3745,15 +3718,6 @@ GameActionResult::Ptr network_modify_groups( group->ToggleActionPermission(permissionIndex); } } - - // Log edit player group permissions event - char log_msg[256]; - const char* args[2] = { - player->Name.c_str(), - group->GetName().c_str(), - }; - format_string(log_msg, 256, STR_LOG_EDIT_PLAYER_GROUP_PERMISSIONS, args); - network_append_server_log(log_msg); } } break; @@ -3775,19 +3739,8 @@ GameActionResult::Ptr network_modify_groups( if (isExecuting) { - if (group) + if (group != nullptr) { - // Log edit player group name event - NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); - char log_msg[256]; - const char* args[3] = { - player->Name.c_str(), - oldName, - name.c_str(), - }; - format_string(log_msg, 256, STR_LOG_EDIT_PLAYER_GROUP_NAME, args); - network_append_server_log(log_msg); - group->SetName(name); } } @@ -3802,17 +3755,6 @@ GameActionResult::Ptr network_modify_groups( if (isExecuting) { gNetwork.SetDefaultGroup(groupId); - - // Log edit default player group event - NetworkPlayer* player = gNetwork.GetPlayerByID(actionPlayerId); - NetworkGroup* group = gNetwork.GetGroupByID(groupId); - char log_msg[256]; - const char* args[2] = { - player->Name.c_str(), - group->GetName().c_str(), - }; - format_string(log_msg, 256, STR_LOG_EDIT_DEFAULT_PLAYER_GROUP, args); - network_append_server_log(log_msg); } } break; @@ -3823,10 +3765,9 @@ GameActionResult::Ptr network_modify_groups( return std::make_unique(); } -GameActionResult::Ptr network_kick_player(NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting) +GameActionResult::Ptr network_kick_player(NetworkPlayerId_t playerId, bool isExecuting) { NetworkPlayer* player = gNetwork.GetPlayerByID(playerId); - NetworkPlayer* kicker = gNetwork.GetPlayerByID(actionPlayerId); if (player == nullptr) { // Player might be already removed by the PLAYERLIST command, need to refactor non-game commands executing too early. @@ -3849,18 +3790,6 @@ GameActionResult::Ptr network_kick_player(NetworkPlayerId_t actionPlayerId, Netw networkUserManager->RemoveUser(player->KeyHash); networkUserManager->Save(); } - - if (kicker != nullptr) - { - // Log kick player event - char log_msg[256]; - const char* args[2] = { - player->Name.c_str(), - kicker->Name.c_str(), - }; - format_string(log_msg, 256, STR_LOG_PLAYER_KICKED, args); - network_append_server_log(log_msg); - } } return std::make_unique(); } @@ -4288,7 +4217,7 @@ GameActionResult::Ptr network_modify_groups( { return std::make_unique(); } -GameActionResult::Ptr network_kick_player(NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting) +GameActionResult::Ptr network_kick_player(NetworkPlayerId_t playerId, bool isExecuting) { return std::make_unique(); } diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 96284b7d4f..12f946d475 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -80,8 +80,7 @@ std::unique_ptr network_set_player_group( std::unique_ptr network_modify_groups( NetworkPlayerId_t actionPlayerId, ModifyGroupType type, uint8_t groupId, const std::string& name, uint32_t permissionIndex, PermissionState permissionState, bool isExecuting); -std::unique_ptr network_kick_player( - NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, bool isExecuting); +std::unique_ptr network_kick_player(NetworkPlayerId_t playerId, bool isExecuting); uint8_t network_get_default_group(); int32_t network_get_num_actions(); rct_string_id network_get_action_name_string_id(uint32_t index); From 0b7d7027e1ba50e79facc4bed06f8395363c72b6 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 13 May 2019 19:53:33 +0100 Subject: [PATCH 384/506] Fix formatting --- src/openrct2-ui/windows/Multiplayer.cpp | 7 +++---- src/openrct2/actions/NetworkModifyGroupAction.hpp | 4 +++- src/openrct2/network/Network.cpp | 9 +++++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/openrct2-ui/windows/Multiplayer.cpp b/src/openrct2-ui/windows/Multiplayer.cpp index de0d4f77f5..00fc390038 100644 --- a/src/openrct2-ui/windows/Multiplayer.cpp +++ b/src/openrct2-ui/windows/Multiplayer.cpp @@ -847,7 +847,8 @@ static void window_multiplayer_groups_scrollmousedown(rct_window* w, int32_t scr w->selected_list_item = index; window_invalidate(w); - auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::SetPermissions, _selectedGroup, "", index, PermissionState::Toggle); + auto networkModifyGroup = NetworkModifyGroupAction( + ModifyGroupType::SetPermissions, _selectedGroup, "", index, PermissionState::Toggle); GameActions::Execute(&networkModifyGroup); } @@ -871,9 +872,7 @@ static void window_multiplayer_groups_text_input(rct_window* w, rct_widgetindex if (text == nullptr) return; - - auto networkModifyGroup = NetworkModifyGroupAction( - ModifyGroupType::SetName, _selectedGroup, text); + auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::SetName, _selectedGroup, text); GameActions::Execute(&networkModifyGroup); } diff --git a/src/openrct2/actions/NetworkModifyGroupAction.hpp b/src/openrct2/actions/NetworkModifyGroupAction.hpp index 780b5949e3..f8185d605d 100644 --- a/src/openrct2/actions/NetworkModifyGroupAction.hpp +++ b/src/openrct2/actions/NetworkModifyGroupAction.hpp @@ -42,7 +42,9 @@ private: public: NetworkModifyGroupAction() = default; - NetworkModifyGroupAction(ModifyGroupType type, uint8_t groupId = std::numeric_limits::max(), const std::string name = "", uint32_t permissionIndex = 0, PermissionState permissionState = PermissionState::Count ) + NetworkModifyGroupAction( + ModifyGroupType type, uint8_t groupId = std::numeric_limits::max(), const std::string name = "", + uint32_t permissionIndex = 0, PermissionState permissionState = PermissionState::Count) : _type(static_cast(type)) , _groupId(groupId) , _name(name) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 7a68d6ba24..59bd4d4974 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -3664,11 +3664,12 @@ GameActionResult::Ptr network_modify_groups( { return std::make_unique(GA_ERROR::DISALLOWED, STR_THIS_GROUP_CANNOT_BE_MODIFIED); } - for (const auto &it : gNetwork.player_list) + for (const auto& it : gNetwork.player_list) { if ((it.get())->Group == groupId) { - return std::make_unique(GA_ERROR::DISALLOWED, STR_CANT_REMOVE_GROUP_THAT_PLAYERS_BELONG_TO); + return std::make_unique( + GA_ERROR::DISALLOWED, STR_CANT_REMOVE_GROUP_THAT_PLAYERS_BELONG_TO); } } if (isExecuting) @@ -3758,6 +3759,10 @@ GameActionResult::Ptr network_modify_groups( } } break; + default: + log_error("Invalid Modify Group Type: %u", static_cast(type)); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + break; } gNetwork.SaveGroups(); From cb6a563e2d6f7ef1d608dcc200575e1381bdc87e Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 14 May 2019 21:59:16 +0200 Subject: [PATCH 385/506] Bump network version [ci skip] --- 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 59bd4d4974..837a7fc606 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 "29" +#define NETWORK_STREAM_VERSION "30" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From abc13422ede658e5f664111ca1d1cbdd93419467 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Tue, 14 May 2019 22:12:23 +0200 Subject: [PATCH 386/506] Fix #9132: System file browser cannot open SV4 files --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/LoadSave.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 989bc5daca..d00d723ad0 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -37,6 +37,7 @@ - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. +- Fix: [#9132] System file browser cannot open SV4 files. - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Fix: [#9240] Crash when passing directory instead of save file. diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 5328622c8d..95875d1d0f 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -431,7 +431,7 @@ static bool browse(bool isSave, char* path, size_t pathSize) { // When the given save type was given, Windows still interprets a filename with a dot in its name as a custom extension, // meaning files like "My Coaster v1.2" will not get the .td6 extension by default. - if (get_file_extension_type(path) != fileType) + if (isSave && get_file_extension_type(path) != fileType) path_append_extension(path, extension, pathSize); return true; From 3ac596faf17ae6c446c2a4712a3b74cc0c62a3d4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 14 May 2019 21:08:50 +0100 Subject: [PATCH 387/506] Implement ScenarioSetSetting game action Further work moving game commands into the game action framework to improve design. --- .../windows/EditorScenarioOptions.cpp | 220 ++++++------- src/openrct2/Editor.cpp | 219 ------------- src/openrct2/Editor.h | 4 - src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + .../actions/ScenarioSetSettingAction.hpp | 290 ++++++++++++++++++ 7 files changed, 408 insertions(+), 331 deletions(-) create mode 100644 src/openrct2/actions/ScenarioSetSettingAction.hpp diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index df9942005b..eaa651b547 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -508,18 +509,19 @@ static void window_editor_scenario_options_financial_mouseup(rct_window* w, rct_ newMoneySetting = (gParkFlags & PARK_FLAGS_NO_MONEY) ? 0 : 1; } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETNOMONEY, newMoneySetting, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::NoMoney, newMoneySetting); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; } case WIDX_FORBID_MARKETING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETFORBIDMARKETINGCAMPAIGNS, - gParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ForbidMarketingCampaigns, gParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } } } @@ -561,9 +563,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INITIAL_CASH_INCREASE: if (gInitialCash < MONEY(1000000, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETINITIALCASH, gInitialCash + MONEY(500, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::InitialCash, gInitialCash + MONEY(500, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -574,9 +576,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INITIAL_CASH_DECREASE: if (gInitialCash > MONEY(0, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETINITIALCASH, gInitialCash - MONEY(500, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::InitialCash, gInitialCash - MONEY(500, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -587,9 +589,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INITIAL_LOAN_INCREASE: if (gBankLoan < MONEY(5000000, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETINITIALLOAN, gBankLoan + MONEY(1000, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::InitialLoan, gBankLoan + MONEY(1000, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -600,9 +602,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INITIAL_LOAN_DECREASE: if (gBankLoan > MONEY(0, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETINITIALLOAN, gBankLoan - MONEY(1000, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::InitialLoan, gBankLoan - MONEY(1000, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -613,9 +615,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_MAXIMUM_LOAN_INCREASE: if (gMaxBankLoan < MONEY(5000000, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETMAXIMUMLOANSIZE, gMaxBankLoan + MONEY(1000, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::MaximumLoanSize, gMaxBankLoan + MONEY(1000, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -626,9 +628,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_MAXIMUM_LOAN_DECREASE: if (gMaxBankLoan > MONEY(0, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETMAXIMUMLOANSIZE, gMaxBankLoan - MONEY(1000, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::MaximumLoanSize, gMaxBankLoan - MONEY(1000, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -639,9 +641,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INTEREST_RATE_INCREASE: if (gBankLoanInterestRate < 80) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETANNUALINTERESTRATE, gBankLoanInterestRate + 1, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::AnnualInterestRate, gBankLoanInterestRate + 1); + GameActions::Execute(&scenarioSetSetting); } else { @@ -652,18 +654,9 @@ static void window_editor_scenario_options_financial_mousedown(rct_window* w, rc case WIDX_INTEREST_RATE_DECREASE: if (gBankLoanInterestRate > 0) { - if (gBankLoanInterestRate > 80) - { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETANNUALINTERESTRATE, 80, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); - } - else - { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETANNUALINTERESTRATE, gBankLoanInterestRate - 1, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); - } + auto interest = std::min(80, gBankLoanInterestRate - 1); + auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::AnnualInterestRate, interest); + GameActions::Execute(&scenarioSetSetting); } else { @@ -820,17 +813,21 @@ static void window_editor_scenario_options_guests_mouseup(rct_window* w, rct_wid window_editor_scenario_options_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GUEST_PREFER_LESS_INTENSE_RIDES: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTSPREFERLESSINTENSERIDES, - gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestsPreferLessIntenseRides, gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } case WIDX_GUEST_PREFER_MORE_INTENSE_RIDES: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTSPREFERMOREINTENSERIDES, - gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestsPreferMoreIntenseRides, gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } } } @@ -854,9 +851,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_CASH_PER_GUEST_INCREASE: if (gGuestInitialCash < MONEY(1000, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETAVERAGECASHPERGUEST, gGuestInitialCash + MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::AverageCashPerGuest, gGuestInitialCash + MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -867,9 +864,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_CASH_PER_GUEST_DECREASE: if (gGuestInitialCash > MONEY(0, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETAVERAGECASHPERGUEST, gGuestInitialCash - MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::AverageCashPerGuest, gGuestInitialCash - MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -880,9 +877,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_HAPPINESS_INCREASE: if (gGuestInitialHappiness < 250) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALHAPPINESS, gGuestInitialHappiness + 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialHappiness, gGuestInitialHappiness + 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -893,9 +890,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_HAPPINESS_DECREASE: if (gGuestInitialHappiness > 40) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALHAPPINESS, gGuestInitialHappiness - 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialHappiness, gGuestInitialHappiness - 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -906,9 +903,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_HUNGER_INCREASE: if (gGuestInitialHunger > 40) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALHUNGER, gGuestInitialHunger - 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialHunger, gGuestInitialHunger - 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -919,9 +916,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_HUNGER_DECREASE: if (gGuestInitialHunger < 250) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALHUNGER, gGuestInitialHunger + 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialHunger, gGuestInitialHunger + 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -932,9 +929,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_THIRST_INCREASE: if (gGuestInitialThirst > 40) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALTHIRST, gGuestInitialThirst - 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialThirst, gGuestInitialThirst - 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -945,9 +942,9 @@ static void window_editor_scenario_options_guests_mousedown(rct_window* w, rct_w case WIDX_GUEST_INITIAL_THIRST_DECREASE: if (gGuestInitialThirst < 250) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTINITIALTHIRST, gGuestInitialThirst + 4, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestInitialThirst, gGuestInitialThirst + 4); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1097,35 +1094,46 @@ static void window_editor_scenario_options_park_mouseup(rct_window* w, rct_widge window_editor_scenario_options_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_FORBID_TREE_REMOVAL: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETFORBIDTREEREMOVAL, - gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ForbidTreeRemoval, gParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } case WIDX_FORBID_LANDSCAPE_CHANGES: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETFORBIDLANDSCAPECHANGES, - gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ForbidLandscapeChanges, gParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } case WIDX_FORBID_HIGH_CONSTRUCTION: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETFORBIDHIGHCONSTRUCTION, - gParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ForbidHighConstruction, gParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } case WIDX_HARD_PARK_RATING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETPARKRATINGHIGHERDIFFICULTLEVEL, - gParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ParkRatingHigherDifficultyLevel, gParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } case WIDX_HARD_GUEST_GENERATION: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETGUESTGENERATIONHIGHERDIFFICULTLEVEL, - gParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION ? 0 : 1, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::GuestGenerationHigherDifficultyLevel, + gParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION ? 0 : 1); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; + } } } @@ -1151,9 +1159,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_LAND_COST_INCREASE: if (gLandPrice < MONEY(200, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETCOSTTOBUYLAND, gLandPrice + MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::CostToBuyLand, gLandPrice + MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1164,9 +1172,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_LAND_COST_DECREASE: if (gLandPrice > MONEY(5, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETCOSTTOBUYLAND, gLandPrice - MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::CostToBuyLand, gLandPrice - MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1177,9 +1185,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE: if (gConstructionRightsPrice < MONEY(200, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETCOSTTOBUYCONSTRUCTIONRIGHTS, - gConstructionRightsPrice + MONEY(1, 00), GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::CostToBuyConstructionRights, gConstructionRightsPrice + MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1190,9 +1198,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE: if (gConstructionRightsPrice > MONEY(5, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETCOSTTOBUYCONSTRUCTIONRIGHTS, - gConstructionRightsPrice - MONEY(1, 00), GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::CostToBuyConstructionRights, gConstructionRightsPrice - MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1203,9 +1211,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_ENTRY_PRICE_INCREASE: if (gParkEntranceFee < MAX_ENTRANCE_FEE) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETPARKCHARGEENTRYFEE, gParkEntranceFee + MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ParkChargeEntryFee, gParkEntranceFee + MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1216,9 +1224,9 @@ static void window_editor_scenario_options_park_mousedown(rct_window* w, rct_wid case WIDX_ENTRY_PRICE_DECREASE: if (gParkEntranceFee > MONEY(0, 00)) { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETPARKCHARGEENTRYFEE, gParkEntranceFee - MONEY(1, 00), - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + auto scenarioSetSetting = ScenarioSetSettingAction( + ScenarioSetSetting::ParkChargeEntryFee, gParkEntranceFee - MONEY(1, 00)); + GameActions::Execute(&scenarioSetSetting); } else { @@ -1268,12 +1276,12 @@ static void window_editor_scenario_options_park_dropdown(rct_window* w, rct_widg switch (widgetIndex) { case WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, EDIT_SCENARIOOPTIONS_SETPARKCHARGEMETHOD, dropdownIndex, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, 0, 0); + { + auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::ParkChargeMethod, dropdownIndex); + GameActions::Execute(&scenarioSetSetting); window_invalidate(w); break; - + } case WIDX_CLIMATE_DROPDOWN: if (gClimate != (uint8_t)dropdownIndex) { diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 6d3f97833e..45232073a9 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -538,219 +538,6 @@ namespace Editor return true; } - void GameCommandEditScenarioOptions( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) - { - if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) - { - *ebx = 0; - return; - } - - switch (*ecx) - { - case EDIT_SCENARIOOPTIONS_SETNOMONEY: - if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) - { - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO; - } - } - else - { - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_NO_MONEY; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY; - } - // Invalidate all windows that have anything to do with finance - window_invalidate_by_class(WC_RIDE); - window_invalidate_by_class(WC_PEEP); - window_invalidate_by_class(WC_PARK_INFORMATION); - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); - window_invalidate_by_class(WC_TOP_TOOLBAR); - } - break; - case EDIT_SCENARIOOPTIONS_SETINITIALCASH: - gInitialCash = std::clamp(*edx, MONEY(0, 00), MONEY(1000000, 00)); - gCash = gInitialCash; - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); - break; - case EDIT_SCENARIOOPTIONS_SETINITIALLOAN: - gBankLoan = std::clamp(*edx, MONEY(0, 00), MONEY(5000000, 00)); - gMaxBankLoan = std::max(gBankLoan, gMaxBankLoan); - window_invalidate_by_class(WC_FINANCES); - break; - case EDIT_SCENARIOOPTIONS_SETMAXIMUMLOANSIZE: - gMaxBankLoan = std::clamp(*edx, MONEY(0, 00), MONEY(5000000, 00)); - gBankLoan = std::min(gBankLoan, gMaxBankLoan); - window_invalidate_by_class(WC_FINANCES); - break; - case EDIT_SCENARIOOPTIONS_SETANNUALINTERESTRATE: - gBankLoanInterestRate = std::clamp(*edx, 0, 80); - window_invalidate_by_class(WC_FINANCES); - break; - case EDIT_SCENARIOOPTIONS_SETFORBIDMARKETINGCAMPAIGNS: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; - } - else - { - gParkFlags &= ~PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; - } - break; - case EDIT_SCENARIOOPTIONS_SETAVERAGECASHPERGUEST: - gGuestInitialCash = std::clamp(*edx, MONEY(0, 00), MONEY(1000, 00)); - break; - case EDIT_SCENARIOOPTIONS_SETGUESTINITIALHAPPINESS: - gGuestInitialHappiness = std::clamp(*edx, 40, 250); - break; - case EDIT_SCENARIOOPTIONS_SETGUESTINITIALHUNGER: - gGuestInitialHunger = std::clamp(*edx, 40, 250); - break; - case EDIT_SCENARIOOPTIONS_SETGUESTINITIALTHIRST: - gGuestInitialThirst = std::clamp(*edx, 40, 250); - break; - case EDIT_SCENARIOOPTIONS_SETGUESTSPREFERLESSINTENSERIDES: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_PREF_LESS_INTENSE_RIDES; - } - else - { - gParkFlags &= ~PARK_FLAGS_PREF_LESS_INTENSE_RIDES; - } - break; - case EDIT_SCENARIOOPTIONS_SETGUESTSPREFERMOREINTENSERIDES: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_PREF_MORE_INTENSE_RIDES; - } - else - { - gParkFlags &= ~PARK_FLAGS_PREF_MORE_INTENSE_RIDES; - } - break; - case EDIT_SCENARIOOPTIONS_SETCOSTTOBUYLAND: - gLandPrice = std::clamp(*edx, MONEY(5, 00), MONEY(200, 00)); - break; - case EDIT_SCENARIOOPTIONS_SETCOSTTOBUYCONSTRUCTIONRIGHTS: - gConstructionRightsPrice = std::clamp(*edx, MONEY(5, 00), MONEY(200, 00)); - break; - case EDIT_SCENARIOOPTIONS_SETPARKCHARGEMETHOD: - if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) - { - if (*edx == 0) - { - gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - gParkEntranceFee = MONEY(0, 00); - } - else if (*edx == 1) - { - gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - gParkEntranceFee = MONEY(10, 00); - } - else - { - gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; - gParkEntranceFee = MONEY(10, 00); - } - } - else - { - if (*edx == 0) - { - gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - } - else if (*edx == 1) - { - gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - } - else - { - gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; - } - window_invalidate_by_class(WC_PARK_INFORMATION); - window_invalidate_by_class(WC_RIDE); - } - break; - case EDIT_SCENARIOOPTIONS_SETPARKCHARGEENTRYFEE: - gParkEntranceFee = std::clamp(*edx, MONEY(0, 00), MAX_ENTRANCE_FEE); - window_invalidate_by_class(WC_PARK_INFORMATION); - break; - case EDIT_SCENARIOOPTIONS_SETFORBIDTREEREMOVAL: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_FORBID_TREE_REMOVAL; - } - else - { - gParkFlags &= ~PARK_FLAGS_FORBID_TREE_REMOVAL; - } - break; - case EDIT_SCENARIOOPTIONS_SETFORBIDLANDSCAPECHANGES: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; - } - else - { - gParkFlags &= ~PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; - } - break; - case EDIT_SCENARIOOPTIONS_SETFORBIDHIGHCONSTRUCTION: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; - } - else - { - gParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; - } - break; - case EDIT_SCENARIOOPTIONS_SETPARKRATINGHIGHERDIFFICULTLEVEL: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_DIFFICULT_PARK_RATING; - } - else - { - gParkFlags &= ~PARK_FLAGS_DIFFICULT_PARK_RATING; - } - break; - case EDIT_SCENARIOOPTIONS_SETGUESTGENERATIONHIGHERDIFFICULTLEVEL: - if (*edx != 0) - { - gParkFlags |= PARK_FLAGS_DIFFICULT_GUEST_GENERATION; - } - else - { - gParkFlags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION; - } - break; - } - window_invalidate_by_class(WC_EDITOR_SCENARIO_OPTIONS); - *ebx = 0; - } - uint8_t GetSelectedObjectFlags(int32_t objectType, size_t index) { uint8_t result = 0; @@ -787,9 +574,3 @@ void editor_open_windows_for_current_step() { Editor::OpenWindowsForCurrentStep(); } - -void game_command_edit_scenario_options( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) -{ - Editor::GameCommandEditScenarioOptions(eax, ebx, ecx, edx, esi, edi, ebp); -} diff --git a/src/openrct2/Editor.h b/src/openrct2/Editor.h index 8810f12ab1..50bfb8d3fd 100644 --- a/src/openrct2/Editor.h +++ b/src/openrct2/Editor.h @@ -24,7 +24,6 @@ namespace Editor int32_t CheckObjectSelection(); void OpenWindowsForCurrentStep(); - void GameCommandEditScenarioOptions(int32_t*, int32_t*, int32_t*, int32_t*, int32_t*, int32_t*, int32_t*); uint8_t GetSelectedObjectFlags(int32_t objectType, size_t index); void ClearSelectedObject(int32_t objectType, size_t index, uint32_t flags); @@ -70,7 +69,4 @@ enum void editor_open_windows_for_current_step(); -void game_command_edit_scenario_options( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - #endif diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index d9ccf3738a..8fe33e3dfa 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1226,6 +1226,6 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_pickup_staff, nullptr, game_command_modify_tile, - game_command_edit_scenario_options, + nullptr, NULL, }; diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 4a897eda5b..d9885993c3 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -89,7 +89,7 @@ enum GAME_COMMAND GAME_COMMAND_PICKUP_STAFF, GAME_COMMAND_BALLOON_PRESS, // GA GAME_COMMAND_MODIFY_TILE, - GAME_COMMAND_EDIT_SCENARIO_OPTIONS, + 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 GAME_COMMAND_SET_COLOUR_SCHEME, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 9da6c6dffe..4bbbabdbcd 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -58,6 +58,7 @@ #include "RideSetSetting.hpp" #include "RideSetStatus.hpp" #include "RideSetVehiclesAction.hpp" +#include "ScenarioSetSettingAction.hpp" #include "SetCheatAction.hpp" #include "SetParkEntranceFeeAction.hpp" #include "SignSetNameAction.hpp" @@ -123,6 +124,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/ScenarioSetSettingAction.hpp b/src/openrct2/actions/ScenarioSetSettingAction.hpp new file mode 100644 index 0000000000..cbfd2fe8ad --- /dev/null +++ b/src/openrct2/actions/ScenarioSetSettingAction.hpp @@ -0,0 +1,290 @@ +/***************************************************************************** + * 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 "../OpenRCT2.h" +#include "../interface/Window.h" +#include "../management/Finance.h" +#include "../peep/Peep.h" +#include "../world/Park.h" +#include "GameAction.h" + +#include + +enum class ScenarioSetSetting : uint8_t +{ + NoMoney, + InitialCash, + InitialLoan, + MaximumLoanSize, + AnnualInterestRate, + ForbidMarketingCampaigns, + AverageCashPerGuest, + GuestInitialHappiness, + GuestInitialHunger, + GuestInitialThirst, + GuestsPreferLessIntenseRides, + GuestsPreferMoreIntenseRides, + CostToBuyLand, + CostToBuyConstructionRights, + ParkChargeMethod, + ParkChargeEntryFee, + ForbidTreeRemoval, + ForbidLandscapeChanges, + ForbidHighConstruction, + ParkRatingHigherDifficultyLevel, + GuestGenerationHigherDifficultyLevel, + Count +}; + +DEFINE_GAME_ACTION(ScenarioSetSettingAction, GAME_COMMAND_EDIT_SCENARIO_OPTIONS, GameActionResult) +{ +private: + uint8_t _setting{ static_cast(ScenarioSetSetting::Count) }; + uint32_t _value{ 0 }; + +public: + ScenarioSetSettingAction() + { + } + ScenarioSetSettingAction(ScenarioSetSetting setting, uint32_t value) + : _setting(static_cast(setting)) + , _value(value) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_setting) << DS_TAG(_value); + } + + GameActionResult::Ptr Query() const override + { + if (_setting >= static_cast(ScenarioSetSetting::Count)) + { + log_error("Invalid setting: %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + switch (static_cast(_setting)) + { + case ScenarioSetSetting::NoMoney: + if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) + { + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; + } + else + { + gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO; + } + } + else + { + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_NO_MONEY; + } + else + { + gParkFlags &= ~PARK_FLAGS_NO_MONEY; + } + // Invalidate all windows that have anything to do with finance + window_invalidate_by_class(WC_RIDE); + window_invalidate_by_class(WC_PEEP); + window_invalidate_by_class(WC_PARK_INFORMATION); + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + window_invalidate_by_class(WC_TOP_TOOLBAR); + } + break; + case ScenarioSetSetting::InitialCash: + gInitialCash = std::clamp(_value, MONEY(0, 00), MONEY(1000000, 00)); + gCash = gInitialCash; + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + break; + case ScenarioSetSetting::InitialLoan: + gBankLoan = std::clamp(_value, MONEY(0, 00), MONEY(5000000, 00)); + gMaxBankLoan = std::max(gBankLoan, gMaxBankLoan); + window_invalidate_by_class(WC_FINANCES); + break; + case ScenarioSetSetting::MaximumLoanSize: + gMaxBankLoan = std::clamp(_value, MONEY(0, 00), MONEY(5000000, 00)); + gBankLoan = std::min(gBankLoan, gMaxBankLoan); + window_invalidate_by_class(WC_FINANCES); + break; + case ScenarioSetSetting::AnnualInterestRate: + gBankLoanInterestRate = std::clamp(_value, 0, 80); + window_invalidate_by_class(WC_FINANCES); + break; + case ScenarioSetSetting::ForbidMarketingCampaigns: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; + } + else + { + gParkFlags &= ~PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; + } + break; + case ScenarioSetSetting::AverageCashPerGuest: + gGuestInitialCash = std::clamp(_value, MONEY(0, 00), MONEY(1000, 00)); + break; + case ScenarioSetSetting::GuestInitialHappiness: + gGuestInitialHappiness = std::clamp(_value, 40, 250); + break; + case ScenarioSetSetting::GuestInitialHunger: + gGuestInitialHunger = std::clamp(_value, 40, 250); + break; + case ScenarioSetSetting::GuestInitialThirst: + gGuestInitialThirst = std::clamp(_value, 40, 250); + break; + case ScenarioSetSetting::GuestsPreferLessIntenseRides: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_PREF_LESS_INTENSE_RIDES; + } + else + { + gParkFlags &= ~PARK_FLAGS_PREF_LESS_INTENSE_RIDES; + } + break; + case ScenarioSetSetting::GuestsPreferMoreIntenseRides: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_PREF_MORE_INTENSE_RIDES; + } + else + { + gParkFlags &= ~PARK_FLAGS_PREF_MORE_INTENSE_RIDES; + } + break; + case ScenarioSetSetting::CostToBuyLand: + gLandPrice = std::clamp(_value, MONEY(5, 00), MONEY(200, 00)); + break; + case ScenarioSetSetting::CostToBuyConstructionRights: + gConstructionRightsPrice = std::clamp(_value, MONEY(5, 00), MONEY(200, 00)); + break; + case ScenarioSetSetting::ParkChargeMethod: + if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) + { + if (_value == 0) + { + gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gParkEntranceFee = MONEY(0, 00); + } + else if (_value == 1) + { + gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gParkEntranceFee = MONEY(10, 00); + } + else + { + gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gParkEntranceFee = MONEY(10, 00); + } + } + else + { + if (_value == 0) + { + gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + } + else if (_value == 1) + { + gParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + } + else + { + gParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; + gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + } + window_invalidate_by_class(WC_PARK_INFORMATION); + window_invalidate_by_class(WC_RIDE); + } + break; + case ScenarioSetSetting::ParkChargeEntryFee: + gParkEntranceFee = std::clamp(_value, MONEY(0, 00), MAX_ENTRANCE_FEE); + window_invalidate_by_class(WC_PARK_INFORMATION); + break; + case ScenarioSetSetting::ForbidTreeRemoval: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_FORBID_TREE_REMOVAL; + } + else + { + gParkFlags &= ~PARK_FLAGS_FORBID_TREE_REMOVAL; + } + break; + case ScenarioSetSetting::ForbidLandscapeChanges: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; + } + else + { + gParkFlags &= ~PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; + } + break; + case ScenarioSetSetting::ForbidHighConstruction: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; + } + else + { + gParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; + } + break; + case ScenarioSetSetting::ParkRatingHigherDifficultyLevel: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_DIFFICULT_PARK_RATING; + } + else + { + gParkFlags &= ~PARK_FLAGS_DIFFICULT_PARK_RATING; + } + break; + case ScenarioSetSetting::GuestGenerationHigherDifficultyLevel: + if (_value != 0) + { + gParkFlags |= PARK_FLAGS_DIFFICULT_GUEST_GENERATION; + } + else + { + gParkFlags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION; + } + break; + } + window_invalidate_by_class(WC_EDITOR_SCENARIO_OPTIONS); + return MakeResult(); + } +}; From 1fcedae3bcfe89c8fb788d2a5f922d12d59449c8 Mon Sep 17 00:00:00 2001 From: Greg Hennis Date: Wed, 15 May 2019 13:07:01 -0400 Subject: [PATCH 388/506] Fix #9258: Rename SPRITE_LIST_NULL to ..._FREE (#9260) --- .../windows/EditorBottomToolbar.cpp | 6 +++--- src/openrct2/actions/StaffHireNewAction.hpp | 2 +- src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/world/Sprite.cpp | 20 +++++++++---------- src/openrct2/world/Sprite.h | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index 6d33965ef0..4a1c0523c0 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -316,7 +316,7 @@ static void window_editor_bottom_toolbar_mouseup([[maybe_unused]] rct_window* w, if (widgetIndex == WIDX_PREVIOUS_STEP_BUTTON) { if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - || (gSpriteListCount[SPRITE_LIST_NULL] == MAX_SPRITES && !(gParkFlags & PARK_FLAGS_SPRITES_INITIALISED))) + || (gSpriteListCount[SPRITE_LIST_FREE] == MAX_SPRITES && !(gParkFlags & PARK_FLAGS_SPRITES_INITIALISED))) { previous_button_mouseup_events[gS6Info.editor_step](); } @@ -376,7 +376,7 @@ void window_editor_bottom_toolbar_invalidate(rct_window* w) } else if (!(gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)) { - if (gSpriteListCount[SPRITE_LIST_NULL] != MAX_SPRITES || gParkFlags & PARK_FLAGS_SPRITES_INITIALISED) + if (gSpriteListCount[SPRITE_LIST_FREE] != MAX_SPRITES || gParkFlags & PARK_FLAGS_SPRITES_INITIALISED) { hide_previous_step_button(); } @@ -401,7 +401,7 @@ void window_editor_bottom_toolbar_paint(rct_window* w, rct_drawpixelinfo* dpi) { drawPreviousButton = true; } - else if (gSpriteListCount[SPRITE_LIST_NULL] != MAX_SPRITES) + else if (gSpriteListCount[SPRITE_LIST_FREE] != MAX_SPRITES) { drawNextButton = true; } diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index d22de4bf08..4f27efc5aa 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -111,7 +111,7 @@ private: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - if (gSpriteListCount[SPRITE_LIST_NULL] < 400) + if (gSpriteListCount[SPRITE_LIST_FREE] < 400) { return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME); } diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 9b40612da0..f07cdb69b9 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1710,7 +1710,7 @@ static constexpr const uint8_t tshirt_colours[] = { */ Peep* Peep::Generate(const CoordsXYZ coords) { - if (gSpriteListCount[SPRITE_LIST_NULL] < 400) + if (gSpriteListCount[SPRITE_LIST_FREE] < 400) return nullptr; Peep* peep = (Peep*)create_sprite(1); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 14105f77e2..fd72503273 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1072,7 +1072,7 @@ public: gSpriteListCount[i] = _s6.sprite_lists_count[i]; } // This list contains the number of free slots. Increase it according to our own sprite limit. - gSpriteListCount[SPRITE_LIST_NULL] += (MAX_SPRITES - RCT2_MAX_SPRITES); + gSpriteListCount[SPRITE_LIST_FREE] += (MAX_SPRITES - RCT2_MAX_SPRITES); } void ImportSprite(rct_sprite* dst, const RCT2Sprite* src) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 28c96ebe07..9345dc4adc 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4574,7 +4574,7 @@ static void ride_set_start_finish_points(ride_id_t rideIndex, CoordsXYE* startEl static int32_t count_free_misc_sprite_slots() { int32_t miscSpriteCount = gSpriteListCount[SPRITE_LIST_MISC]; - int32_t remainingSpriteCount = gSpriteListCount[SPRITE_LIST_NULL]; + int32_t remainingSpriteCount = gSpriteListCount[SPRITE_LIST_FREE]; return std::max(0, miscSpriteCount + remainingSpriteCount - 300); } diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 319cd61b43..e2585c8507 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -174,13 +174,13 @@ void reset_sprite_list() else { spr->generic.previous = SPRITE_INDEX_NULL; - gSpriteListHead[SPRITE_LIST_NULL] = i; + gSpriteListHead[SPRITE_LIST_FREE] = i; } _spriteFlashingList[i] = false; previous_spr = spr; } - gSpriteListCount[SPRITE_LIST_NULL] = MAX_SPRITES; + gSpriteListCount[SPRITE_LIST_FREE] = MAX_SPRITES; reset_sprite_spatial_index(); } @@ -316,13 +316,13 @@ void sprite_clear_all_unused() rct_sprite_generic* sprite; uint16_t spriteIndex, nextSpriteIndex; - spriteIndex = gSpriteListHead[SPRITE_LIST_NULL]; + spriteIndex = gSpriteListHead[SPRITE_LIST_FREE]; while (spriteIndex != SPRITE_INDEX_NULL) { sprite = &get_sprite(spriteIndex)->generic; nextSpriteIndex = sprite->next; sprite_reset(sprite); - sprite->linked_list_type_offset = SPRITE_LIST_NULL * 2; + sprite->linked_list_type_offset = SPRITE_LIST_FREE * 2; // This shouldn't be necessary, as sprite_reset() preserves the index // but it has been left in as a safety net in case the index isn't set correctly @@ -351,18 +351,18 @@ rct_sprite* create_sprite(uint8_t bl) { // 69EC96; uint16_t cx = 0x12C - gSpriteListCount[SPRITE_LIST_MISC]; - if (cx >= gSpriteListCount[SPRITE_LIST_NULL]) + if (cx >= gSpriteListCount[SPRITE_LIST_FREE]) { return nullptr; } linkedListTypeOffset = SPRITE_LIST_MISC; } - else if (gSpriteListCount[SPRITE_LIST_NULL] == 0) + else if (gSpriteListCount[SPRITE_LIST_FREE] == 0) { return nullptr; } - rct_sprite_generic* sprite = &(get_sprite(gSpriteListHead[SPRITE_LIST_NULL]))->generic; + rct_sprite_generic* sprite = &(get_sprite(gSpriteListHead[SPRITE_LIST_FREE]))->generic; move_sprite_to_list((rct_sprite*)sprite, linkedListTypeOffset); @@ -684,7 +684,7 @@ void sprite_remove(rct_sprite* sprite) user_string_free(peep->name_string_idx); } - move_sprite_to_list(sprite, SPRITE_LIST_NULL); + move_sprite_to_list(sprite, SPRITE_LIST_FREE); sprite->generic.sprite_identifier = SPRITE_IDENTIFIER_NULL; _spriteFlashingList[sprite->generic.sprite_index] = false; @@ -1029,7 +1029,7 @@ int32_t check_for_sprite_list_cycles(bool fix) } /** - * Finds and fixes null sprites that are not reachable via SPRITE_LIST_NULL list. + * Finds and fixes null sprites that are not reachable via SPRITE_LIST_FREE list. * * @return count of disjoint sprites found */ @@ -1037,7 +1037,7 @@ int32_t fix_disjoint_sprites() { // Find reachable sprites bool reachable[MAX_SPRITES] = { false }; - uint16_t sprite_idx = gSpriteListHead[SPRITE_LIST_NULL]; + uint16_t sprite_idx = gSpriteListHead[SPRITE_LIST_FREE]; rct_sprite* null_list_tail = nullptr; while (sprite_idx != SPRITE_INDEX_NULL) { diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 7d41dd68a2..27bc9d4a53 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -30,7 +30,7 @@ enum SPRITE_IDENTIFIER enum SPRITE_LIST { - SPRITE_LIST_NULL, + SPRITE_LIST_FREE, SPRITE_LIST_TRAIN, SPRITE_LIST_PEEP, SPRITE_LIST_MISC, From 1a01a49002355fca4df0e90754b237e7bbfa431b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Wed, 15 May 2019 19:55:16 +0200 Subject: [PATCH 389/506] Fix #9124: Disconnected clients can crash the server --- distribution/changelog.txt | 1 + src/openrct2/network/Network.cpp | 272 ++++++++++++++--------- src/openrct2/network/NetworkConnection.h | 1 + 3 files changed, 167 insertions(+), 107 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 83ebc4c02f..253e021f0d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -38,6 +38,7 @@ - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. +- Fix: [#9124] Disconnected clients can crash the server. - Fix: [#9132] System file browser cannot open SV4 files. - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 837a7fc606..5f5e137aba 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 "30" +#define NETWORK_STREAM_VERSION "31" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; @@ -133,6 +133,7 @@ public: void ProcessPending(); void ProcessPlayerList(); void ProcessPlayerInfo(); + void ProcessDisconnectedClients(); void ProcessGameCommands(); void EnqueueGameAction(const GameAction* action); std::vector>::iterator GetPlayerIteratorByID(uint8_t id); @@ -148,7 +149,7 @@ public: NetworkServerState_t GetServerState() const; void KickPlayer(int32_t playerId); void SetPassword(const char* password); - void ShutdownClient(); + void ServerClientDisconnected(); NetworkGroup* AddGroup(); void RemoveGroup(uint8_t id); uint8_t GetDefaultGroup(); @@ -224,8 +225,9 @@ private: bool ProcessConnection(NetworkConnection& connection); void ProcessPacket(NetworkConnection& connection, NetworkPacket& packet); void AddClient(std::unique_ptr&& socket); - void RemoveClient(std::unique_ptr& connection); + void ServerClientDisconnected(std::unique_ptr& connection); + void RemovePlayer(std::unique_ptr& connection); NetworkPlayer* AddPlayer(const std::string& name, const std::string& keyhash); std::string MakePlayerNameUnique(const std::string& name); @@ -286,18 +288,9 @@ private: struct PlayerListUpdate { - uint32_t tick = 0; std::vector players; - - void reset() - { - tick = 0; - players.clear(); - } }; - PlayerListUpdate _pendingPlayerList; - struct ServerTickData_t { uint32_t srand0; @@ -306,7 +299,9 @@ private: }; std::map _serverTickData; + std::map _pendingPlayerLists; std::multimap _pendingPlayerInfo; + bool _playerListInvalidated = false; int32_t mode = NETWORK_MODE_NONE; int32_t status = NETWORK_STATUS_NONE; bool _closeLock = false; @@ -484,7 +479,8 @@ void Network::Close() game_command_queue.clear(); player_list.clear(); group_list.clear(); - _pendingPlayerList.reset(); + _serverTickData.clear(); + _pendingPlayerLists.clear(); _pendingPlayerInfo.clear(); gfx_invalidate_screen(); @@ -774,18 +770,19 @@ void Network::Flush() void Network::UpdateServer() { - auto it = client_connection_list.begin(); - while (it != client_connection_list.end()) + for (auto& connection : client_connection_list) { - if (!ProcessConnection(*(*it))) + // This can be called multiple times before the connection is removed. + if (connection->IsDisconnected) + continue; + + if (!ProcessConnection(*connection)) { - RemoveClient((*it)); - it = client_connection_list.begin(); + connection->IsDisconnected = true; } else { - DecayCooldown((*it)->Player); - it++; + DecayCooldown(connection->Player); } } @@ -983,6 +980,12 @@ void Network::SendPacketToClients(NetworkPacket& packet, bool front, bool gameCm { for (auto& client_connection : client_connection_list) { + if (client_connection->IsDisconnected) + { + // Client will be removed at the end of the tick, don't bother. + continue; + } + if (gameCmd) { // If marked as game command we can not send the packet to connections that are not fully connected. @@ -1097,7 +1100,7 @@ void Network::SetPassword(const char* password) _password = password == nullptr ? "" : password; } -void Network::ShutdownClient() +void Network::ServerClientDisconnected() { if (GetMode() == NETWORK_MODE_CLIENT) { @@ -1956,63 +1959,89 @@ void Network::ProcessPacket(NetworkConnection& connection, NetworkPacket& packet packet.Clear(); } +// This is called at the end of each game tick, this where things should be processed that affects the game state. void Network::ProcessPending() { ProcessGameCommands(); + if (GetMode() == NETWORK_MODE_SERVER) + { + ProcessDisconnectedClients(); + } + else if (GetMode() == NETWORK_MODE_CLIENT) + { + ProcessPlayerInfo(); + } ProcessPlayerList(); - ProcessPlayerInfo(); } void Network::ProcessPlayerList() { - if (_pendingPlayerList.tick == 0 || _pendingPlayerList.tick < gCurrentTicks) + if (GetMode() == NETWORK_MODE_SERVER) { - return; - } - - // List of active players found in the list. - std::vector activePlayerIds; - - for (auto&& pendingPlayer : _pendingPlayerList.players) - { - activePlayerIds.push_back(pendingPlayer.Id); - - auto* player = GetPlayerByID(pendingPlayer.Id); - if (player == nullptr) + // Avoid sending multiple times the player list, we mark the list invalidated on modifications + // and then send at the end of the tick the final player list. + if (_playerListInvalidated) { - // Add new player. - player = AddPlayer("", ""); - if (player) + _playerListInvalidated = false; + Server_Send_PLAYERLIST(); + } + } + else + { + // As client we have to keep things in order so the update is tick bound. + // Commands/Actions reference players and so this list needs to be in sync with those. + auto itPending = _pendingPlayerLists.begin(); + while (itPending != _pendingPlayerLists.end()) + { + if (itPending->first > gCurrentTicks) + break; + + // List of active players found in the list. + std::vector activePlayerIds; + + for (auto&& pendingPlayer : itPending->second.players) { - *player = pendingPlayer; - if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) + activePlayerIds.push_back(pendingPlayer.Id); + + auto* player = GetPlayerByID(pendingPlayer.Id); + if (player == nullptr) { - _serverConnection->Player = player; + // Add new player. + player = AddPlayer("", ""); + if (player) + { + *player = pendingPlayer; + if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) + { + _serverConnection->Player = player; + } + } + } + else + { + // Update. + *player = pendingPlayer; } } - } - else - { - // Update. - *player = pendingPlayer; + + // Remove any players that are not in newly received list + auto it = player_list.begin(); + while (it != player_list.end()) + { + if (std::find(activePlayerIds.begin(), activePlayerIds.end(), (*it)->Id) == activePlayerIds.end()) + { + it = player_list.erase(it); + } + else + { + it++; + } + } + + _pendingPlayerLists.erase(itPending); + itPending = _pendingPlayerLists.begin(); } } - - // Remove any players that are not in newly received list - auto it = player_list.begin(); - while (it != player_list.end()) - { - if (std::find(activePlayerIds.begin(), activePlayerIds.end(), (*it)->Id) == activePlayerIds.end()) - { - it = player_list.erase(it); - } - else - { - it++; - } - } - - _pendingPlayerList.reset(); } void Network::ProcessPlayerInfo() @@ -2035,6 +2064,31 @@ void Network::ProcessPlayerInfo() _pendingPlayerInfo.erase(gCurrentTicks); } +void Network::ProcessDisconnectedClients() +{ + for (auto it = client_connection_list.begin(); it != client_connection_list.end();) + { + auto& connection = *it; + if (connection->IsDisconnected) + { + ServerClientDisconnected(connection); + RemovePlayer(connection); + + it = client_connection_list.erase(it); + } + else + { + it++; + } + } + + if (gConfigNetwork.pause_server_if_no_clients && game_is_not_paused() && client_connection_list.empty()) + { + auto pauseToggleAction = PauseToggleAction(); + GameActions::Execute(&pauseToggleAction); + } +} + void Network::ProcessGameCommands() { while (game_command_queue.begin() != game_command_queue.end()) @@ -2168,53 +2222,57 @@ void Network::AddClient(std::unique_ptr&& socket) client_connection_list.push_back(std::move(connection)); } -void Network::RemoveClient(std::unique_ptr& connection) +void Network::ServerClientDisconnected(std::unique_ptr& connection) { NetworkPlayer* connection_player = connection->Player; - if (connection_player) + if (connection_player == nullptr) + return; + + char text[256]; + const char* has_disconnected_args[2] = { + connection_player->Name.c_str(), + connection->GetLastDisconnectReason(), + }; + if (has_disconnected_args[1]) { - char text[256]; - const char* has_disconnected_args[2] = { - connection_player->Name.c_str(), - connection->GetLastDisconnectReason(), - }; - if (has_disconnected_args[1]) - { - format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, has_disconnected_args); - } - else - { - format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, &(has_disconnected_args[0])); - } - - chat_history_add(text); - Peep* pickup_peep = network_get_pickup_peep(connection_player->Id); - if (pickup_peep) - { - game_command_playerid = connection_player->Id; - game_do_command( - pickup_peep->sprite_index, GAME_COMMAND_FLAG_APPLY, 1, 0, - pickup_peep->type == PEEP_TYPE_GUEST ? GAME_COMMAND_PICKUP_GUEST : GAME_COMMAND_PICKUP_STAFF, - network_get_pickup_peep_old_x(connection_player->Id), 0); - } - gNetwork.Server_Send_EVENT_PLAYER_DISCONNECTED( - (char*)connection_player->Name.c_str(), connection->GetLastDisconnectReason()); - - // Log player disconnected event - AppendServerLog(text); + format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, has_disconnected_args); } + else + { + format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, &(has_disconnected_args[0])); + } + + chat_history_add(text); + Peep* pickup_peep = network_get_pickup_peep(connection_player->Id); + if (pickup_peep) + { + game_command_playerid = connection_player->Id; + game_do_command( + pickup_peep->sprite_index, GAME_COMMAND_FLAG_APPLY, 1, 0, + pickup_peep->type == PEEP_TYPE_GUEST ? GAME_COMMAND_PICKUP_GUEST : GAME_COMMAND_PICKUP_STAFF, + network_get_pickup_peep_old_x(connection_player->Id), 0); + } + gNetwork.Server_Send_EVENT_PLAYER_DISCONNECTED( + (char*)connection_player->Name.c_str(), connection->GetLastDisconnectReason()); + + // Log player disconnected event + AppendServerLog(text); +} + +void Network::RemovePlayer(std::unique_ptr& connection) +{ + NetworkPlayer* connection_player = connection->Player; + if (connection_player == nullptr) + return; + player_list.erase( std::remove_if( player_list.begin(), player_list.end(), [connection_player](std::unique_ptr& player) { return player.get() == connection_player; }), player_list.end()); - client_connection_list.remove(connection); - if (gConfigNetwork.pause_server_if_no_clients && game_is_not_paused() && client_connection_list.empty()) - { - auto pauseToggleAction = PauseToggleAction(); - GameActions::Execute(&pauseToggleAction); - } - Server_Send_PLAYERLIST(); + + // Send new player list. + _playerListInvalidated = true; } NetworkPlayer* Network::AddPlayer(const std::string& name, const std::string& keyhash) @@ -2267,6 +2325,9 @@ NetworkPlayer* Network::AddPlayer(const std::string& name, const std::string& ke player->Group = networkUser->GroupId.GetValueOrDefault(GetDefaultGroup()); player->SetName(networkUser->Name); } + + // Send new player list. + _playerListInvalidated = true; } else { @@ -2482,8 +2543,6 @@ void Network::Server_Client_Joined(const char* name, const std::string& keyhash, player_name = (const char*)playerNameHash.c_str(); format_string(text, 256, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &player_name); AppendServerLog(text); - - Server_Send_PLAYERLIST(); } } @@ -2645,7 +2704,6 @@ void Network::Server_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket Server_Send_MAP(&connection); Server_Send_EVENT_PLAYER_JOINED(player_name); Server_Send_GROUPLIST(connection); - Server_Send_PLAYERLIST(); } void Network::Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& packet) @@ -3190,15 +3248,15 @@ void Network::Client_Handle_PLAYERLIST([[maybe_unused]] NetworkConnection& conne uint8_t size; packet >> tick >> size; - _pendingPlayerList.reset(); - _pendingPlayerList.tick = tick; + auto& pending = _pendingPlayerLists[tick]; + pending.players.clear(); for (uint32_t i = 0; i < size; i++) { NetworkPlayer tempplayer; tempplayer.Read(packet); - _pendingPlayerList.players.push_back(tempplayer); + pending.players.push_back(tempplayer); } } @@ -3364,7 +3422,7 @@ void network_reconnect() void network_shutdown_client() { - gNetwork.ShutdownClient(); + gNetwork.ServerClientDisconnected(); } int32_t network_begin_client(const std::string& host, int32_t port) diff --git a/src/openrct2/network/NetworkConnection.h b/src/openrct2/network/NetworkConnection.h index 2872ac6b6f..26803aff16 100644 --- a/src/openrct2/network/NetworkConnection.h +++ b/src/openrct2/network/NetworkConnection.h @@ -35,6 +35,7 @@ public: NetworkKey Key; std::vector Challenge; std::vector RequestedObjects; + bool IsDisconnected = false; NetworkConnection(); ~NetworkConnection(); From 00c4b393a3f82bcca4697cb258dec7446e494966 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 15 May 2019 19:47:18 +0100 Subject: [PATCH 390/506] Take care of default case --- src/openrct2/actions/ScenarioSetSettingAction.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/openrct2/actions/ScenarioSetSettingAction.hpp b/src/openrct2/actions/ScenarioSetSettingAction.hpp index cbfd2fe8ad..230854a5d2 100644 --- a/src/openrct2/actions/ScenarioSetSettingAction.hpp +++ b/src/openrct2/actions/ScenarioSetSettingAction.hpp @@ -283,6 +283,10 @@ public: gParkFlags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION; } break; + default: + log_error("Invalid setting: %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + break; } window_invalidate_by_class(WC_EDITOR_SCENARIO_OPTIONS); return MakeResult(); From bbcc69270d279420eebfc3b96d44ca03c81c5287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 15 May 2019 21:09:01 +0200 Subject: [PATCH 391/506] Ensure finances window's months don't overflow (#8686) Some functions (e.g. window_finances_summary_scrollpaint) will try using the returned index, which makes it overflow. --- src/openrct2-ui/windows/Finances.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 1322bb54e0..3c6ce80dd2 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -611,14 +611,14 @@ static void window_finances_summary_mousedown(rct_window* w, rct_widgetindex wid } } -static uint16_t summary_num_months_available() +static uint16_t summary_max_available_month() { - return std::min(gDateMonthsElapsed, EXPENDITURE_TABLE_MONTH_COUNT); + return std::min(gDateMonthsElapsed, EXPENDITURE_TABLE_MONTH_COUNT - 1); } static void window_finances_summary_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) { - *width = EXPENDITURE_COLUMN_WIDTH * (summary_num_months_available() + 1); + *width = EXPENDITURE_COLUMN_WIDTH * (summary_max_available_month() + 1); } static void window_finances_summary_invertscroll(rct_window* w) @@ -737,7 +737,7 @@ static void window_finances_summary_scrollpaint(rct_window* w, rct_drawpixelinfo // Expenditure / Income values for each month int16_t currentMonthYear = gDateMonthsElapsed; - for (int32_t i = summary_num_months_available(); i >= 0; i--) + for (int32_t i = summary_max_available_month(); i >= 0; i--) { y = 0; From 77d0c07d2c3622243bb4d1685f31e73dff2e3a5e Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 15 May 2019 22:31:25 +0200 Subject: [PATCH 392/506] Add #9067 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 253e021f0d..9e996b585c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -38,6 +38,7 @@ - Fix: [#8947] Detection of AVX2 support. - Fix: [#8988] Character sprite lookup noticeably slows down drawing. - Fix: [#9000] Show correct error message if not enough money available. +- Fix: [#9067] Land/water tools show prices when money is disabled. - Fix: [#9124] Disconnected clients can crash the server. - Fix: [#9132] System file browser cannot open SV4 files. - Fix: [#9152] Spectators can modify ride colours. From f39c3fdb1ae1c733c0db72a6d038b1ecc31ea719 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 15 May 2019 22:33:51 +0200 Subject: [PATCH 393/506] Add #8480 and #8535 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9e996b585c..921b652446 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -27,6 +27,7 @@ - Fix: [#7700, #8079, #8969] Crash when unloading buggy custom rides. - Fix: [#7878] Scroll shortcut keys ignore SHIFT/CTRL/ALT modifiers. - Fix: [#8219] Faulty folder recreation in "save" folder. +- Fix: [#8480, #8535] Crash when mirroring track design. - Fix: [#8507] Incorrect change in vehicle rolling direction. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8598] Taking screenshots fails with some park names. From f7bd6d516a52bd395849e40bbfaa9cf47f33a905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 16 May 2019 09:05:09 +0200 Subject: [PATCH 394/506] Fix #9267: Only check if a file is a directory before opening it (#9269) --- src/openrct2/core/FileStream.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/openrct2/core/FileStream.hpp b/src/openrct2/core/FileStream.hpp index c2bc81c918..0839b9994f 100644 --- a/src/openrct2/core/FileStream.hpp +++ b/src/openrct2/core/FileStream.hpp @@ -76,9 +76,16 @@ public: free(pathW); free(modeW); #else - struct stat fileStat; - // Only allow regular files to be opened as its possible to open directories. - if (stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) + if (fileMode == FILE_MODE_OPEN) + { + struct stat fileStat; + // Only allow regular files to be opened as its possible to open directories. + if (stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) + { + _file = fopen(path, mode); + } + } + else { _file = fopen(path, mode); } From 6b232f7e537b45e4919fd1bb9f5f7e1861ee15fe Mon Sep 17 00:00:00 2001 From: nexgenration Date: Sat, 18 May 2019 04:47:25 -0400 Subject: [PATCH 395/506] Fix#9197: Peep insert new thought (#9230) Improve the readability of the codebase by moving functions into the relevant structures. - Change name of peep_insert_new_thought to InsertNewThought. - Update InsertNewThought definition to Guest::InsertNewThought. --- src/openrct2-ui/windows/Guest.cpp | 2 +- src/openrct2/peep/Guest.cpp | 76 ++++++++++----------- src/openrct2/peep/Peep.cpp | 110 +++++++++++++++--------------- src/openrct2/peep/Peep.h | 8 +-- src/openrct2/ride/Vehicle.cpp | 2 +- 5 files changed, 96 insertions(+), 102 deletions(-) diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 41bf1dbb3a..befd243a37 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1188,7 +1188,7 @@ void window_guest_overview_update(rct_window* w) int32_t random = util_rand() & 0xFFFF; if (random <= 0x2AAA) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_WATCHED, PEEP_THOUGHT_ITEM_NONE); } } } diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 3ea536e340..56e99a1375 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -382,7 +382,7 @@ void Guest::Tick128UpdateGuest(int32_t index) PeepThoughtType thought_type = crowded_thoughts[scenario_rand() & 0xF]; if (thought_type != PEEP_THOUGHT_TYPE_NONE) { - peep_insert_new_thought(this, thought_type, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(thought_type, PEEP_THOUGHT_ITEM_NONE); } } @@ -443,7 +443,7 @@ void Guest::Tick128UpdateGuest(int32_t index) if (thought_type != PEEP_THOUGHT_TYPE_NONE) { - peep_insert_new_thought(this, thought_type, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(thought_type, PEEP_THOUGHT_ITEM_NONE); happiness_target = std::min(PEEP_MAX_HAPPINESS, happiness_target + 45); } } @@ -458,7 +458,7 @@ void Guest::Tick128UpdateGuest(int32_t index) if (peep_flags & PEEP_FLAGS_WOW) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_WOW2, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_WOW2, PEEP_THOUGHT_ITEM_NONE); } if (time_on_ride > 15) @@ -473,7 +473,7 @@ void Guest::Tick128UpdateGuest(int32_t index) ? PEEP_THOUGHT_TYPE_GET_OUT : PEEP_THOUGHT_TYPE_GET_OFF; - peep_insert_new_thought(this, thought_type, current_ride); + InsertNewThought(thought_type, current_ride); } } } @@ -560,7 +560,7 @@ void Guest::Tick128UpdateGuest(int32_t index) { PeepThoughtType chosen_thought = possible_thoughts[scenario_rand() % num_thoughts]; - peep_insert_new_thought(this, chosen_thought, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(chosen_thought, PEEP_THOUGHT_ITEM_NONE); switch (chosen_thought) { @@ -596,7 +596,7 @@ void Guest::Tick128UpdateGuest(int32_t index) thought_type = PEEP_THOUGHT_TYPE_VERY_SICK; peep_head_for_nearest_ride_type(this, RIDE_TYPE_FIRST_AID); } - peep_insert_new_thought(this, thought_type, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(thought_type, PEEP_THOUGHT_ITEM_NONE); } } @@ -1087,7 +1087,7 @@ void Guest::CheckIfLost() return; time_lost = 230; } - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_LOST, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_LOST, PEEP_THOUGHT_ITEM_NONE); happiness_target = std::max(happiness_target - 30, 0); } @@ -1105,7 +1105,7 @@ void Guest::CheckCantFindRide() // Peeps will think "I can't find ride X" twice before giving up completely. if (peep_is_lost_countdown == 30 || peep_is_lost_countdown == 60) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_CANT_FIND, guest_heading_to_ride_id); + InsertNewThought(PEEP_THOUGHT_TYPE_CANT_FIND, guest_heading_to_ride_id); happiness_target = std::max(happiness_target - 30, 0); } @@ -1137,7 +1137,7 @@ void Guest::CheckCantFindExit() // Peeps who can't find the park exit will continue to get less happy until they find it. if (peep_is_lost_countdown == 1) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_CANT_FIND_EXIT, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_CANT_FIND_EXIT, PEEP_THOUGHT_ITEM_NONE); happiness_target = std::max(happiness_target - 30, 0); } @@ -1172,7 +1172,7 @@ bool Guest::DecideAndBuyItem(Ride* ride, int32_t shopItem, money32 price) if (HasItem(shopItem)) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_ALREADY_GOT, shopItem); + InsertNewThought(PEEP_THOUGHT_TYPE_ALREADY_GOT, shopItem); return false; } @@ -1181,12 +1181,12 @@ bool Guest::DecideAndBuyItem(Ride* ride, int32_t shopItem, money32 price) int32_t food = -1; if ((food = HasFoodStandardFlag()) != 0) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_HAVENT_FINISHED, bitscanforward(food)); + InsertNewThought(PEEP_THOUGHT_TYPE_HAVENT_FINISHED, bitscanforward(food)); return false; } else if ((food = HasFoodExtraFlag()) != 0) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_HAVENT_FINISHED, bitscanforward(food) + 32); + InsertNewThought(PEEP_THOUGHT_TYPE_HAVENT_FINISHED, bitscanforward(food) + 32); return false; } else if (nausea >= 145) @@ -1208,13 +1208,13 @@ bool Guest::DecideAndBuyItem(Ride* ride, int32_t shopItem, money32 price) if (shop_item_is_food(shopItem) && (hunger > 75)) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NOT_HUNGRY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_NOT_HUNGRY, PEEP_THOUGHT_ITEM_NONE); return false; } if (shop_item_is_drink(shopItem) && (thirst > 75)) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NOT_THIRSTY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_NOT_THIRSTY, PEEP_THOUGHT_ITEM_NONE); return false; } @@ -1236,12 +1236,12 @@ loc_69B119: { if (cash_in_pocket == 0) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); return false; } if (price > cash_in_pocket) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_CANT_AFFORD, shopItem); + InsertNewThought(PEEP_THOUGHT_TYPE_CANT_AFFORD, shopItem); return false; } } @@ -1275,7 +1275,7 @@ loc_69B119: PeepThoughtType thought_type = static_cast( (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2_MUCH + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON_MUCH + shopItem))); - peep_insert_new_thought(this, thought_type, ride->id); + InsertNewThought(thought_type, ride->id); return false; } } @@ -1292,7 +1292,7 @@ loc_69B119: PeepThoughtType thought_item = static_cast( (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2 + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON + shopItem))); - peep_insert_new_thought(this, thought_item, ride->id); + InsertNewThought(thought_item, ride->id); } } @@ -1498,7 +1498,7 @@ void Guest::OnExitRide(ride_id_t rideIndex) if (peep_really_liked_ride(this, ride)) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_WAS_GREAT, rideIndex); + InsertNewThought(PEEP_THOUGHT_TYPE_WAS_GREAT, rideIndex); int32_t laugh = scenario_rand() & 7; if (laugh < 3) @@ -1744,11 +1744,11 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (cash_in_pocket <= 0) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); } else { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_CANT_AFFORD_0, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_CANT_AFFORD_0, ride->id); } } ChoseNotToGoOnRide(ride, peepAtRide, true); @@ -1761,7 +1761,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (peepAtRide) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NOT_SAFE, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_NOT_SAFE, ride->id); if (happiness_target >= 64) { happiness_target -= 8; @@ -1791,7 +1791,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (peepAtRide) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NOT_WHILE_RAINING, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_NOT_WHILE_RAINING, ride->id); if (happiness_target >= 64) { happiness_target -= 8; @@ -1813,7 +1813,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (peepAtRide) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_MORE_THRILLING, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_MORE_THRILLING, ride->id); if (happiness_target >= 64) { happiness_target -= 8; @@ -1836,7 +1836,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (peepAtRide) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SICKENING, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_SICKENING, ride->id); if (happiness_target >= 64) { happiness_target -= 8; @@ -1892,7 +1892,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (peepAtRide) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_BAD_VALUE, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_BAD_VALUE, ride->id); if (happiness_target >= 60) { happiness_target -= 16; @@ -1910,7 +1910,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t { if (!(peep_flags & PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY)) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_GOOD_VALUE, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_GOOD_VALUE, ride->id); } } } @@ -1959,7 +1959,7 @@ bool Guest::ShouldGoToShop(Ride* ride, bool peepAtShop) { if (peepAtShop) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NOT_PAYING, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_NOT_PAYING, ride->id); if (happiness_target >= 60) { happiness_target -= 16; @@ -1987,11 +1987,11 @@ bool Guest::ShouldGoToShop(Ride* ride, bool peepAtShop) { if (cash_in_pocket <= 0) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); } else { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_CANT_AFFORD_0, ride->id); + InsertNewThought(PEEP_THOUGHT_TYPE_CANT_AFFORD_0, ride->id); } } ChoseNotToGoOnRide(ride, peepAtShop, true); @@ -2128,7 +2128,7 @@ static void peep_ride_is_too_intense(Guest* peep, Ride* ride, bool peepAtRide) { if (peepAtRide) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_INTENSE, ride->id); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_INTENSE, ride->id); if (peep->happiness_target >= 64) { peep->happiness_target -= 8; @@ -2329,14 +2329,14 @@ static bool peep_check_ride_price_at_entrance(Guest* peep, Ride* ride, money32 r if (peep->cash_in_pocket <= 0) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_SPENT_MONEY, PEEP_THOUGHT_ITEM_NONE); peep_update_ride_at_entrance_try_leave(peep); return false; } if (ridePrice > peep->cash_in_pocket) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CANT_AFFORD_0, peep->current_ride); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_CANT_AFFORD_0, peep->current_ride); peep_update_ride_at_entrance_try_leave(peep); return false; } @@ -2346,7 +2346,7 @@ static bool peep_check_ride_price_at_entrance(Guest* peep, Ride* ride, money32 r { if (value * 2 < ridePrice) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_BAD_VALUE, peep->current_ride); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_BAD_VALUE, peep->current_ride); peep_update_ride_at_entrance_try_leave(peep); return false; } @@ -2817,7 +2817,7 @@ static void peep_leave_park(Peep* peep) peep->peep_flags &= ~PEEP_FLAGS_PARK_ENTRANCE_CHOSEN; } - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_GO_HOME, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_GO_HOME, PEEP_THOUGHT_ITEM_NONE); rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); if (w != nullptr) @@ -5384,11 +5384,11 @@ void Guest::UpdateWalking() if (current_seat & 1) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NEW_RIDE, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_NEW_RIDE, PEEP_THOUGHT_ITEM_NONE); } if (current_ride == RIDE_ID_NULL) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SCENERY, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_SCENERY, PEEP_THOUGHT_ITEM_NONE); } } @@ -5463,7 +5463,7 @@ void Guest::UpdateQueuing() if (time_in_queue >= 3500 && (0xFFFF & scenario_rand()) <= 93) { // Create the I have been waiting in line ages thought - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_QUEUING_AGES, current_ride); + InsertNewThought(PEEP_THOUGHT_TYPE_QUEUING_AGES, current_ride); } } else diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index f07cdb69b9..85c3d4284a 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1074,7 +1074,7 @@ void Peep::UpdateFalling() peep_release_balloon(guest, height); } - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_DROWNING, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_DROWNING, PEEP_THOUGHT_ITEM_NONE); action = PEEP_ACTION_DROWNING; action_frame = 0; @@ -1173,7 +1173,7 @@ void Peep::UpdatePicked() sub_state++; if (sub_state == 13) { - peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_HELP, PEEP_THOUGHT_ITEM_NONE); + InsertNewThought(PEEP_THOUGHT_TYPE_HELP, PEEP_THOUGHT_ITEM_NONE); } } @@ -1704,6 +1704,55 @@ static constexpr const uint8_t tshirt_colours[] = { }; // clang-format on +/** + * + * rct2: 0x699F5A + * al:thoughtType + * ah:thoughtArguments + * esi: peep + */ +void Peep::InsertNewThought(PeepThoughtType thoughtType, uint8_t thoughtArguments) +{ + PeepActionType newAction = PeepThoughtToActionMap[thoughtType].action; + if (newAction != PEEP_ACTION_NONE_2 && this->action >= PEEP_ACTION_NONE_1) + { + action = newAction; + action_frame = 0; + action_sprite_image_offset = 0; + UpdateCurrentActionSpriteType(); + Invalidate(); + } + + for (int32_t i = 0; i < PEEP_MAX_THOUGHTS; ++i) + { + rct_peep_thought* thought = &thoughts[i]; + // Remove the oldest thought by setting it to NONE. + if (thought->type == PEEP_THOUGHT_TYPE_NONE) + break; + + if (thought->type == thoughtType && thought->item == thoughtArguments) + { + // If the thought type has not changed then we need to move + // it to the top of the thought list. This is done by first removing the + // existing thought and placing it at the top. + if (i < PEEP_MAX_THOUGHTS - 2) + { + memmove(thought, thought + 1, sizeof(rct_peep_thought) * (PEEP_MAX_THOUGHTS - i - 1)); + } + break; + } + } + + memmove(&thoughts[1], &thoughts[0], sizeof(rct_peep_thought) * (PEEP_MAX_THOUGHTS - 1)); + + thoughts[0].type = thoughtType; + thoughts[0].item = thoughtArguments; + thoughts[0].freshness = 0; + thoughts[0].fresh_timeout = 0; + + window_invalidate_flags |= PEEP_INVALIDATE_PEEP_THOUGHTS; +} + /** * * rct2: 0x0069A05D @@ -2229,55 +2278,6 @@ int32_t peep_get_easteregg_name_id(Peep* peep) return -1; } -/** - * - * rct2: 0x699F5A - * al:thought_type - * ah:thought_arguments - * esi: peep - */ -void peep_insert_new_thought(Peep* peep, PeepThoughtType thought_type, uint8_t thought_arguments) -{ - PeepActionType action = PeepThoughtToActionMap[thought_type].action; - if (action != PEEP_ACTION_NONE_2 && peep->action >= PEEP_ACTION_NONE_1) - { - peep->action = action; - peep->action_frame = 0; - peep->action_sprite_image_offset = 0; - peep->UpdateCurrentActionSpriteType(); - peep->Invalidate(); - } - - for (int32_t i = 0; i < PEEP_MAX_THOUGHTS; ++i) - { - rct_peep_thought* thought = &peep->thoughts[i]; - // Remove the oldest thought by setting it to NONE. - if (thought->type == PEEP_THOUGHT_TYPE_NONE) - break; - - if (thought->type == thought_type && thought->item == thought_arguments) - { - // If the thought type has not changed then we need to move - // it to the top of the thought list. This is done by first removing the - // existing thought and placing it at the top. - if (i < PEEP_MAX_THOUGHTS - 2) - { - memmove(thought, thought + 1, sizeof(rct_peep_thought) * (PEEP_MAX_THOUGHTS - i - 1)); - } - break; - } - } - - memmove(&peep->thoughts[1], &peep->thoughts[0], sizeof(rct_peep_thought) * (PEEP_MAX_THOUGHTS - 1)); - - peep->thoughts[0].type = thought_type; - peep->thoughts[0].item = thought_arguments; - peep->thoughts[0].freshness = 0; - peep->thoughts[0].fresh_timeout = 0; - - peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_THOUGHTS; -} - void peep_set_map_tooltip(Peep* peep) { if (peep->type == PEEP_TYPE_GUEST) @@ -2745,7 +2745,7 @@ static void peep_footpath_move_forward(Peep* peep, int16_t x, int16_t y, TileEle { if ((scenario_rand() & 0xFFFF) <= 10922) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_VANDALISM, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_VANDALISM, PEEP_THOUGHT_ITEM_NONE); peep->happiness_target = std::max(0, peep->happiness_target - 17); } vandalThoughtTimeout = 3; @@ -2793,7 +2793,7 @@ static void peep_footpath_move_forward(Peep* peep, int16_t x, int16_t y, TileEle if (crowded >= 10 && peep->state == PEEP_STATE_WALKING && (scenario_rand() & 0xFFFF) <= 21845) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CROWDED, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_CROWDED, PEEP_THOUGHT_ITEM_NONE); peep->happiness_target = std::max(0, peep->happiness_target - 14); } @@ -2819,7 +2819,7 @@ static void peep_footpath_move_forward(Peep* peep, int16_t x, int16_t y, TileEle if (total_sick >= 3 && (scenario_rand() & 0xFFFF) <= 10922) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_PATH_DISGUSTING, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_PATH_DISGUSTING, PEEP_THOUGHT_ITEM_NONE); peep->happiness_target = std::max(0, peep->happiness_target - 17); // Reset disgusting time peep->disgusting_count |= 0xC0; @@ -2845,7 +2845,7 @@ static void peep_footpath_move_forward(Peep* peep, int16_t x, int16_t y, TileEle if (total_litter >= 3 && (scenario_rand() & 0xFFFF) <= 10922) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_BAD_LITTER, PEEP_THOUGHT_ITEM_NONE); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_BAD_LITTER, PEEP_THOUGHT_ITEM_NONE); peep->happiness_target = std::max(0, peep->happiness_target - 17); // Reset litter time peep->litter_count |= 0xC0; diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 439d2a4cff..56c8336cba 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -717,6 +717,7 @@ public: // Peep static Peep* Generate(const CoordsXYZ coords); void RemoveFromQueue(); void RemoveFromRide(); + void InsertNewThought(PeepThoughtType thought_type, uint8_t thought_arguments); // TODO: Make these private again when done refactoring public: // Peep @@ -959,13 +960,6 @@ void peep_sprite_remove(Peep* peep); void peep_window_state_update(Peep* peep); void peep_decrement_num_riders(Peep* peep); -/** - * rct2: 0x699F5A - * al:thought_type - * ah:thought_arguments - * esi: peep - */ -void peep_insert_new_thought(Peep* peep, PeepThoughtType thought_type, uint8_t thought_arguments); void peep_set_map_tooltip(Peep* peep); diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index c3bd1c5817..c6f812854f 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3042,7 +3042,7 @@ void vehicle_peep_easteregg_here_we_are(const rct_vehicle* vehicle) Peep* peep = GET_PEEP(vehicle->peep[i]); if (peep->peep_flags & PEEP_FLAGS_HERE_WE_ARE) { - peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_HERE_WE_ARE, peep->current_ride); + peep->InsertNewThought(PEEP_THOUGHT_TYPE_HERE_WE_ARE, peep->current_ride); } } } while ((spriteId = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL); From d7074e65a2cb25cf6d941e1ed9530f5aeb093217 Mon Sep 17 00:00:00 2001 From: James Warwood Date: Sat, 18 May 2019 10:43:06 +0100 Subject: [PATCH 396/506] Fix: Staff patrol areas getting clobbered when hiring new staff (#9271) Fixed incorrect indexing when resetting staff patrol areas during hiring process. --- src/openrct2/actions/StaffHireNewAction.hpp | 4 ++-- src/openrct2/network/Network.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index 4f27efc5aa..bf29df5300 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -260,9 +260,9 @@ private: gStaffModes[staffIndex] = STAFF_MODE_WALK; - for (int32_t newStaffIndex = 0; newStaffIndex < STAFF_PATROL_AREA_SIZE; newStaffIndex++) + for (int32_t i = 0; i < STAFF_PATROL_AREA_SIZE; i++) { - gStaffPatrolAreas[newStaffIndex * STAFF_PATROL_AREA_SIZE + newStaffId] = 0; + gStaffPatrolAreas[staffIndex * STAFF_PATROL_AREA_SIZE + i] = 0; } res->peepSriteIndex = newPeep->sprite_index; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index da10395c96..dd48e71827 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 "31" +#define NETWORK_STREAM_VERSION "32" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 83511c5c7f5d7891458f4f5567215ec1f8e93f01 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 18 May 2019 19:45:12 +0200 Subject: [PATCH 397/506] Fix clients being behind one tick at all times --- src/openrct2/GameState.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index ebafbd0e3b..20a32182a2 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -230,10 +230,9 @@ void GameState::UpdateLogic() if (network_get_mode() == NETWORK_MODE_CLIENT && network_get_status() == NETWORK_STATUS_CONNECTED && network_get_authstatus() == NETWORK_AUTH_OK) { - // Can't be in sync with server, round trips won't work if we are at same level. - if (gCurrentTicks >= network_get_server_tick()) + // Don't run ahead of the server but can be on same tick. + if (gCurrentTicks > network_get_server_tick()) { - // Don't run past the server return; } } From 8389e5119bb58ff510f37897185baa670c8e6c0b Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 18 May 2019 19:57:51 +0200 Subject: [PATCH 398/506] Bump up 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 dd48e71827..da4054c254 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 "32" +#define NETWORK_STREAM_VERSION "33" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From ee79c11389ebf0c716c9f18d3eb2af80ec023478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 19 May 2019 17:44:43 +0200 Subject: [PATCH 399/506] Fix desync when host changes map --- src/openrct2/Context.cpp | 10 ++++++++-- src/openrct2/network/Network.cpp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 59382c20d9..7e1e6927b7 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -545,6 +545,8 @@ namespace OpenRCT2 sprite_position_tween_reset(); gScreenAge = 0; gLastAutoSaveUpdate = AUTOSAVE_PAUSE; + + bool sendMap = false; if (info.Type == FILE_TYPE::SAVED_GAME) { if (network_get_mode() == NETWORK_MODE_CLIENT) @@ -554,7 +556,7 @@ namespace OpenRCT2 game_load_init(); if (network_get_mode() == NETWORK_MODE_SERVER) { - network_send_map(); + sendMap = true; } } else @@ -562,7 +564,7 @@ namespace OpenRCT2 scenario_begin(); if (network_get_mode() == NETWORK_MODE_SERVER) { - network_send_map(); + sendMap = true; } if (network_get_mode() == NETWORK_MODE_CLIENT) { @@ -572,6 +574,10 @@ namespace OpenRCT2 // This ensures that the newly loaded save reflects the user's // 'show real names of guests' option, now that it's a global setting peep_update_names(gConfigGeneral.show_real_names_of_guests); + if (sendMap) + { + network_send_map(); + } return true; } catch (const ObjectLoadException& e) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index da4054c254..8b3dae255b 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 "33" +#define NETWORK_STREAM_VERSION "34" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 65f110fad8f7aeadfdff4673a7c72017b0ac1a10 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 20 May 2019 04:00:22 +0000 Subject: [PATCH 400/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/da-DK.txt | 4 + data/language/en-US.txt | 779 +++------------------------------------- data/language/ko-KR.txt | 8 +- data/language/nl-NL.txt | 4 + 4 files changed, 61 insertions(+), 734 deletions(-) diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index aeb2da4688..02e57f55d0 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3788,6 +3788,10 @@ STR_6314 :{WINDOW_COLOUR_2}Dest: {BLACK}{INT32}, {INT32} tolerance {INT32} STR_6315 :{WINDOW_COLOUR_2}Stisøger Goal: {BLACK}{INT32}, {INT32}, {INT32} ret {INT32} STR_6316 :{WINDOW_COLOUR_2}Stisøger historie: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} ret {INT32} +STR_6318 :Netværks synkroniseringsfejl.{NEWLINE}Log fil: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Blok Bremse tilkoblet +STR_6320 :{WINDOW_COLOUR_2}Uforgængelig +STR_6321 :{WINDOW_COLOUR_2}Tilføjelse defekt ############# # Scenarios # diff --git a/data/language/en-US.txt b/data/language/en-US.txt index 97cb8211d3..cbfde7af19 100644 --- a/data/language/en-US.txt +++ b/data/language/en-US.txt @@ -22,8 +22,6 @@ STR_0574 :Riders are held in special harnesses in a lying-down position, trav STR_0976 :Restrooms and Information Kiosks -STR_1035 :Local authority won't allow construction above tree-height! - STR_1102 :Traveling at {VELOCITY} STR_1105 :Traveling at {VELOCITY} STR_1108 :Traveling at {VELOCITY} @@ -37,163 +35,16 @@ STR_1138 :{SMALLFONT}{BLACK}Select additional color 2 STR_1139 :{SMALLFONT}{BLACK}Select support structure color STR_1140 :{SMALLFONT}{BLACK}Select vehicle color scheme option -STR_1361 :Can't change speed... -STR_1362 :Can't change launch speed... -STR_1363 :Too high for supports! -STR_1364 :Supports for track above can't be extended any further! -STR_1365 :In-line Twist (left) -STR_1366 :In-line Twist (right) -STR_1367 :Half Loop -STR_1368 :Half Corkscrew (left) -STR_1369 :Half Corkscrew (right) -STR_1370 :Barrel Roll (left) -STR_1371 :Barrel Roll (right) -STR_1372 :Launched Lift Hill -STR_1373 :Large Half Loop (left) -STR_1374 :Large Half Loop (right) -STR_1375 :Upper Transfer -STR_1376 :Lower Transfer -STR_1377 :Heartline Roll (left) -STR_1378 :Heartline Roll (right) -STR_1379 :Reverser (left) -STR_1380 :Reverser (right) -STR_1381 :Curved Lift Hill (left) -STR_1382 :Curved Lift Hill (right) -STR_1383 :Quarter Loop -STR_1384 :{YELLOW}{STRINGID} -STR_1385 :{SMALLFONT}{BLACK}Other track configurations -STR_1386 :Special... -STR_1387 :Can't change land type... -STR_1388 :{OUTLINE}{GREEN}+ {CURRENCY} -STR_1389 :{OUTLINE}{RED}- {CURRENCY} -STR_1390 :{CURRENCY2DP} -STR_1391 :{RED}{CURRENCY2DP} -STR_1392 :{SMALLFONT}{BLACK}View of ride/attraction -STR_1393 :{SMALLFONT}{BLACK}Vehicle details and options -STR_1394 :{SMALLFONT}{BLACK}Operating options -STR_1395 :{SMALLFONT}{BLACK}Maintenance options STR_1396 :{SMALLFONT}{BLACK}Color scheme options -STR_1397 :{SMALLFONT}{BLACK}Sound & music options -STR_1398 :{SMALLFONT}{BLACK}Measurements and test data -STR_1399 :{SMALLFONT}{BLACK}Graphs -STR_1400 :Entrance -STR_1401 :Exit -STR_1402 :{SMALLFONT}{BLACK}Build or move entrance to ride/attraction -STR_1403 :{SMALLFONT}{BLACK}Build or move exit from ride/attraction -STR_1404 :{SMALLFONT}{BLACK}Rotate 90° -STR_1405 :{SMALLFONT}{BLACK}Mirror image -STR_1406 :{SMALLFONT}{BLACK}Toggle scenery on/off (if available for this design) -STR_1407 :{WINDOW_COLOUR_2}Build this... -STR_1408 :{WINDOW_COLOUR_2}Cost: {BLACK}{CURRENCY} -STR_1409 :Entry/Exit Platform -STR_1410 :Vertical Tower -STR_1411 :{STRINGID} in the way -STR_1412 :{WINDOW_COLOUR_3}Data logging not available for this type of ride -STR_1413 :{WINDOW_COLOUR_3}Data logging will start when next {STRINGID} leaves {STRINGID} -STR_1414 :{SMALLFONT}{BLACK}{DURATION} -STR_1415 :{WINDOW_COLOUR_2}Velocity -STR_1416 :{WINDOW_COLOUR_2}Altitude -STR_1417 :{WINDOW_COLOUR_2}Vert.G's -STR_1418 :{WINDOW_COLOUR_2}Lat.G's -STR_1419 :{SMALLFONT}{BLACK}{VELOCITY} -STR_1420 :{SMALLFONT}{BLACK}{LENGTH} -STR_1421 :{SMALLFONT}{BLACK}{COMMA16}g -STR_1422 :{SMALLFONT}{BLACK}Logging data from {POP16}{STRINGID} -STR_1423 :{SMALLFONT}{BLACK}Queue line path -STR_1424 :{SMALLFONT}{BLACK}Footpath -STR_1425 :Footpath -STR_1426 :Queue Line -STR_1427 :{WINDOW_COLOUR_2}Customers: {BLACK}{COMMA32} per hour -STR_1428 :{WINDOW_COLOUR_2}Admission price: -STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} -STR_1430 :Free -STR_1431 :Walking -STR_1432 :Heading for {STRINGID} -STR_1433 :Queuing for {STRINGID} -STR_1434 :Drowning -STR_1435 :On {STRINGID} -STR_1436 :In {STRINGID} -STR_1437 :At {STRINGID} -STR_1438 :Sitting -STR_1439 :(select location) -STR_1440 :Mowing grass -STR_1441 :Sweeping footpath + STR_1442 :Emptying trash can -STR_1443 :Watering gardens -STR_1444 :Watching {STRINGID} -STR_1445 :Watching construction of {STRINGID} -STR_1446 :Looking at scenery -STR_1447 :Leaving the park -STR_1448 :Watching new ride being constructed -STR_1449 :{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) -STR_1450 :{INLINE_SPRITE}{09}{20}{00}{00}{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) -STR_1451 :{STRINGID}{NEWLINE}({STRINGID}) -STR_1452 :Guest's name -STR_1453 :Enter name for this guest: -STR_1454 :Can't name guest... -STR_1455 :Invalid name for guest -STR_1456 :{WINDOW_COLOUR_2}Cash spent: {BLACK}{CURRENCY2DP} -STR_1457 :{WINDOW_COLOUR_2}Cash in pocket: {BLACK}{CURRENCY2DP} -STR_1458 :{WINDOW_COLOUR_2}Time in park: {BLACK}{REALTIME} -STR_1459 :Track style -STR_1460 :{SMALLFONT}{BLACK}'U' shaped open track -STR_1461 :{SMALLFONT}{BLACK}'O' shaped enclosed track -STR_1462 :Too steep for lift hill -STR_1463 :Guests -STR_1464 :Helix up (small) -STR_1465 :Helix up (large) -STR_1466 :Helix down (small) -STR_1467 :Helix down (large) -STR_1468 :Staff -STR_1469 :Ride must start and end with stations -STR_1470 :Station not long enough -STR_1471 :{WINDOW_COLOUR_2}Speed: -STR_1472 :{SMALLFONT}{BLACK}Speed of this ride -STR_1473 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1474 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}Not yet available -STR_1475 :{WINDOW_COLOUR_2}Intensity rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1476 :{WINDOW_COLOUR_2}Intensity rating: {BLACK}Not yet available -STR_1477 :{WINDOW_COLOUR_2}Intensity rating: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) -STR_1478 :{WINDOW_COLOUR_2}Nausea rating: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1479 :{WINDOW_COLOUR_2}Nausea rating: {BLACK}Not yet available -STR_1480 :{SMALLFONT}“I can't afford {STRINGID}” -STR_1481 :{SMALLFONT}“I've spent all my money” -STR_1482 :{SMALLFONT}“I feel sick” -STR_1483 :{SMALLFONT}“I feel very sick” -STR_1484 :{SMALLFONT}“I want to go on something more thrilling than {STRINGID}” -STR_1485 :{SMALLFONT}“{STRINGID} looks too intense for me” -STR_1486 :{SMALLFONT}“I haven't finished my {STRINGID} yet” -STR_1487 :{SMALLFONT}“Just looking at {STRINGID} makes me feel sick” -STR_1488 :{SMALLFONT}“I'm not paying that much to go on {STRINGID}” -STR_1489 :{SMALLFONT}“I want to go home” + STR_1490 :{SMALLFONT}“{STRINGID} is a really good value” -STR_1491 :{SMALLFONT}“I've already got {STRINGID}” -STR_1492 :{SMALLFONT}“I can't afford {STRINGID}” -STR_1493 :{SMALLFONT}“I'm not hungry” -STR_1494 :{SMALLFONT}“I'm not thirsty” -STR_1495 :{SMALLFONT}“Help! I'm drowning!” -STR_1496 :{SMALLFONT}“I'm lost!” -STR_1497 :{SMALLFONT}“{STRINGID} was great” -STR_1498 :{SMALLFONT}“I've been queuing for {STRINGID} for ages” -STR_1499 :{SMALLFONT}“I'm tired” -STR_1500 :{SMALLFONT}“I'm hungry” -STR_1501 :{SMALLFONT}“I'm thirsty” + STR_1502 :{SMALLFONT}“I need to go to the bathroom” -STR_1503 :{SMALLFONT}“I can't find {STRINGID}” -STR_1504 :{SMALLFONT}“I'm not paying that much to use {STRINGID}” -STR_1505 :{SMALLFONT}“I'm not going on {STRINGID} while it's raining” + STR_1506 :{SMALLFONT}“The trash here is really bad” -STR_1507 :{SMALLFONT}“I can't find the park exit” -STR_1508 :{SMALLFONT}“I want to get off {STRINGID}” -STR_1509 :{SMALLFONT}“I want to get out of {STRINGID}” -STR_1510 :{SMALLFONT}“I'm not going on {STRINGID} - It isn't safe” -STR_1511 :{SMALLFONT}“This path is disgusting” -STR_1512 :{SMALLFONT}“It's too crowded here” -STR_1513 :{SMALLFONT}“The vandalism here is really bad” -STR_1514 :{SMALLFONT}“Great scenery!” -STR_1515 :{SMALLFONT}“This park is really clean and tidy” -STR_1516 :{SMALLFONT}“The jumping fountains are great” -STR_1517 :{SMALLFONT}“The music is nice here” + STR_1518 :{SMALLFONT}“This balloon from {STRINGID} is a really good value” STR_1519 :{SMALLFONT}“This cuddly toy from {STRINGID} is a really good value” STR_1520 :{SMALLFONT}“This park map from {STRINGID} is a really good value” @@ -204,11 +55,9 @@ STR_1524 :{SMALLFONT}“This burger from {STRINGID} is a really good value” STR_1525 :{SMALLFONT}“These fries from {STRINGID} are a really good value” STR_1526 :{SMALLFONT}“This ice cream from {STRINGID} is a really good value” STR_1527 :{SMALLFONT}“This cotton candy from {STRINGID} is a really good value” -STR_1528 : -STR_1529 : -STR_1530 : + STR_1531 :{SMALLFONT}“This pizza from {STRINGID} is a really good value” -STR_1532 : + STR_1533 :{SMALLFONT}“This popcorn from {STRINGID} is a really good value” STR_1534 :{SMALLFONT}“This hot dog from {STRINGID} is a really good value” STR_1535 :{SMALLFONT}“This tentacle from {STRINGID} is a really good value” @@ -217,49 +66,18 @@ STR_1537 :{SMALLFONT}“This candy apple from {STRINGID} is a really good val STR_1538 :{SMALLFONT}“This T-shirt from {STRINGID} is a really good value” STR_1539 :{SMALLFONT}“This donut from {STRINGID} is a really good value” STR_1540 :{SMALLFONT}“This coffee from {STRINGID} is a really good value” -STR_1541 : + STR_1542 :{SMALLFONT}“This fried chicken from {STRINGID} is a really good value” STR_1543 :{SMALLFONT}“This lemonade from {STRINGID} is a really good value” -STR_1544 : -STR_1545 : -STR_1546 : -STR_1547 : -STR_1548 : -STR_1549 : -STR_1550 :{SMALLFONT}“Wow!” -STR_1551 :{SMALLFONT}“I have the strangest feeling someone is watching me” -STR_1552 :{SMALLFONT}“I'm not paying that much for a balloon from {STRINGID}” -STR_1553 :{SMALLFONT}“I'm not paying that much for a cuddly toy from {STRINGID}” -STR_1554 :{SMALLFONT}“I'm not paying that much for a park map from {STRINGID}” -STR_1555 :{SMALLFONT}“I'm not paying that much for an on-ride photo from {STRINGID}” -STR_1556 :{SMALLFONT}“I'm not paying that much for an umbrella from {STRINGID}” -STR_1557 :{SMALLFONT}“I'm not paying that much for a drink from {STRINGID}” -STR_1558 :{SMALLFONT}“I'm not paying that much for a burger from {STRINGID}” + STR_1559 :{SMALLFONT}“I'm not paying that much for fries from {STRINGID}” -STR_1560 :{SMALLFONT}“I'm not paying that much for an ice cream from {STRINGID}” + STR_1561 :{SMALLFONT}“I'm not paying that much for cotton candy from {STRINGID}” -STR_1562 : -STR_1563 : -STR_1564 : -STR_1565 :{SMALLFONT}“I'm not paying that much for pizza from {STRINGID}” -STR_1566 : -STR_1567 :{SMALLFONT}“I'm not paying that much for popcorn from {STRINGID}” -STR_1568 :{SMALLFONT}“I'm not paying that much for a hot dog from {STRINGID}” -STR_1569 :{SMALLFONT}“I'm not paying that much for tentacle from {STRINGID}” -STR_1570 :{SMALLFONT}“I'm not paying that much for a hat from {STRINGID}” + STR_1571 :{SMALLFONT}“I'm not paying that much for a candy apple from {STRINGID}” -STR_1572 :{SMALLFONT}“I'm not paying that much for a T-shirt from {STRINGID}” + STR_1573 :{SMALLFONT}“I'm not paying that much for a donut from {STRINGID}” -STR_1574 :{SMALLFONT}“I'm not paying that much for coffee from {STRINGID}” -STR_1575 : -STR_1576 :{SMALLFONT}“I'm not paying that much for fried chicken from {STRINGID}” -STR_1577 :{SMALLFONT}“I'm not paying that much for lemonade from {STRINGID}” -STR_1578 : -STR_1579 : -STR_1580 : -STR_1581 : -STR_1582 : -STR_1583 : + STR_1584 :{SMALLFONT}“This on-ride photo from {STRINGID} is a really good value” STR_1585 :{SMALLFONT}“This on-ride photo from {STRINGID} is a really good value” STR_1586 :{SMALLFONT}“This on-ride photo from {STRINGID} is a really good value” @@ -277,583 +95,80 @@ STR_1597 :{SMALLFONT}“This soybean milk from {STRINGID} is a really good va STR_1598 :{SMALLFONT}“This sujeonggwa from {STRINGID} is a really good value” STR_1599 :{SMALLFONT}“This sub sandwich from {STRINGID} is a really good value” STR_1600 :{SMALLFONT}“This cookie from {STRINGID} is a really good value” -STR_1601 : -STR_1602 : -STR_1603 : -STR_1604 :{SMALLFONT}“This roast sausage from {STRINGID} is a really good value” -STR_1605 : -STR_1606 : -STR_1607 : -STR_1608 : -STR_1609 : -STR_1610 : -STR_1611 : -STR_1612 : -STR_1613 : -STR_1614 : -STR_1615 : -STR_1616 :{SMALLFONT}“I'm not paying that much for an on-ride photo from {STRINGID}” -STR_1617 :{SMALLFONT}“I'm not paying that much for an on-ride photo from {STRINGID}” -STR_1618 :{SMALLFONT}“I'm not paying that much for an on-ride photo from {STRINGID}” -STR_1619 :{SMALLFONT}“I'm not paying that much for a pretzel from {STRINGID}” -STR_1620 :{SMALLFONT}“I'm not paying that much for hot chocolate from {STRINGID}” -STR_1621 :{SMALLFONT}“I'm not paying that much for iced tea from {STRINGID}” -STR_1622 :{SMALLFONT}“I'm not paying that much for a funnel cake from {STRINGID}” -STR_1623 :{SMALLFONT}“I'm not paying that much for sunglasses from {STRINGID}” -STR_1624 :{SMALLFONT}“I'm not paying that much for beef noodles from {STRINGID}” -STR_1625 :{SMALLFONT}“I'm not paying that much for fried rice noodles from {STRINGID}” -STR_1626 :{SMALLFONT}“I'm not paying that much for wonton soup from {STRINGID}” -STR_1627 :{SMALLFONT}“I'm not paying that much for meatball soup from {STRINGID}” -STR_1628 :{SMALLFONT}“I'm not paying that much for fruit juice from {STRINGID}” -STR_1629 :{SMALLFONT}“I'm not paying that much for soybean milk from {STRINGID}” -STR_1630 :{SMALLFONT}“I'm not paying that much for sujeonggwa from {STRINGID}” -STR_1631 :{SMALLFONT}“I'm not paying that much for a sub sandwich from {STRINGID}” -STR_1632 :{SMALLFONT}“I'm not paying that much for a cookie from {STRINGID}” -STR_1633 : -STR_1634 : -STR_1635 : -STR_1636 :{SMALLFONT}“I'm not paying that much for a roast sausage from {STRINGID}” -STR_1637 : -STR_1638 : -STR_1639 : -STR_1640 : -STR_1641 : -STR_1642 : -STR_1643 : -STR_1644 : -STR_1645 : -STR_1646 : -STR_1647 : -STR_1648 :{SMALLFONT}“Help! Put me down!” -STR_1649 :{SMALLFONT}“I'm running out of cash!” -STR_1650 :{SMALLFONT}“Wow! A new ride being built!” -# Two removed inside jokes about Intamin and Phoenix -STR_1653 :{SMALLFONT}“...and here we are on {STRINGID}!” -STR_1654 :{WINDOW_COLOUR_2}Recent thoughts: -STR_1655 :{SMALLFONT}{BLACK}Construct footpath on land -STR_1656 :{SMALLFONT}{BLACK}Construct bridge or tunnel footpath -STR_1657 :{WINDOW_COLOUR_2}Preferred ride -STR_1658 :{WINDOW_COLOUR_2}intensity: {BLACK}less than {COMMA16} -STR_1659 :{WINDOW_COLOUR_2}intensity: {BLACK}between {COMMA16} and {COMMA16} -STR_1660 :{WINDOW_COLOUR_2}intensity: {BLACK}more than {COMMA16} -STR_1661 :{WINDOW_COLOUR_2}Nausea tolerance: {BLACK}{STRINGID} -STR_1662 :{WINDOW_COLOUR_2}Happiness: -STR_1663 :{WINDOW_COLOUR_2}Nausea: -STR_1664 :{WINDOW_COLOUR_2}Energy: -STR_1665 :{WINDOW_COLOUR_2}Hunger: -STR_1666 :{WINDOW_COLOUR_2}Thirst: -STR_1667 :{WINDOW_COLOUR_2}Bathroom: -STR_1668 :{WINDOW_COLOUR_2}Satisfaction: {BLACK}Unknown -STR_1669 :{WINDOW_COLOUR_2}Satisfaction: {BLACK}{COMMA16}% -STR_1670 :{WINDOW_COLOUR_2}Total customers: {BLACK}{COMMA32} -STR_1671 :{WINDOW_COLOUR_2}Total profit: {BLACK}{CURRENCY2DP} -STR_1672 :Brakes -STR_1673 :Spinning Control Toggle Track -STR_1674 :Brake speed -STR_1675 :{POP16}{VELOCITY} -STR_1676 :{SMALLFONT}{BLACK}Set speed limit for brakes -STR_1677 :{WINDOW_COLOUR_2}Popularity: {BLACK}Unknown -STR_1678 :{WINDOW_COLOUR_2}Popularity: {BLACK}{COMMA16}% -STR_1679 :Helix up (left) -STR_1680 :Helix up (right) -STR_1681 :Helix down (left) -STR_1682 :Helix down (right) -STR_1683 :Base size 2 x 2 -STR_1684 :Base size 4 x 4 -STR_1685 :Base size 2 x 4 -STR_1686 :Base size 5 x 1 -STR_1687 :Water splash -STR_1688 :Base size 4 x 1 -STR_1689 :Block brakes -STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID} -STR_1691 :{WINDOW_COLOUR_2} Cost: {BLACK}{CURRENCY} -STR_1692 :{WINDOW_COLOUR_2} Cost: {BLACK}from {CURRENCY} -STR_1693 :{SMALLFONT}{BLACK}Guests -STR_1694 :{SMALLFONT}{BLACK}Staff -STR_1695 :{SMALLFONT}{BLACK}Income and costs -STR_1696 :{SMALLFONT}{BLACK}Customer information -STR_1697 :Cannot place these on queue line area -STR_1698 :Can only place these on queue area -STR_1699 :Too many people in game -STR_1700 :Hire new Handyman -STR_1701 :Hire new Mechanic -STR_1702 :Hire new Security Guard -STR_1703 :Hire new Entertainer -STR_1704 :Can't hire new staff... -STR_1705 :{SMALLFONT}{BLACK}Sack this staff member -STR_1706 :{SMALLFONT}{BLACK}Move this person to a new location -STR_1707 :Too many staff in game -STR_1708 :{SMALLFONT}{BLACK}Set patrol area for this staff member -STR_1709 :Sack staff -STR_1710 :Yes -STR_1711 :{WINDOW_COLOUR_1}Are you sure you want to sack {STRINGID}? -STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Sweep footpaths -STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Water gardens -STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Empty trash cans -STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}Mow grass -STR_1716 :Invalid name for park -STR_1717 :Can't rename park... -STR_1718 :Park Name -STR_1719 :Enter name for park: -STR_1720 :{SMALLFONT}{BLACK}Name park -STR_1721 :Park closed -STR_1722 :Park open -STR_1723 :Can't open park... -STR_1724 :Can't close park... -STR_1725 :Can't buy land... -STR_1726 :Land not for sale! -STR_1727 :Construction rights not for sale! -STR_1728 :Can't buy construction rights here... -STR_1729 :Land not owned by park! -STR_1731 :{WHITE}{STRINGID} - - -STR_1732 :Build -STR_1733 :Mode -STR_1734 :{WINDOW_COLOUR_2}Number of laps: -STR_1735 :{SMALLFONT}{BLACK}Number of laps of circuit -STR_1736 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1738 :Can't change number of laps... -STR_1739 :Race won by guest {INT32} -STR_1740 :Race won by {STRINGID} -STR_1741 :Not yet constructed! -STR_1742 :{WINDOW_COLOUR_2}Max. people on ride: -STR_1743 :{SMALLFONT}{BLACK}Maximum number of people allowed on this ride at one time -STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1746 :Can't change this... -STR_1747 :{WINDOW_COLOUR_2}Time limit: -STR_1748 :{SMALLFONT}{BLACK}Time limit for ride -STR_1749 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{DURATION} -STR_1751 :Can't change time limit for ride... -STR_1752 :{SMALLFONT}{BLACK}Show list of individual guests in park +STR_1604 :{SMALLFONT}“This roast sausage from {STRINGID} is a really good value” + +STR_1667 :{WINDOW_COLOUR_2}Bathroom: + +STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Empty trash cans + STR_1753 :{SMALLFONT}{BLACK}Show summarized list of guests in park -STR_1754 :{BLACK}{COMMA16} guests -STR_1755 :{BLACK}{COMMA16} guest -STR_1756 :{WINDOW_COLOUR_2}Admission price: -STR_1757 :{WINDOW_COLOUR_2}Reliability: {MOVE_X}{255}{BLACK}{COMMA16}% -STR_1758 :{SMALLFONT}{BLACK}Build mode -STR_1759 :{SMALLFONT}{BLACK}Move mode -STR_1760 :{SMALLFONT}{BLACK}Fill-in mode -STR_1761 :{SMALLFONT}{BLACK}Build maze in this direction -STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} Panda costume -STR_1780 :{INLINE_SPRITE}{255}{19}{00}{00} Tiger costume -STR_1781 :{INLINE_SPRITE}{00}{20}{00}{00} Elephant costume -STR_1782 :{INLINE_SPRITE}{01}{20}{00}{00} Roman costume -STR_1783 :{INLINE_SPRITE}{02}{20}{00}{00} Gorilla costume -STR_1784 :{INLINE_SPRITE}{03}{20}{00}{00} Snowman costume -STR_1785 :{INLINE_SPRITE}{04}{20}{00}{00} Knight costume -STR_1786 :{INLINE_SPRITE}{05}{20}{00}{00} Astronaut costume -STR_1787 :{INLINE_SPRITE}{06}{20}{00}{00} Bandit costume -STR_1788 :{INLINE_SPRITE}{07}{20}{00}{00} Sheriff costume -STR_1789 :{INLINE_SPRITE}{08}{20}{00}{00} Pirate costume + STR_1790 :{SMALLFONT}{BLACK}Select uniform color for this type of staff STR_1791 :{WINDOW_COLOUR_2}Uniform color: -STR_1792 :Responding to {STRINGID} breakdown call -STR_1793 :Heading to {STRINGID} for an inspection -STR_1794 :Fixing {STRINGID} -STR_1795 :Answering radio call -STR_1796 :Has broken down and requires fixing -STR_1798 :Whirlpool -STR_1799 :{POP16}{POP16}{POP16}{POP16}{POP16}{CURRENCY2DP} -STR_1800 :Safety cut-out -STR_1801 :Restraints stuck closed -STR_1802 :Restraints stuck open -STR_1803 :Doors stuck closed -STR_1804 :Doors stuck open -STR_1805 :Vehicle malfunction -STR_1806 :Brakes failure -STR_1807 :Control failure -STR_1808 :{WINDOW_COLOUR_2}Last breakdown: {BLACK}{STRINGID} -STR_1809 :{WINDOW_COLOUR_2}Current breakdown: {OUTLINE}{RED}{STRINGID} -STR_1810 :{WINDOW_COLOUR_2}Carrying: -STR_1811 :Can't build this here... -STR_1812 :{SMALLFONT}{BLACK}{STRINGID} -STR_1813 :Miscellaneous Objects -STR_1814 :Actions -STR_1815 :Thoughts -STR_1816 :{SMALLFONT}{BLACK}Select information type to show in guest list -STR_1817 :({COMMA16}) -STR_1818 :{WINDOW_COLOUR_2}All guests + STR_1819 :{WINDOW_COLOUR_2}All guests (summarized) -STR_1820 :{WINDOW_COLOUR_2}Guests {STRINGID} -STR_1821 :{WINDOW_COLOUR_2}Guests thinking {STRINGID} -STR_1822 :{WINDOW_COLOUR_2}Guests thinking about {POP16}{STRINGID} -STR_1823 :{SMALLFONT}{BLACK}Show guests' thoughts about this ride/attraction -STR_1824 :{SMALLFONT}{BLACK}Show guests on this ride/attraction -STR_1825 :{SMALLFONT}{BLACK}Show guests queuing for this ride/attraction -STR_1826 :Status -STR_1827 :Popularity -STR_1828 :Satisfaction -STR_1829 :Profit -STR_1830 :Queue length -STR_1831 :Queue time -STR_1832 :Reliability -STR_1833 :Down-time + STR_1834 :Guests favorite -STR_1835 :Popularity: Unknown -STR_1836 :Popularity: {COMMA16}% -STR_1837 :Satisfaction: Unknown -STR_1838 :Satisfaction: {COMMA16}% -STR_1839 :Reliability: {COMMA16}% -STR_1840 :Down-time: {COMMA16}% -STR_1841 :Profit: {CURRENCY2DP} per hour + STR_1842 :Favorite of: {COMMA16} guest STR_1843 :Favorite of: {COMMA16} guests -STR_1844 :{SMALLFONT}{BLACK}Select information type to show in ride/attraction list -STR_1845 :{MONTHYEAR} -STR_1846 :{COMMA16} guests -STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16} guests -STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16} guests -STR_1849 :{WINDOW_COLOUR_2}Play music -STR_1850 :{SMALLFONT}{BLACK}Select whether music should be played for this ride -STR_1851 :{WINDOW_COLOUR_2}Running cost: {BLACK}{CURRENCY2DP} per hour -STR_1852 :{WINDOW_COLOUR_2}Running cost: {BLACK}Unknown -STR_1853 :{WINDOW_COLOUR_2}Built: {BLACK}This Year -STR_1854 :{WINDOW_COLOUR_2}Built: {BLACK}Last Year -STR_1855 :{WINDOW_COLOUR_2}Built: {BLACK}{COMMA16} Years Ago -STR_1856 :{WINDOW_COLOUR_2}Profit per item sold: {BLACK}{CURRENCY2DP} -STR_1857 :{WINDOW_COLOUR_2}Loss per item sold: {BLACK}{CURRENCY2DP} -STR_1858 :{WINDOW_COLOUR_2}Cost: {BLACK}{CURRENCY2DP} per month -STR_1859 :Handymen -STR_1860 :Mechanics -STR_1861 :Security Guards -STR_1862 :Entertainers -STR_1863 :Handyman -STR_1864 :Mechanic -STR_1865 :Security Guard -STR_1866 :Entertainer -STR_1867 :{BLACK}{COMMA16} {STRINGID} -STR_1868 :Can't change number of rotations... -STR_1869 :{WINDOW_COLOUR_2}Number of rotations: -STR_1870 :{SMALLFONT}{BLACK}Number of complete rotations -STR_1871 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1873 :{WINDOW_COLOUR_2}Income: {BLACK}{CURRENCY2DP} per hour -STR_1874 :{WINDOW_COLOUR_2}Profit: {BLACK}{CURRENCY2DP} per hour -STR_1875 :{BLACK} {SPRITE}{BLACK} {STRINGID} -STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}Inspect Rides -STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}Fix Rides -STR_1878 :{WINDOW_COLOUR_2}Inspection: -STR_1879 :Every 10 minutes -STR_1880 :Every 20 minutes -STR_1881 :Every 30 minutes -STR_1882 :Every 45 minutes -STR_1883 :Every hour -STR_1884 :Every 2 hours -STR_1885 :Never -STR_1886 :Inspecting {STRINGID} -STR_1887 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}{COMMA16} minutes -STR_1888 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}more than 4 hours -STR_1889 :{WINDOW_COLOUR_2}Down-Time: {MOVE_X}{255}{BLACK}{COMMA16}% -STR_1890 :{SMALLFONT}{BLACK}Select how often a mechanic should check this ride -STR_1891 :No {STRINGID} in park yet! -STR_1894 :{WINDOW_COLOUR_2}{STRINGID} sold: {BLACK}{COMMA32} -STR_1895 :{SMALLFONT}{BLACK}Build new ride/attraction -STR_1896 :{WINDOW_COLOUR_2}Expenditure/Income -STR_1897 :{WINDOW_COLOUR_2}Ride construction -STR_1898 :{WINDOW_COLOUR_2}Ride running costs -STR_1899 :{WINDOW_COLOUR_2}Land purchase -STR_1900 :{WINDOW_COLOUR_2}Landscaping -STR_1901 :{WINDOW_COLOUR_2}Park entrance tickets -STR_1902 :{WINDOW_COLOUR_2}Ride tickets -STR_1903 :{WINDOW_COLOUR_2}Shop sales -STR_1904 :{WINDOW_COLOUR_2}Shop stock -STR_1905 :{WINDOW_COLOUR_2}Food/drink sales -STR_1906 :{WINDOW_COLOUR_2}Food/drink stock -STR_1907 :{WINDOW_COLOUR_2}Staff wages -STR_1908 :{WINDOW_COLOUR_2}Marketing -STR_1909 :{WINDOW_COLOUR_2}Research -STR_1910 :{WINDOW_COLOUR_2}Loan interest -STR_1911 :{BLACK} at {COMMA16}% per year -STR_1912 :{MONTH} -STR_1913 :{BLACK}+{CURRENCY2DP} -STR_1914 :{BLACK}{CURRENCY2DP} -STR_1915 :{RED}{CURRENCY2DP} -STR_1916 :{WINDOW_COLOUR_2}Loan: -STR_1917 :{POP16}{POP16}{POP16}{CURRENCY} -STR_1918 :Can't borrow any more money! -STR_1919 :Not enough cash available! -STR_1920 :Can't pay back loan! -STR_1921 :{SMALLFONT}{BLACK}Start a new game -STR_1922 :{SMALLFONT}{BLACK}Continue playing a saved game -STR_1924 :{SMALLFONT}{BLACK}Exit -STR_1925 :Can't place person here... -STR_1926 :{SMALLFONT} -STR_1927 :{YELLOW}{STRINGID} has broken down -STR_1928 :{RED}{STRINGID} has crashed! STR_1929 :{RED}{STRINGID} still hasn't been fixed{NEWLINE}Check where your mechanics are and consider organizing them better -STR_1930 :{SMALLFONT}{BLACK}Turn on/off tracking information for this guest - (If tracking is on, guest's movements will be reported in the message area) -STR_1931 :{STRINGID} has joined the queue line for {STRINGID} -STR_1932 :{STRINGID} is on {STRINGID} -STR_1933 :{STRINGID} is in {STRINGID} -STR_1934 :{STRINGID} has left {STRINGID} -STR_1935 :{STRINGID} has left the park -STR_1936 :{STRINGID} has bought {STRINGID} -STR_1937 :{SMALLFONT}{BLACK}Show information about the subject of this message -STR_1938 :{SMALLFONT}{BLACK}Show view of guest -STR_1939 :{SMALLFONT}{BLACK}Show view of staff member -STR_1940 :{SMALLFONT}{BLACK}Show happiness, energy, hunger etc. for this guest -STR_1941 :{SMALLFONT}{BLACK}Show which rides this guest has been on -STR_1942 :{SMALLFONT}{BLACK}Show financial information about this guest -STR_1943 :{SMALLFONT}{BLACK}Show guest's recent thoughts -STR_1944 :{SMALLFONT}{BLACK}Show items guest is carrying -STR_1945 :{SMALLFONT}{BLACK}Show orders and options for this staff member -STR_1946 :{SMALLFONT}{BLACK}Select costume for this entertainer -STR_1947 :{SMALLFONT}{BLACK}Show areas patrolled by selected staff type, and locate the nearest staff member -STR_1948 :{SMALLFONT}{BLACK}Hire a new staff member of the selected type -STR_1949 :Financial Summary -STR_1950 :Financial Graph -STR_1951 :Park Value Graph -STR_1952 :Profit Graph -STR_1953 :Marketing -STR_1954 :Research Funding -STR_1955 :{WINDOW_COLOUR_2}Number of circuits: -STR_1956 :{SMALLFONT}{BLACK}Number of circuits of track per ride -STR_1957 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} -STR_1958 :{COMMA16} -STR_1959 :Can't change number of circuits... -STR_1960 :{WINDOW_COLOUR_2}Balloon price: -STR_1961 :{WINDOW_COLOUR_2}Cuddly Toy price: -STR_1962 :{WINDOW_COLOUR_2}Park Map price: -STR_1963 :{WINDOW_COLOUR_2}On-Ride Photo price: -STR_1964 :{WINDOW_COLOUR_2}Umbrella price: -STR_1965 :{WINDOW_COLOUR_2}Drink price: -STR_1966 :{WINDOW_COLOUR_2}Burger price: + STR_1967 :{WINDOW_COLOUR_2}Fries price: -STR_1968 :{WINDOW_COLOUR_2}Ice Cream price: + STR_1969 :{WINDOW_COLOUR_2}Cotton Candy price: -STR_1970 :{WINDOW_COLOUR_2} -STR_1971 :{WINDOW_COLOUR_2} -STR_1972 :{WINDOW_COLOUR_2} -STR_1973 :{WINDOW_COLOUR_2}Pizza price: -STR_1974 :{WINDOW_COLOUR_2} -STR_1975 :{WINDOW_COLOUR_2}Popcorn price: -STR_1976 :{WINDOW_COLOUR_2}Hot Dog price: -STR_1977 :{WINDOW_COLOUR_2}Tentacle price: -STR_1978 :{WINDOW_COLOUR_2}Hat price: + STR_1979 :{WINDOW_COLOUR_2}Candy Apple price: -STR_1980 :{WINDOW_COLOUR_2}T-Shirt price: + STR_1981 :{WINDOW_COLOUR_2}Donut price: -STR_1982 :{WINDOW_COLOUR_2}Coffee price: -STR_1983 :{WINDOW_COLOUR_2} -STR_1984 :{WINDOW_COLOUR_2}Fried Chicken price: -STR_1985 :{WINDOW_COLOUR_2}Lemonade price: -STR_1986 :{WINDOW_COLOUR_2} -STR_1987 :{WINDOW_COLOUR_2} -STR_1988 :Balloon -STR_1989 :Cuddly Toy -STR_1990 :Park Map -STR_1991 :On-Ride Photo -STR_1992 :Umbrella -STR_1993 :Drink -STR_1994 :Burger + STR_1995 :Fries -STR_1996 :Ice Cream + STR_1997 :Cotton Candy -STR_1998 :Empty Can + STR_1999 :Trash -STR_2000 :Empty Burger Box -STR_2001 :Pizza -STR_2002 :Voucher -STR_2003 :Popcorn -STR_2004 :Hot Dog -STR_2005 :Tentacle -STR_2006 :Hat + STR_2007 :Candy Apple -STR_2008 :T-Shirt + STR_2009 :Donut -STR_2010 :Coffee -STR_2011 :Empty Cup -STR_2012 :Fried Chicken -STR_2013 :Lemonade -STR_2014 :Empty Box -STR_2015 :Empty Bottle -STR_2016 :Balloons -STR_2017 :Cuddly Toys -STR_2018 :Park Maps -STR_2019 :On-Ride Photos -STR_2020 :Umbrellas -STR_2021 :Drinks -STR_2022 :Burgers + STR_2023 :Fries -STR_2024 :Ice Creams + STR_2025 :Cotton Candy -STR_2026 :Empty Cans + STR_2027 :Trash -STR_2028 :Empty Burger Boxes -STR_2029 :Pizzas -STR_2030 :Vouchers -STR_2031 :Popcorn -STR_2032 :Hot Dogs -STR_2033 :Tentacles -STR_2034 :Hats + STR_2035 :Candy Apples -STR_2036 :T-Shirts + STR_2037 :Donuts -STR_2038 :Coffees -STR_2039 :Empty Cups -STR_2040 :Fried Chicken -STR_2041 :Lemonade -STR_2042 :Empty Boxes -STR_2043 :Empty Bottles -STR_2044 :a Balloon -STR_2045 :a Cuddly Toy -STR_2046 :a Park Map -STR_2047 :an On-Ride Photo -STR_2048 :an Umbrella -STR_2049 :a Drink -STR_2050 :a Burger + STR_2051 :some Fries -STR_2052 :an Ice Cream + STR_2053 :some Cotton Candy -STR_2054 :an Empty Can + STR_2055 :some Trash -STR_2056 :an Empty Burger Box -STR_2057 :a Pizza -STR_2058 :a Voucher -STR_2059 :some Popcorn -STR_2060 :a Hot Dog -STR_2061 :a Tentacle -STR_2062 :a Hat + STR_2063 :a Candy Apple -STR_2064 :a T-Shirt + STR_2065 :a Donut -STR_2066 :a Coffee -STR_2067 :an Empty Cup -STR_2068 :some Fried Chicken -STR_2069 :some Lemonade -STR_2070 :an Empty Box -STR_2071 :an Empty Bottle -STR_2072 :“{STRINGID}” Balloon -STR_2073 :“{STRINGID}” Cuddly Toy -STR_2074 :Map of {STRINGID} -STR_2075 :On-Ride Photo of {STRINGID} -STR_2076 :“{STRINGID}” Umbrella -STR_2077 :Drink -STR_2078 :Burger + STR_2079 :Fries -STR_2080 :Ice Cream + STR_2081 :Cotton Candy -STR_2082 :Empty Can + STR_2083 :Trash -STR_2084 :Empty Burger Box -STR_2085 :Pizza -STR_2086 :Voucher for {STRINGID} -STR_2087 :Popcorn -STR_2088 :Hot Dog -STR_2089 :Tentacle -STR_2090 :“{STRINGID}” Hat + STR_2091 :Candy Apple -STR_2092 :“{STRINGID}” T-Shirt + STR_2093 :Donut -STR_2094 :Coffee -STR_2095 :Empty Cup -STR_2096 :Fried Chicken -STR_2097 :Lemonade -STR_2098 :Empty Box -STR_2099 :Empty Bottle -STR_2103 :{WINDOW_COLOUR_2}Pretzel price: -STR_2104 :{WINDOW_COLOUR_2}Hot Chocolate price: -STR_2105 :{WINDOW_COLOUR_2}Iced Tea price: -STR_2106 :{WINDOW_COLOUR_2}Funnel Cake price: -STR_2107 :{WINDOW_COLOUR_2}Sunglasses price: -STR_2108 :{WINDOW_COLOUR_2}Beef Noodles price: -STR_2109 :{WINDOW_COLOUR_2}Fried Rice Noodles price: -STR_2110 :{WINDOW_COLOUR_2}Wonton Soup price: -STR_2111 :{WINDOW_COLOUR_2}Meatball Soup price: -STR_2112 :{WINDOW_COLOUR_2}Fruit Juice price: -STR_2113 :{WINDOW_COLOUR_2}Soybean Milk price: -STR_2114 :{WINDOW_COLOUR_2}Sujeonggwa price: -STR_2115 :{WINDOW_COLOUR_2}Sub Sandwich price: -STR_2116 :{WINDOW_COLOUR_2}Cookie price: -STR_2117 :{WINDOW_COLOUR_2} -STR_2118 :{WINDOW_COLOUR_2} -STR_2119 :{WINDOW_COLOUR_2} -STR_2120 :{WINDOW_COLOUR_2}Roast Sausage price: -STR_2121 :{WINDOW_COLOUR_2} -STR_2125 :Pretzel -STR_2126 :Hot Chocolate -STR_2127 :Iced Tea -STR_2128 :Funnel Cake -STR_2129 :Sunglasses -STR_2130 :Beef Noodles -STR_2131 :Fried Rice Noodles -STR_2132 :Wonton Soup -STR_2133 :Meatball Soup -STR_2134 :Fruit Juice -STR_2135 :Soybean Milk -STR_2136 :Sujeonggwa -STR_2137 :Sub Sandwich -STR_2138 :Cookie -STR_2139 :Empty Bowl -STR_2140 :Empty Drink Carton -STR_2141 :Empty Juice Cup -STR_2142 :Roast Sausage -STR_2143 :Empty Bowl -STR_2147 :Pretzels -STR_2148 :Hot Chocolates -STR_2149 :Iced Teas -STR_2150 :Funnel Cakes -STR_2151 :Sunglasses -STR_2152 :Beef Noodles -STR_2153 :Fried Rice Noodles -STR_2154 :Wonton Soups -STR_2155 :Meatball Soups -STR_2156 :Fruit Juices -STR_2157 :Soybean Milks -STR_2158 :Sujeonggwa -STR_2159 :Sub Sandwiches -STR_2160 :Cookies -STR_2161 :Empty Bowls -STR_2162 :Empty Drink Cartons -STR_2163 :Empty Juice cups -STR_2164 :Roast Sausages -STR_2165 :Empty Bowls -STR_2169 :a Pretzel -STR_2170 :a Hot Chocolate -STR_2171 :an Iced Tea -STR_2172 :a Funnel Cake -STR_2173 :a pair of Sunglasses -STR_2174 :some Beef Noodles -STR_2175 :some Fried Rice Noodles -STR_2176 :some Wonton Soup -STR_2177 :some Meatball Soup -STR_2178 :a Fruit Juice -STR_2179 :some Soybean Milk -STR_2180 :some Sujeonggwa -STR_2181 :a Sub Sandwich -STR_2182 :a Cookie -STR_2183 :an Empty Bowl -STR_2184 :an Empty Drink Carton -STR_2185 :an Empty Juice Cup -STR_2186 :a Roast Sausage -STR_2187 :an Empty Bowl -STR_2191 :Pretzel -STR_2192 :Hot Chocolate -STR_2193 :Iced Tea -STR_2194 :Funnel Cake -STR_2195 :Sunglasses -STR_2196 :Beef Noodles -STR_2197 :Fried Rice Noodles -STR_2198 :Wonton Soup -STR_2199 :Meatball Soup -STR_2200 :Fruit Juice -STR_2201 :Soybean Milk -STR_2202 :Sujeonggwa -STR_2203 :Sub Sandwich -STR_2204 :Cookie -STR_2205 :Empty Bowl -STR_2206 :Empty Drink Carton -STR_2207 :Empty Juice Cup -STR_2208 :Roast Sausage -STR_2209 :Empty Bowl STR_2353 :{WINDOW_COLOUR_2}Trash swept: {BLACK}{COMMA16} STR_2354 :{WINDOW_COLOUR_2}Trash cans emptied: {BLACK}{COMMA16} STR_2707 :Use system dialog window -STR_2735 :{COMMA16}km/h - STR_2756 :Remove trash STR_2806 :{RED}Guests are complaining about the disgusting state of the paths in your park{NEWLINE}Check where your handymen are and consider organizing them better diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index bf7ce643a8..9bad3cea48 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3398,8 +3398,8 @@ STR_5939 :공원 울타리 제거 STR_5940 :공원 울타리 복구 STR_5941 :{WINDOW_COLOUR_2}기본 높이: STR_5942 :{WINDOW_COLOUR_2}공원 이름: {BLACK}{STRINGID} -STR_5943 :{WINDOW_COLOUR_2}추가: {BLACK}{STRINGID} -STR_5944 :{WINDOW_COLOUR_2}추가: {BLACK}없음 +STR_5943 :{WINDOW_COLOUR_2}기물: {BLACK}{STRINGID} +STR_5944 :{WINDOW_COLOUR_2}기물: {BLACK}없음 STR_5945 :{WINDOW_COLOUR_2}연결된 면: STR_5946 :{WINDOW_COLOUR_2}놀이기구 종류: {BLACK}{STRINGID} STR_5947 :{WINDOW_COLOUR_2}놀이기구 ID: {BLACK}{COMMA16} @@ -3773,6 +3773,10 @@ STR_6314 :{WINDOW_COLOUR_2}목표: {BLACK}{INT32}, {INT32} 인내심 {INT32} STR_6315 :{WINDOW_COLOUR_2}경로탐색 목표: {BLACK}{INT32}, {INT32}, {INT32} 방향 {INT32} STR_6316 :{WINDOW_COLOUR_2}경로탐색 기록: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} 방향 {INT32} +STR_6318 :네트워크 비동기화가 감지되었습니다.{NEWLINE}로그 파일: {STRING} +STR_6319 :{WINDOW_COLOUR_2}블록 브레이크 닫기 +STR_6320 :{WINDOW_COLOUR_2}파괴 불가 +STR_6321 :{WINDOW_COLOUR_2}기물 부서짐 ############# diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index 449792d514..f760ce9f56 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -3780,6 +3780,10 @@ STR_6314 :{WINDOW_COLOUR_2}Bestemming: {BLACK}{INT32}, {INT32} tolerantie {IN STR_6315 :{WINDOW_COLOUR_2}Pathfind-doel: {BLACK}{INT32}, {INT32}, {INT32} richting {INT32} STR_6316 :{WINDOW_COLOUR_2}Pathfind-geschiedenis: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} richting {INT32} +STR_6318 :Netwerkdesynchronisatie gedetecteerd.{NEWLINE}Logbestand: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Blokrem is gesloten +STR_6320 :{WINDOW_COLOUR_2}Mag niet worden verwijderd +STR_6321 :{WINDOW_COLOUR_2}Straatmeubel is kapot ############# # Scenarios # From b6ae8a758ef85dc1855b087ad5db373aae5bc056 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 20 May 2019 19:46:04 +0100 Subject: [PATCH 401/506] Update changelog Add fix note for #7039, fixed in 710da039a4c2639620fcdc4fcd0cd20c413532fa. --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 921b652446..75d42a7fce 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -21,6 +21,7 @@ - Fix: [#5893] Looking at guest window tabs other than the main tab eventually causes assertion. - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). +- Fix: [#7039] Map window not rendering properly when using OpenGL. - Fix: [#7729] Money Input Prompt breaks on certain values. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. From 7f2936b8fb56da3a0f907eed72abe992c89af962 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 20 May 2019 19:47:26 +0100 Subject: [PATCH 402/506] Fix #7045: Theme window's colour pickers not drawn properly on OpenGL Remove unnecessary transparent flag when drawing colour buttons. --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/Themes.cpp | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 75d42a7fce..b6df9f9e4c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -22,6 +22,7 @@ - Fix: [#5905] Urban Park merry-go-round has entrance and exit swapped (original bug). - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7039] Map window not rendering properly when using OpenGL. +- Fix: [#7045] Theme window's colour pickers not drawn properly on OpenGL. - Fix: [#7729] Money Input Prompt breaks on certain values. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. diff --git a/src/openrct2-ui/windows/Themes.cpp b/src/openrct2-ui/windows/Themes.cpp index c0f2713422..0b29e1f178 100644 --- a/src/openrct2-ui/windows/Themes.cpp +++ b/src/openrct2-ui/windows/Themes.cpp @@ -904,12 +904,10 @@ void window_themes_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t sc gfx_draw_string_left(dpi, theme_desc_get_name(wc), nullptr, w->colours[1], 2, y + 4); uint8_t colour = theme_get_colour(wc, j); - uint32_t image = SPRITE_ID_PALETTE_COLOUR_1(colour & ~COLOUR_FLAG_TRANSLUCENT) | IMAGE_TYPE_TRANSPARENT - | SPR_PALETTE_BTN; + uint32_t image = SPRITE_ID_PALETTE_COLOUR_1(colour & ~COLOUR_FLAG_TRANSLUCENT) | SPR_PALETTE_BTN; if (i == _colour_index_1 && j == _colour_index_2) { - image = SPRITE_ID_PALETTE_COLOUR_1(colour & ~COLOUR_FLAG_TRANSLUCENT) | IMAGE_TYPE_TRANSPARENT - | SPR_PALETTE_BTN_PRESSED; + image = SPRITE_ID_PALETTE_COLOUR_1(colour & ~COLOUR_FLAG_TRANSLUCENT) | SPR_PALETTE_BTN_PRESSED; } gfx_draw_sprite(dpi, image, _button_offset_x + 12 * j, y + _button_offset_y, 0); From 831d69083ea2dc0e44d95cd4fa2ec5bf39e91da3 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 21 May 2019 04:00:31 +0000 Subject: [PATCH 403/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 02b2ce0799..3473fef7ad 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3785,6 +3785,10 @@ STR_6314 :{WINDOW_COLOUR_2}Cíl: {BLACK}{INT32}, {INT32} tolerance {INT32} STR_6315 :{WINDOW_COLOUR_2}Cíl hledání cesty: {BLACK}{INT32}, {INT32}, {INT32} směr {INT32} STR_6316 :{WINDOW_COLOUR_2}Historie hledání cest: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} směr {INT32} +STR_6318 :Detekována síťová desynchronizace.{NEWLINE}Log: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Uzavřený brzdný blok +STR_6320 :{WINDOW_COLOUR_2}Nezničitelné +STR_6321 :{WINDOW_COLOUR_2}Rozbitá část ############################################################################### ## RCT2 Scenarios From 8c20b635bdc43f67fe70d5aabcbb5bb268d08da3 Mon Sep 17 00:00:00 2001 From: aw20368 Date: Tue, 21 May 2019 15:22:47 -0400 Subject: [PATCH 404/506] Fix #9270: Refactor money effect Changed static functions to rct_money_effect member functions. GetStringId now returns std::pair. --- contributors.md | 1 + src/openrct2/Game.cpp | 2 +- src/openrct2/actions/GameAction.cpp | 2 +- src/openrct2/paint/sprite/Paint.Misc.cpp | 3 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/world/MoneyEffect.cpp | 79 ++++++++++++++---------- src/openrct2/world/Sprite.cpp | 2 +- src/openrct2/world/Sprite.h | 15 +++-- 8 files changed, 58 insertions(+), 48 deletions(-) diff --git a/contributors.md b/contributors.md index 3b7771e4bc..f875eb6045 100644 --- a/contributors.md +++ b/contributors.md @@ -130,6 +130,7 @@ The following people are not part of the development team, but have been contrib * Florian Will (w-flo) * Trevor Harkness (tharkne) * Steve Xu (stevexu-umich) +* (aw20368) ## Toolchain * (Balletie) - macOS diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 8fe33e3dfa..f24cd83a6f 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -528,7 +528,7 @@ int32_t game_do_command_p( { // Create a +/- money text effect if (cost != 0 && game_is_not_paused()) - money_effect_create(cost); + rct_money_effect::Create(cost); } } diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 731e4d59ae..b6789b86e5 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -301,7 +301,7 @@ namespace GameActions if (result->Error == GA_ERROR::OK && finance_check_money_required(flags) && result->Cost != 0) { finance_payment(result->Cost, result->ExpenditureType); - money_effect_create(result->Cost); + rct_money_effect::Create(result->Cost); } if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && result->Error == GA_ERROR::OK) diff --git a/src/openrct2/paint/sprite/Paint.Misc.cpp b/src/openrct2/paint/sprite/Paint.Misc.cpp index 2e598049f6..7525e715ca 100644 --- a/src/openrct2/paint/sprite/Paint.Misc.cpp +++ b/src/openrct2/paint/sprite/Paint.Misc.cpp @@ -49,8 +49,7 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir } const rct_money_effect* moneyEffect = &misc->money_effect; - money32 value; - rct_string_id stringId = money_effect_get_string_id(moneyEffect, &value); + auto [stringId, value] = moneyEffect->GetStringId(); paint_floating_money_effect( session, value, stringId, moneyEffect->y, moneyEffect->z, (int8_t*)&money_wave[moneyEffect->wiggle % 22], moneyEffect->offset_x, session->CurrentRotation); diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 56e99a1375..2a82a05de6 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -2041,7 +2041,7 @@ void Guest::SpendMoney(money16& peep_expend_type, money32 amount) // needing to be synchronised if (network_get_mode() == NETWORK_MODE_NONE && !gOpenRCT2Headless) { - money_effect_create_at(amount, x, y, z, true); + rct_money_effect::CreateAt(amount, x, y, z, true); } } diff --git a/src/openrct2/world/MoneyEffect.cpp b/src/openrct2/world/MoneyEffect.cpp index e5a7a2b765..16680d802d 100644 --- a/src/openrct2/world/MoneyEffect.cpp +++ b/src/openrct2/world/MoneyEffect.cpp @@ -17,11 +17,27 @@ static constexpr const LocationXY16 _moneyEffectMoveOffset[] = { { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } }; +bool rct_sprite::IsMoneyEffect() +{ + return this->money_effect.sprite_identifier == SPRITE_IDENTIFIER_MISC + && this->money_effect.type == SPRITE_MISC_MONEY_EFFECT; +} + +rct_money_effect* rct_sprite::AsMoneyEffect() +{ + rct_money_effect* result = nullptr; + if (IsMoneyEffect()) + { + result = (rct_money_effect*)this; + } + return result; +} + /** * * rct2: 0x0067351F */ -void money_effect_create_at(money32 value, int32_t x, int32_t y, int32_t z, bool vertical) +void rct_money_effect::CreateAt(money32 value, int32_t x, int32_t y, int32_t z, bool vertical) { if (value == MONEY(0, 00)) return; @@ -44,10 +60,9 @@ void money_effect_create_at(money32 value, int32_t x, int32_t y, int32_t z, bool int16_t offsetX = 0; if (!gOpenRCT2NoGraphics) { - // Construct string to display - rct_string_id stringId = money_effect_get_string_id(moneyEffect, &value); + auto [stringId, newValue] = moneyEffect->GetStringId(); char buffer[128]; - format_string(buffer, 128, stringId, &value); + format_string(buffer, 128, stringId, &newValue); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; offsetX = -(gfx_get_string_width(buffer) / 2); } @@ -59,7 +74,7 @@ void money_effect_create_at(money32 value, int32_t x, int32_t y, int32_t z, bool * * rct2: 0x0069C5D0 */ -void money_effect_create(money32 value) +void rct_money_effect::Create(money32 value) { LocationXYZ16 mapPosition = { gCommandPosition.x, gCommandPosition.y, gCommandPosition.z }; @@ -79,66 +94,62 @@ void money_effect_create(money32 value) mapPosition.z = tile_element_height(mapPosition.x, mapPosition.y); } mapPosition.z += 10; - money_effect_create_at(-value, mapPosition.x, mapPosition.y, mapPosition.z, false); + CreateAt(-value, mapPosition.x, mapPosition.y, mapPosition.z, false); } /** * * rct2: 0x00673232 */ -void money_effect_update(rct_money_effect* moneyEffect) +void rct_money_effect::Update() { - invalidate_sprite_2((rct_sprite*)moneyEffect); - moneyEffect->wiggle++; - if (moneyEffect->wiggle >= 22) + invalidate_sprite_2((rct_sprite*)this); + wiggle++; + if (wiggle >= 22) { - moneyEffect->wiggle = 0; + wiggle = 0; } - moneyEffect->move_delay++; - if (moneyEffect->move_delay < 2) + move_delay++; + if (move_delay < 2) { return; } - int32_t x = moneyEffect->x; - int32_t y = moneyEffect->y; - int32_t z = moneyEffect->z; - moneyEffect->move_delay = 0; + int32_t newX = x; + int32_t newY = y; + int32_t newZ = z; + move_delay = 0; - if (moneyEffect->vertical) + if (vertical) { - z += 1; + newZ += 1; } - y += _moneyEffectMoveOffset[get_current_rotation()].y; - x += _moneyEffectMoveOffset[get_current_rotation()].x; + newY += _moneyEffectMoveOffset[get_current_rotation()].y; + newX += _moneyEffectMoveOffset[get_current_rotation()].x; - sprite_move(x, y, z, (rct_sprite*)moneyEffect); + sprite_move(newX, newY, newZ, (rct_sprite*)this); - moneyEffect->num_movements++; - if (moneyEffect->num_movements < 55) + num_movements++; + if (num_movements < 55) { return; } - sprite_remove((rct_sprite*)moneyEffect); + sprite_remove((rct_sprite*)this); } -rct_string_id money_effect_get_string_id(const rct_money_effect* sprite, money32* outValue) +std::pair rct_money_effect::GetStringId() const { - bool vertical = (sprite->vertical != 0); rct_string_id spentStringId = vertical ? STR_MONEY_EFFECT_SPEND_HIGHP : STR_MONEY_EFFECT_SPEND; rct_string_id receiveStringId = vertical ? STR_MONEY_EFFECT_RECEIVE_HIGHP : STR_MONEY_EFFECT_RECEIVE; rct_string_id stringId = receiveStringId; - money32 value = sprite->value; + money32 outValue = value; if (value < 0) { - value *= -1; + outValue *= -1; stringId = spentStringId; } - if (outValue != nullptr) - { - *outValue = value; - } - return stringId; + + return std::make_pair(stringId, outValue); } diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index e2585c8507..dfdd09b3e1 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -541,7 +541,7 @@ static void sprite_misc_update(rct_sprite* sprite) sprite_steam_particle_update((rct_steam_particle*)sprite); break; case SPRITE_MISC_MONEY_EFFECT: - money_effect_update(&sprite->money_effect); + sprite->money_effect.Update(); break; case SPRITE_MISC_CRASHED_VEHICLE_PARTICLE: crashed_vehicle_particle_update((rct_crashed_vehicle_particle*)sprite); diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 27bc9d4a53..0b66a33286 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -93,6 +93,11 @@ struct rct_money_effect : rct_sprite_common money32 value; int16_t offset_x; uint16_t wiggle; + + static void CreateAt(money32 value, int32_t x, int32_t y, int32_t z, bool vertical); + static void Create(money32 value); + void Update(); + std::pair GetStringId() const; }; struct rct_crashed_vehicle_particle : rct_sprite_generic @@ -139,9 +144,11 @@ union rct_sprite bool IsBalloon(); bool IsDuck(); + bool IsMoneyEffect(); bool IsPeep(); rct_balloon* AsBalloon(); rct_duck* AsDuck(); + rct_money_effect* AsMoneyEffect(); Peep* AsPeep(); }; assert_struct_size(rct_sprite, 0x100); @@ -239,14 +246,6 @@ void duck_press(rct_duck* duck); void duck_remove_all(); uint32_t duck_get_frame_image(const rct_duck* duck, int32_t direction); -/////////////////////////////////////////////////////////////// -// Money effect -/////////////////////////////////////////////////////////////// -void money_effect_create(money32 value); -void money_effect_create_at(money32 value, int32_t x, int32_t y, int32_t z, bool vertical); -void money_effect_update(rct_money_effect* moneyEffect); -rct_string_id money_effect_get_string_id(const rct_money_effect* sprite, money32* outValue); - /////////////////////////////////////////////////////////////// // Crash particles /////////////////////////////////////////////////////////////// From a484102f610ee9ef8f0901895843e1c083a9c0ae Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 22 May 2019 04:00:38 +0000 Subject: [PATCH 405/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ko-KR.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 9bad3cea48..c0cd623702 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -46,7 +46,7 @@ STR_0041 :3D 영화관 STR_0042 :톱 스핀 STR_0043 :스페이스 링 STR_0044 :역방향 자유낙하 코스터 -STR_0045 :리프트 +STR_0045 :엘리베이터 STR_0046 :수직 낙하 롤러코스터 STR_0047 :현금 지급기 STR_0048 :트위스트 @@ -156,7 +156,7 @@ STR_0575 :공원 여기 저기로 사람들을 실어나르는, 단선 레일 STR_0577 :특수한 반전 섹션에서 앞뒤가 바뀌는 나무 트랙을 달리는 보우기 차입니다 STR_0578 :원형 고리로 둘러싸여 급강하와 하트라인 트위스트를 횡단하는 트랙을 달리는 차량입니다. STR_0579 : -STR_0580 :90m 이상의 언덕을 부드럽게 오르내리는 거대한 철제 롤러코스터입니다. +STR_0580 :90m 이상의 높이를 부드럽게 오르내리는 거대한 철제 롤러코스터입니다. STR_0581 :원형 모양의 좌석이 맨 위까지 끌어올려진 다음, 자유 낙하하며, 자기장에 의해 부드럽게 바닥에 정지합니다. STR_0582 : STR_0583 : @@ -1711,9 +1711,9 @@ STR_2358 :유닛 STR_2359 :실제 값 STR_2360 :해상도: STR_2361 :땅 테두리를 부드럽게 -STR_2362 :{SMALLFONT}{BLACK}땅의 테두리를 부드럽게 표시합니다. -STR_2363 :땅에 격자선 보이기 -STR_2364 :{SMALLFONT}{BLACK}땅에 격자선을 보여줍니다 +STR_2362 :{SMALLFONT}{BLACK}땅의 테두리를 부드럽게 표시합니다 +STR_2363 :땅에 격자선 표시 +STR_2364 :{SMALLFONT}{BLACK}땅에 격자선을 표시합니다 STR_2365 :은행이 대출을 증가시키는 것을 거절했습니다! STR_2366 :섭씨 (°C) STR_2367 :화씨 (°F) @@ -2020,7 +2020,7 @@ STR_2678 :??? STR_2679 :??? STR_2680 :모든 연구가 완료되었습니다 STR_2681 :{MEDIUMFONT}{BLACK}돈 {CURRENCY} 늘리기 -STR_2684 :{SMALLFONT}{BLACK}손님 대규모로 불러오기 +STR_2684 :{SMALLFONT}{BLACK}손님을 대규모로 부릅니다 STR_2685 :단일 노이즈 매개 변수 STR_2686 :저: STR_2687 :고: @@ -2620,7 +2620,7 @@ STR_3446 :순찰 영역 해제 # New strings, cleaner STR_5120 :재정 STR_5121 :연구 -STR_5122 :놀이기구를 (RCT1처럼) 트랙 종류 별로 선택 +STR_5122 :RCT1처럼 놀이기구를 트랙 종류 별로 선택 STR_5123 :놀이기구 새 걸로 STR_5125 :모두 파괴 가능 STR_5126 :무작위 타이틀 음악 @@ -2933,9 +2933,9 @@ STR_5435 :세이브 이름 바꾸기 STR_5436 :타이틀 시퀀스 편집하기... STR_5437 :선택된 세이브 없음 STR_5438 :명령 에디터가 열려있을 때 변경할 수 없습니다 -STR_5439 :4초 이상의 기다림 명령은 재시작 명령이 필요합니다. +STR_5439 :4초 이상의 기다림 명령은 재시작 명령이 필요합니다 STR_5440 :커서가 게임 밖으로 나가면 전체 화면을 최소화 -STR_5441 :{SMALLFONT}{BLACK}놀이기구를 종류별로 구분합니다. (RCT1처럼) +STR_5441 :{SMALLFONT}{BLACK}놀이기구를 RCT1처럼 종류별로 구분합니다 STR_5442 :공원 등급 고정: STR_5443 :속도{MOVE_X}{87}{STRINGID} STR_5444 :속도: @@ -3251,8 +3251,8 @@ STR_5790 :{SMALLFONT}{BLACK}RCT1식으로 돈을 받습니다.{NEWLINE}(예: STR_5791 :{SMALLFONT}{BLACK}모든 놀이기구의 신뢰도를 100%로 설정하고{NEWLINE}건설 시점을 "올해"로 바꿉니다. STR_5792 :{SMALLFONT}{BLACK}고장난 놀이기구를 모두 고칩니다. STR_5793 :{SMALLFONT}{BLACK}놀이기구의 충돌 이력을 제거하여,{NEWLINE}손님들이 안전하지 않다고 불평하지 않게 만듭니다. -STR_5794 :{SMALLFONT}{BLACK}일부 시나리오에서 공원에 이미 존재하는 놀이기구를 수정할 수 없게 해놓은 것을 해제해줍니다. -STR_5795 :{SMALLFONT}{BLACK}손님들이 놀이기구의 격렬도가 아무리 높아도 그 놀이기구에 타도록 만듭니다. +STR_5794 :{SMALLFONT}{BLACK}일부 시나리오에서 공원에 이미 존재하는 놀이기구를 수정할 수 없게 해놓은 것을 해제합니다. +STR_5795 :{SMALLFONT}{BLACK}놀이기구의 격렬도가 아무리 높아도 손님들이 그 놀이기구에 타도록 만듭니다. STR_5796 :{SMALLFONT}{BLACK}공원의 문을 강제로 열거나 닫습니다. STR_5797 :{SMALLFONT}{BLACK}날씨를 선택한 날씨로 고정하고 바뀌지 않게 만듭니다. STR_5798 :{SMALLFONT}{BLACK}일시정지 상태에서 건설을 허용합니다. @@ -3279,7 +3279,7 @@ STR_5817 :{SMALLFONT}{BLACK}게임 UI 크기 조절 방식을 설정합니다 STR_5819 :{SMALLFONT}{BLACK}[하드웨어 디스플레이 설정 필요]{NEWLINE}스팀 인게임 오버레이가 열려있으면 게임을 일시정지시킵니다. STR_5820 :{SMALLFONT}{BLACK}전체 화면 모드에서 커서가 게임 밖으로 나가면 게임을 최소화시킵니다. STR_5822 :{SMALLFONT}{BLACK}낮밤을 순환하도록 설정합니다.{NEWLINE}낮밤이 바뀌는 데에는 한 달이 걸립니다. -STR_5823 :{SMALLFONT}{BLACK}팻말의 영문을 대문자로 표시합니다. (RCT1처럼) +STR_5823 :{SMALLFONT}{BLACK}RCT1처럼 팻말의 영문을 대문자로 표시합니다. STR_5824 :{SMALLFONT}{BLACK}폭풍이 칠 때 번개가 치는 효과를 끕니다. STR_5825 :{SMALLFONT}{BLACK}마우스 커서를 화면 밖으로 나가지 못하게 만듭니다. STR_5826 :{SMALLFONT}{BLACK}게임 화면에서 마우스 오른쪽 클릭으로 드래그할 때의 방향을 반대로 바꿉니다. @@ -3298,8 +3298,8 @@ STR_5838 :{SMALLFONT}{BLACK}메인 메뉴에 재정 창을 위한 별도의 STR_5839 :{SMALLFONT}{BLACK}메인 매뉴에 연구 및 개발 창을 위한 별도의 버튼을 표시합니다. STR_5840 :{SMALLFONT}{BLACK}메인 메뉴에 치트 창을 위한 별도의 버튼을 표시합니다. STR_5841 :{SMALLFONT}{BLACK}메인 메뉴에 최근 메시지 창을 위한 별도의 버튼을 표시합니다. -STR_5842 :{SMALLFONT}{BLACK}시나리오를 (RCT2처럼) 난이도 별로 정렬하거나 (RCT1처럼) 출신 게임별로 정렬합니다. -STR_5843 :{SMALLFONT}{BLACK}(RCT1 처럼) 시나리오를 클리어하면 다음 시나리오를 해제합니다. +STR_5842 :{SMALLFONT}{BLACK}시나리오를 RCT2처럼 난이도별로 정렬하거나, RCT1처럼 출신 게임별로 정렬합니다. +STR_5843 :{SMALLFONT}{BLACK}RCT1처럼 시나리오를 클리어하면 다음 시나리오를 해제합니다. STR_5844 :{SMALLFONT}{BLACK}멀티 플레이 서버에서 비동기화나 오류가 발생하여도 접속을 유지합니다. STR_5845 :{SMALLFONT}{BLACK}메인 메뉴에 디버깅 툴을 위한 버튼을 추가합니다.{NEWLINE}개발자 콘솔을 여는 키보드 단축키가 활성화됩니다. STR_5846 :{SMALLFONT}{BLACK}OpenRCT2의 자동 저장 빈도를 설정합니다. @@ -3515,8 +3515,8 @@ STR_6056 :{SMALLFONT}{BLACK}음소거 STR_6057 :{SMALLFONT}{BLACK}메인 메뉴에 음소거를 설정할 수 있는 별도의 버튼을 표시합니다. STR_6058 :음소거 STR_6059 :» -STR_6060 :손님의 돈 사용을 애니메이션 효과로 표시 -STR_6061 :{SMALLFONT}{BLACK}손님들이 돈을 사용하면{NEWLINE}움직이는 효과로 표시해줍니다. +STR_6060 :손님이 돈을 쓰면 화면에 표시 +STR_6061 :{SMALLFONT}{BLACK}손님들이 돈을 사용하면{NEWLINE}화면에 움직이는 글씨로 표시해줍니다. STR_6062 :{OUTLINE}{GREEN}+ {CURRENCY2DP} STR_6063 :{OUTLINE}{RED}- {CURRENCY2DP} STR_6064 :모든 땅 소유 From abf72eda7f0b60399e79018ec5f2ce12c4c0008a Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 24 May 2019 19:31:29 +0100 Subject: [PATCH 406/506] Fix #9293: Issue with the native load/save dialog (#9294) Do not set OpenRCT2 as the owner of the file dialog so that it has its own taskbar button and can be independently focused. --- distribution/changelog.txt | 1 + src/openrct2-ui/UiContext.Win32.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b6df9f9e4c..b1877ade72 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -47,6 +47,7 @@ - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Fix: [#9240] Crash when passing directory instead of save file. +- Fix: [#9293] Issue with the native load/save dialog. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2-ui/UiContext.Win32.cpp b/src/openrct2-ui/UiContext.Win32.cpp index 67b6365b97..c9b0e99538 100644 --- a/src/openrct2-ui/UiContext.Win32.cpp +++ b/src/openrct2-ui/UiContext.Win32.cpp @@ -109,7 +109,6 @@ namespace OpenRCT2::Ui // Set open file name options OPENFILENAMEW openFileName = {}; openFileName.lStructSize = sizeof(OPENFILENAMEW); - openFileName.hwndOwner = GetHWND(window); openFileName.lpstrTitle = wcTitle.c_str(); openFileName.lpstrInitialDir = wcInitialDirectory.c_str(); openFileName.lpstrFilter = wcFilters.c_str(); From 6a8b218fd9dd61f6b78642f1dc65550e227eec77 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sun, 26 May 2019 12:43:00 +0200 Subject: [PATCH 407/506] Rename remaining unnamed G2 images. (#9308) --- resources/g2/icons/{58.png => news_messages.png} | Bin resources/g2/icons/{31.png => title_play.png} | Bin resources/g2/icons/{29.png => title_restart.png} | Bin resources/g2/icons/{32.png => title_skip.png} | Bin resources/g2/icons/{30.png => title_stop.png} | Bin resources/g2/{7.png => placeholder.png} | Bin resources/g2/sprites.json | 12 ++++++------ 7 files changed, 6 insertions(+), 6 deletions(-) rename resources/g2/icons/{58.png => news_messages.png} (100%) rename resources/g2/icons/{31.png => title_play.png} (100%) rename resources/g2/icons/{29.png => title_restart.png} (100%) rename resources/g2/icons/{32.png => title_skip.png} (100%) rename resources/g2/icons/{30.png => title_stop.png} (100%) rename resources/g2/{7.png => placeholder.png} (100%) diff --git a/resources/g2/icons/58.png b/resources/g2/icons/news_messages.png similarity index 100% rename from resources/g2/icons/58.png rename to resources/g2/icons/news_messages.png diff --git a/resources/g2/icons/31.png b/resources/g2/icons/title_play.png similarity index 100% rename from resources/g2/icons/31.png rename to resources/g2/icons/title_play.png diff --git a/resources/g2/icons/29.png b/resources/g2/icons/title_restart.png similarity index 100% rename from resources/g2/icons/29.png rename to resources/g2/icons/title_restart.png diff --git a/resources/g2/icons/32.png b/resources/g2/icons/title_skip.png similarity index 100% rename from resources/g2/icons/32.png rename to resources/g2/icons/title_skip.png diff --git a/resources/g2/icons/30.png b/resources/g2/icons/title_stop.png similarity index 100% rename from resources/g2/icons/30.png rename to resources/g2/icons/title_stop.png diff --git a/resources/g2/7.png b/resources/g2/placeholder.png similarity index 100% rename from resources/g2/7.png rename to resources/g2/placeholder.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 6a77ebd8b8..88fc27a638 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -21,7 +21,7 @@ "path": "icons/map_gen_land.png" }, { - "path": "7.png" + "path": "placeholder.png" }, { "path": "icons/zoom_in.png" @@ -87,16 +87,16 @@ "path": "icons/rct1_open_on_pressed.png" }, { - "path": "icons/29.png" + "path": "icons/title_restart.png" }, { - "path": "icons/30.png" + "path": "icons/title_stop.png" }, { - "path": "icons/31.png" + "path": "icons/title_play.png" }, { - "path": "icons/32.png" + "path": "icons/title_skip.png" }, { "path": "icons/cheats.png" @@ -174,7 +174,7 @@ "path": "track/junior/steep_to_flat_lift_3_2.png" }, { - "path": "icons/58.png" + "path": "icons/news_messages.png" }, { "path": "icons/server_password.png" From f26a1aee5749582a4ea49377b45baf7ddea47002 Mon Sep 17 00:00:00 2001 From: Sijmen Schoon Date: Sun, 26 May 2019 16:06:56 +0200 Subject: [PATCH 408/506] Fix compile error with DISABLE_HTTP (#9309) There are two variables, MASTER_SERVER_REGISTER_TIME and MASTER_SERVER_HEARTBEAT_TIME, which are unused when DISABLE_HTTP is set. This commit fixes that. --- src/openrct2/network/NetworkServerAdvertiser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 9b857ce525..e712a1a38a 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -41,8 +41,10 @@ enum MASTER_SERVER_STATUS MASTER_SERVER_STATUS_INTERNAL_ERROR = 500 }; +# ifndef DISABLE_HTTP constexpr int32_t MASTER_SERVER_REGISTER_TIME = 120 * 1000; // 2 minutes constexpr int32_t MASTER_SERVER_HEARTBEAT_TIME = 60 * 1000; // 1 minute +# endif class NetworkServerAdvertiser final : public INetworkServerAdvertiser { From 1cf4f17ee6004bc982cb9cf51eac159c521c0b7a Mon Sep 17 00:00:00 2001 From: James Warwood Date: Mon, 27 May 2019 21:37:31 +0100 Subject: [PATCH 409/506] Fix: Unable to use second skyscraper terrain edge style Code to check if selected edge style is valid was passing the wrong object type (surface instead of edge) to GetLoadedObject, causing that method to warn that the selected edge style index was out-of-range. --- src/openrct2/actions/SurfaceSetStyleAction.hpp | 2 +- src/openrct2/network/Network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/SurfaceSetStyleAction.hpp b/src/openrct2/actions/SurfaceSetStyleAction.hpp index 22ec7a0149..45e8d965e0 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.hpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.hpp @@ -88,7 +88,7 @@ public: } const auto edgeObj = static_cast( - objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _edgeStyle)); + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, _edgeStyle)); if (edgeObj == nullptr) { diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 8b3dae255b..3429d978fb 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 "34" +#define NETWORK_STREAM_VERSION "35" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 46889b5381b8464b89d6bb2519889f622f62e930 Mon Sep 17 00:00:00 2001 From: nexgenration Date: Mon, 27 May 2019 16:39:03 -0400 Subject: [PATCH 410/506] Implement #9231: Add sprite_index to Guest Debug Tab --- data/language/en-GB.txt | 1 + src/openrct2-ui/windows/Guest.cpp | 7 ++++++- src/openrct2/localisation/StringIds.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 0f82efe2c3..56d0323e58 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3769,6 +3769,7 @@ STR_6318 :Network desync detected.{NEWLINE}Log file: {STRING} STR_6319 :{WINDOW_COLOUR_2}Block Brake Closed STR_6320 :{WINDOW_COLOUR_2}Indestructible STR_6321 :{WINDOW_COLOUR_2}Addition is broken +STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} ############# # Scenarios # diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index befd243a37..ea051bee58 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -486,7 +486,7 @@ static constexpr const rct_size16 window_guest_page_sizes[][2] = { { 210, 148, 210, 148 }, // WINDOW_GUEST_FINANCE { 192, 159, 500, 450 }, // WINDOW_GUEST_THOUGHTS { 192, 159, 500, 450 }, // WINDOW_GUEST_INVENTORY - { 192, 159, 192, 159 } // WINDOW_GUEST_DEBUG + { 192, 159, 192, 171 } // WINDOW_GUEST_DEBUG }; // clang-format on @@ -2067,6 +2067,11 @@ void window_guest_debug_paint(rct_window* w, rct_drawpixelinfo* dpi) auto peep = GET_PEEP(w->number); auto x = w->x + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].left + 4; auto y = w->y + window_guest_debug_widgets[WIDX_PAGE_BACKGROUND].top + 4; + { + set_format_arg(0, uint32_t, peep->sprite_index); + gfx_draw_string_left(dpi, STR_PEEP_DEBUG_SPRITE_INDEX, gCommonFormatArgs, 0, x, y); + } + y += LIST_ROW_HEIGHT; { int32_t args[] = { peep->x, peep->y, peep->x }; gfx_draw_string_left(dpi, STR_PEEP_DEBUG_POSITION, args, 0, x, y); diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index d0fa8b27ca..4e26c2a50b 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3955,6 +3955,7 @@ enum STR_PEEP_DEBUG_PATHFIND_GOAL = 6315, STR_PEEP_DEBUG_PATHFIND_HISTORY = 6316, STR_PEEP_DEBUG_PATHFIND_HISTORY_ITEM = 6317, + STR_PEEP_DEBUG_SPRITE_INDEX = 6322, STR_DESYNC_REPORT = 6318, From c4e18e570ee09a036635d8516b9c231288977132 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 20:14:21 +0100 Subject: [PATCH 411/506] Add and implement simulation mode for rides --- data/language/en-GB.txt | 3 + distribution/changelog.txt | 1 + src/openrct2-ui/windows/Ride.cpp | 79 +++++++++++++------ src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2/actions/RideDemolishAction.hpp | 2 +- .../actions/RideEntranceExitPlaceAction.hpp | 2 +- .../actions/RideEntranceExitRemoveAction.hpp | 2 +- src/openrct2/actions/RideSetSetting.hpp | 2 +- src/openrct2/actions/RideSetStatus.hpp | 37 ++++++++- .../actions/RideSetVehiclesAction.hpp | 2 +- src/openrct2/localisation/StringIds.h | 4 + src/openrct2/paint/Paint.h | 2 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/ride/Ride.cpp | 45 +++++------ src/openrct2/ride/Ride.h | 5 +- src/openrct2/ride/Vehicle.cpp | 40 +++++++++- src/openrct2/ride/VehiclePaint.cpp | 20 +++++ 17 files changed, 185 insertions(+), 65 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 56d0323e58..ebd2c98aad 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3770,6 +3770,9 @@ STR_6319 :{WINDOW_COLOUR_2}Block Brake Closed STR_6320 :{WINDOW_COLOUR_2}Indestructible STR_6321 :{WINDOW_COLOUR_2}Addition is broken STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} +STR_6323 :Simulating +STR_6324 :Simulate +STR_6325 :{SMALLFONT}{BLACK}Simulate ride/attraction ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b1877ade72..dcd7fc082b 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ +- Feature: [#485] Rides can now be simulated with ghost trains during construction. - Feature: [#2339] Find local servers automatically when fetching servers. - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index c0d3f92e61..61ef2f47a3 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -98,6 +98,7 @@ enum { WIDX_LOCATE, WIDX_DEMOLISH, WIDX_CLOSE_LIGHT, + WIDX_SIMULATE_LIGHT, WIDX_TEST_LIGHT, WIDX_OPEN_LIGHT, WIDX_RIDE_TYPE, @@ -231,6 +232,7 @@ static rct_widget window_ride_main_widgets[] = { { WWT_FLATBTN, 1, 291, 314, 118, 141, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP }, { WWT_FLATBTN, 1, 291, 314, 142, 165, SPR_DEMOLISH, STR_DEMOLISH_RIDE_TIP }, { WWT_IMGBTN, 1, 296, 309, 48, 61, SPR_G2_RCT1_CLOSE_BUTTON_0, STR_CLOSE_RIDE_TIP }, + { WWT_IMGBTN, 1, 296, 309, 62, 75, SPR_G2_RCT1_TEST_BUTTON_0, STR_SIMULATE_RIDE_TIP }, { WWT_IMGBTN, 1, 296, 309, 62, 75, SPR_G2_RCT1_TEST_BUTTON_0, STR_TEST_RIDE_TIP }, { WWT_IMGBTN, 1, 296, 309, 76, 89, SPR_G2_RCT1_OPEN_BUTTON_0, STR_OPEN_RIDE_TIP }, { WWT_DROPDOWN, 1, 3, 307, 180, 191, STR_ARG_6_STRINGID, STR_NONE }, @@ -397,6 +399,7 @@ static constexpr const uint64_t window_ride_page_enabled_widgets[] = { (1ULL << WIDX_LOCATE) | (1ULL << WIDX_DEMOLISH) | (1ULL << WIDX_CLOSE_LIGHT) | + (1ULL << WIDX_SIMULATE_LIGHT) | (1ULL << WIDX_TEST_LIGHT) | (1ULL << WIDX_OPEN_LIGHT) | (1ULL << WIDX_RIDE_TYPE) | @@ -2024,6 +2027,7 @@ static void window_ride_main_mouseup(rct_window* w, rct_widgetindex widgetIndex) context_open_detail_window(WD_DEMOLISH_RIDE, w->number); break; case WIDX_CLOSE_LIGHT: + case WIDX_SIMULATE_LIGHT: case WIDX_TEST_LIGHT: case WIDX_OPEN_LIGHT: switch (widgetIndex) @@ -2032,6 +2036,9 @@ static void window_ride_main_mouseup(rct_window* w, rct_widgetindex widgetIndex) case WIDX_CLOSE_LIGHT: status = RIDE_STATUS_CLOSED; break; + case WIDX_SIMULATE_LIGHT: + status = RIDE_STATUS_SIMULATING; + break; case WIDX_TEST_LIGHT: status = RIDE_STATUS_TESTING; break; @@ -2060,7 +2067,7 @@ static void window_ride_main_resize(rct_window* w) int32_t minHeight = 180 + offset; if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE) minHeight = 200 + offset + RCT1_LIGHT_OFFSET - - (ride_type_has_flag(get_ride(w->number)->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 : 0); + - (ride_type_has_flag(get_ride(w->number)->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 * 2 : 0); window_set_resize(w, 316, minHeight, 500, 450); window_ride_init_viewport(w); } @@ -2130,7 +2137,7 @@ static void window_ride_show_view_dropdown(rct_window* w, rct_widget* widget) static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) { Ride* ride; - int32_t numItems, highlightedIndex = 0, checkedIndex; + int32_t numItems, highlightedIndex = 0; ride = get_ride(w->number); @@ -2141,6 +2148,10 @@ static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) { + gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[numItems] = STR_SIMULATE_RIDE; + numItems++; + gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; gDropdownItemsArgs[numItems] = STR_TEST_RIDE; numItems++; @@ -2153,47 +2164,52 @@ static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) window_dropdown_show_text( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[1], 0, numItems); - checkedIndex = ride->status; + auto checkedIndex = -1; switch (ride->status) { case RIDE_STATUS_CLOSED: + checkedIndex = 0; highlightedIndex = 0; if ((ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) || (ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE)) break; + highlightedIndex = 3; + if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + highlightedIndex = 2; + break; + case RIDE_STATUS_SIMULATING: + checkedIndex = 1; highlightedIndex = 2; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) - break; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) - break; - - highlightedIndex = 1; + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + highlightedIndex = 0; break; case RIDE_STATUS_TESTING: - highlightedIndex = 2; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) - break; - - highlightedIndex = 0; + checkedIndex = 2; + highlightedIndex = 3; + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + highlightedIndex = 3; break; case RIDE_STATUS_OPEN: + checkedIndex = 3; highlightedIndex = 0; break; } - if (checkedIndex != RIDE_STATUS_CLOSED) - checkedIndex = 3 - checkedIndex; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) { - if (checkedIndex != 0) - checkedIndex--; - if (highlightedIndex != 0) - highlightedIndex--; + // Open item is now index 1 + if (checkedIndex == 3) + checkedIndex = 1; + if (highlightedIndex == 3) + highlightedIndex = 1; } - dropdown_set_checked(checkedIndex, true); + if (checkedIndex != -1) + { + dropdown_set_checked(checkedIndex, true); + } gDropdownDefaultIndex = highlightedIndex; } @@ -2412,7 +2428,7 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex ride = get_ride(w->number); if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) && dropdownIndex != 0) - dropdownIndex++; + dropdownIndex += 2; switch (dropdownIndex) { @@ -2420,9 +2436,12 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex status = RIDE_STATUS_CLOSED; break; case 1: - status = RIDE_STATUS_TESTING; + status = RIDE_STATUS_SIMULATING; break; case 2: + status = RIDE_STATUS_TESTING; + break; + case 3: status = RIDE_STATUS_OPEN; break; } @@ -2533,11 +2552,14 @@ static void window_ride_main_invalidate(rct_window* w) SPR_CLOSED, SPR_OPEN, SPR_TESTING, + SPR_TESTING | (COLOUR_WHITE << 19 | COLOUR_WHITE << 24 | IMAGE_TYPE_REMAP), }; window_ride_main_widgets[WIDX_OPEN].image = spriteIds[ride->status]; window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (ride->status == RIDE_STATUS_CLOSED) * 2 + widget_is_pressed(w, WIDX_CLOSE_LIGHT); + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + + (ride->status == RIDE_STATUS_SIMULATING) * 2 + widget_is_pressed(w, WIDX_SIMULATE_LIGHT); window_ride_main_widgets[WIDX_TEST_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + (ride->status == RIDE_STATUS_TESTING) * 2 + widget_is_pressed(w, WIDX_TEST_LIGHT); window_ride_main_widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (ride->status == RIDE_STATUS_OPEN) * 2 @@ -2580,11 +2602,19 @@ static void window_ride_main_invalidate(rct_window* w) { window_ride_main_widgets[WIDX_OPEN].type = WWT_EMPTY; window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN; + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type + = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN); window_ride_main_widgets[WIDX_TEST_LIGHT].type = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN); window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN; height = 62; + if (window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type != WWT_EMPTY) + { + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].top = height; + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].bottom = height + 13; + height += 14; + } if (window_ride_main_widgets[WIDX_TEST_LIGHT].type != WWT_EMPTY) { window_ride_main_widgets[WIDX_TEST_LIGHT].top = height; @@ -2603,6 +2633,7 @@ static void window_ride_main_invalidate(rct_window* w) { window_ride_main_widgets[WIDX_OPEN].type = WWT_FLATBTN; window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_EMPTY; + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type = WWT_EMPTY; window_ride_main_widgets[WIDX_TEST_LIGHT].type = WWT_EMPTY; window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_EMPTY; height = 46; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 408d789a8c..e5ed3c16f2 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2026,7 +2026,7 @@ static void window_ride_construction_update(rct_window* w) // Close construction window if ride is not closed, // editing ride while open will cause many issues until properly handled - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { window_close(w); return; diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index bca4f79d94..73562abf3b 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -78,7 +78,7 @@ public: if (_modifyType == RIDE_MODIFY_RENEW) { - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { return std::make_unique( GA_ERROR::DISALLOWED, STR_CANT_REFURBISH_RIDE, STR_MUST_BE_CLOSED_FIRST); diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp index 7c584689d2..83e77d84e1 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp @@ -79,7 +79,7 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle); } - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { return MakeResult(GA_ERROR::NOT_CLOSED, errorTitle, STR_MUST_BE_CLOSED_FIRST); } diff --git a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp index c13f1deaa3..88ce3f3536 100644 --- a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp +++ b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp @@ -60,7 +60,7 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_MUST_BE_CLOSED_FIRST); } diff --git a/src/openrct2/actions/RideSetSetting.hpp b/src/openrct2/actions/RideSetSetting.hpp index ade1fcb5a4..ed560e9053 100644 --- a/src/openrct2/actions/RideSetSetting.hpp +++ b/src/openrct2/actions/RideSetSetting.hpp @@ -82,7 +82,7 @@ public: GA_ERROR::DISALLOWED, STR_CANT_CHANGE_OPERATING_MODE, STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING); } - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_CHANGE_OPERATING_MODE, STR_MUST_BE_CLOSED_FIRST); } diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index 5dff42ab41..3e5adc6eb8 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -73,9 +73,9 @@ public: if (_status != ride->status) { - if (_status == RIDE_STATUS_TESTING) + if (_status == RIDE_STATUS_TESTING || _status == RIDE_STATUS_SIMULATING) { - if (!ride_is_valid_for_test(ride, _status == RIDE_STATUS_OPEN, 0)) + if (!ride_is_valid_for_test(ride, _status, 0)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; @@ -123,7 +123,7 @@ public: switch (_status) { case RIDE_STATUS_CLOSED: - if (ride->status == _status) + if (ride->status == _status || ride->status == RIDE_STATUS_SIMULATING) { if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { @@ -139,6 +139,29 @@ public: ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; window_invalidate_by_number(WC_RIDE, _rideIndex); break; + case RIDE_STATUS_SIMULATING: + { + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + + if (!ride_is_valid_for_test(ride, _status, 1)) + { + res->Error = GA_ERROR::UNKNOWN; + res->ErrorMessage = gGameCommandErrorText; + return res; + } + + ride->status = _status; + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING; + ride->race_winner = SPRITE_INDEX_NULL; + ride->current_issues = 0; + ride->last_issue_time = 0; + ride_get_measurement(ride, nullptr); + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + window_invalidate_by_number(WC_RIDE, _rideIndex); + break; + } case RIDE_STATUS_TESTING: case RIDE_STATUS_OPEN: { @@ -147,6 +170,12 @@ public: return res; } + if (ride->status == RIDE_STATUS_SIMULATING) + { + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + } + // Fix #3183: Make sure we close the construction window so the ride finishes any editing code before opening // otherwise vehicles get added to the ride incorrectly (such as to a ghost station) rct_window* constructionWindow = window_find_by_number(WC_RIDE_CONSTRUCTION, _rideIndex); @@ -157,7 +186,7 @@ public: if (_status == RIDE_STATUS_TESTING) { - if (!ride_is_valid_for_test(ride, _status == RIDE_STATUS_OPEN, 1)) + if (!ride_is_valid_for_test(ride, _status, 1)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; diff --git a/src/openrct2/actions/RideSetVehiclesAction.hpp b/src/openrct2/actions/RideSetVehiclesAction.hpp index 04a8e3b04a..69b89c02ac 100644 --- a/src/openrct2/actions/RideSetVehiclesAction.hpp +++ b/src/openrct2/actions/RideSetVehiclesAction.hpp @@ -92,7 +92,7 @@ public: return std::make_unique(GA_ERROR::BROKEN, errTitle, STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING); } - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { return std::make_unique(GA_ERROR::NOT_CLOSED, errTitle, STR_MUST_BE_CLOSED_FIRST); } diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 4e26c2a50b..838aa3f577 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3959,6 +3959,10 @@ enum STR_DESYNC_REPORT = 6318, + STR_SIMULATING = 6323, + STR_SIMULATE_RIDE = 6324, + STR_SIMULATE_RIDE_TIP = 6325, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 6128bc14c1..3d7780b6af 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -182,7 +182,7 @@ extern LocationXY8 gClipSelectionA; extern LocationXY8 gClipSelectionB; /** rct2: 0x00993CC4. The white ghost that indicates not-yet-built elements. */ -#define CONSTRUCTION_MARKER (COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP); +#define CONSTRUCTION_MARKER (COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP) extern bool gShowDirtyVisuals; extern bool gPaintBoundingBoxes; extern bool gPaintBlockedTiles; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 2a82a05de6..6aba5ec4c7 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -5404,7 +5404,7 @@ void Guest::UpdateQueuing() return; } Ride* ride = get_ride(current_ride); - if (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_TESTING) + if (ride->status != RIDE_STATUS_OPEN) { RemoveFromQueue(); SetState(PEEP_STATE_1); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9345dc4adc..4763cc3198 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -897,7 +897,12 @@ void ride_get_status(const Ride* ride, rct_string_id* formatSecondary, int32_t* return; } - if (ride->status == RIDE_STATUS_TESTING) + else if (ride->status == RIDE_STATUS_SIMULATING) + { + *formatSecondary = STR_SIMULATING; + return; + } + else if (ride->status == RIDE_STATUS_TESTING) { *formatSecondary = STR_TEST_RUN; return; @@ -1024,7 +1029,7 @@ static int32_t ride_check_if_construction_allowed(Ride* ride) return 0; } - if (ride->status != RIDE_STATUS_CLOSED) + if (ride->status != RIDE_STATUS_CLOSED && ride->status != RIDE_STATUS_SIMULATING) { set_format_arg(6, rct_string_id, ride->name); set_format_arg(8, uint32_t, ride->name_arguments); @@ -1985,7 +1990,10 @@ int32_t ride_modify(CoordsXYE* input) } // Stop the ride again to clear all vehicles and peeps (compatible with network games) - ride_set_status(ride, RIDE_STATUS_CLOSED); + if (ride->status != RIDE_STATUS_SIMULATING) + { + ride_set_status(ride, RIDE_STATUS_CLOSED); + } // Check if element is a station entrance or exit if (tileElement.element->GetType() == TILE_ELEMENT_TYPE_ENTRANCE) @@ -2192,24 +2200,10 @@ void Ride::Update() ride_inspection_update(this); - if (status == RIDE_STATUS_TESTING && gConfigGeneral.no_test_crashes) + // If ride is simulating but crashed, reset the vehicles + if (status == RIDE_STATUS_SIMULATING && (lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { - for (int32_t i = 0; i < num_vehicles; i++) - { - uint16_t spriteIndex = vehicles[i]; - if (spriteIndex == SPRITE_INDEX_NULL) - continue; - - rct_vehicle* vehicle = GET_VEHICLE(spriteIndex); - - if (vehicle->status == VEHICLE_STATUS_CRASHED || vehicle->status == VEHICLE_STATUS_CRASHING) - { - ride_set_status(this, RIDE_STATUS_CLOSED); - ride_set_status(this, RIDE_STATUS_CLOSED); - ride_set_status(this, RIDE_STATUS_TESTING); - break; - } - } + ride_set_status(this, RIDE_STATUS_SIMULATING); } } @@ -5396,7 +5390,7 @@ static TileElement* loc_6B4F6B(ride_id_t rideIndex, int32_t x, int32_t y) return nullptr; } -int32_t ride_is_valid_for_test(Ride* ride, int32_t goingToBeOpen, int32_t isApplying) +int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying) { int32_t stationIndex; CoordsXYE trackElement, problematicTrackElement = {}; @@ -5407,7 +5401,10 @@ int32_t ride_is_valid_for_test(Ride* ride, int32_t goingToBeOpen, int32_t isAppl return 0; } - window_close_by_number(WC_RIDE_CONSTRUCTION, ride->id); + if (status != RIDE_STATUS_SIMULATING) + { + window_close_by_number(WC_RIDE_CONSTRUCTION, ride->id); + } stationIndex = ride_mode_check_station_present(ride); if (stationIndex == -1) @@ -5422,7 +5419,7 @@ int32_t ride_is_valid_for_test(Ride* ride, int32_t goingToBeOpen, int32_t isAppl return 0; } - if (goingToBeOpen && isApplying) + if (status == RIDE_STATUS_OPEN && isApplying) { sub_6B5952(ride); ride->lifecycle_flags |= RIDE_LIFECYCLE_EVER_BEEN_OPENED; @@ -5443,7 +5440,7 @@ int32_t ride_is_valid_for_test(Ride* ride, int32_t goingToBeOpen, int32_t isAppl || ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED) { if (ride_find_track_gap(ride, &trackElement, &problematicTrackElement) - && (!gConfigGeneral.test_unfinished_tracks || ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED + && (status != RIDE_STATUS_SIMULATING || ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)) { gGameCommandErrorText = STR_TRACK_IS_NOT_A_COMPLETE_CIRCUIT; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 34bbbc86c3..4b122ba6ad 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -631,7 +631,8 @@ enum { RIDE_STATUS_CLOSED, RIDE_STATUS_OPEN, - RIDE_STATUS_TESTING + RIDE_STATUS_TESTING, + RIDE_STATUS_SIMULATING, }; enum @@ -1074,7 +1075,7 @@ rct_ride_measurement* ride_get_measurement(Ride* ride, rct_string_id* message); void ride_breakdown_add_news_item(Ride* ride); Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection); int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, int32_t isApplying); -int32_t ride_is_valid_for_test(Ride* ride, int32_t goingToBeOpen, int32_t isApplying); +int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying); int32_t ride_initialise_construction_window(Ride* ride); void ride_construction_invalidate_current_track(); int32_t sub_6C683D( diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index c6f812854f..678d4fcfd4 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3520,6 +3520,15 @@ static void vehicle_check_if_missing(rct_vehicle* vehicle) news_item_add_to_queue(NEWS_ITEM_RIDE, STR_NEWS_VEHICLE_HAS_STALLED, vehicle->ride); } +static void vehicle_simulate_crash(rct_vehicle* vehicle) +{ + auto ride = get_ride(vehicle->ride); + if (ride != nullptr) + { + ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED; + } +} + /** * Setup function for a vehicle colliding with * another vehicle. @@ -3528,10 +3537,16 @@ static void vehicle_check_if_missing(rct_vehicle* vehicle) */ static void vehicle_update_collision_setup(rct_vehicle* vehicle) { + auto ride = get_ride(vehicle->ride); + if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) + { + vehicle_simulate_crash(vehicle); + return; + } + vehicle->status = VEHICLE_STATUS_CRASHED; vehicle_invalidate_window(vehicle); - Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { auto frontVehicle = vehicle->GetHead(); @@ -3603,6 +3618,13 @@ static constexpr const LocationXY16 stru_9A3AC4[] = { */ static void vehicle_update_crash_setup(rct_vehicle* vehicle) { + auto ride = get_ride(vehicle->ride); + if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) + { + vehicle_simulate_crash(vehicle); + return; + } + vehicle->status = VEHICLE_STATUS_CRASHING; vehicle_invalidate_window(vehicle); @@ -5266,10 +5288,16 @@ static void vehicle_kill_all_passengers(rct_vehicle* vehicle) static void vehicle_crash_on_land(rct_vehicle* vehicle) { + auto ride = get_ride(vehicle->ride); + if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) + { + vehicle_simulate_crash(vehicle); + return; + } + vehicle->status = VEHICLE_STATUS_CRASHED; vehicle_invalidate_window(vehicle); - Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { auto frontVehicle = vehicle->GetHead(); @@ -5320,10 +5348,16 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) static void vehicle_crash_on_water(rct_vehicle* vehicle) { + auto ride = get_ride(vehicle->ride); + if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) + { + vehicle_simulate_crash(vehicle); + return; + } + vehicle->status = VEHICLE_STATUS_CRASHED; vehicle_invalidate_window(vehicle); - Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { auto frontVehicle = vehicle->GetHead(); diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index e1d91f78ac..e7d40507d4 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -899,6 +899,13 @@ static void vehicle_sprite_paint( } vehicle_boundbox bb = VehicleBoundboxes[vehicleEntry->draw_order][ecx]; + bool isGhost = false; + auto ride = get_ride(vehicle->ride); + if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) + { + isGhost = true; + } + if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) { baseImage_id += (vehicle->spin_sprite / 8) & 31; @@ -909,6 +916,12 @@ static void vehicle_sprite_paint( } int32_t image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | IMAGE_TYPE_REMAP_2_PLUS; + + if (isGhost) + { + image_id &= 0x7FFFF; + image_id |= CONSTRUCTION_MARKER; + } paint_struct* ps = sub_98197C( session, image_id, 0, 0, bb.length_x, bb.length_y, bb.length_z, z, bb.offset_x, bb.offset_y, bb.offset_z + z); if (ps != nullptr) @@ -930,6 +943,13 @@ static void vehicle_sprite_paint( { image_id += (vehicleEntry->no_vehicle_images * vehicle->animation_frame); } + + if (isGhost) + { + image_id &= 0x7FFFF; + image_id |= CONSTRUCTION_MARKER; + } + sub_98199C( session, image_id, 0, 0, bb.length_x, bb.length_y, bb.length_z, z, bb.offset_x, bb.offset_y, bb.offset_z + z); From fec6d660c60b3d41186e8dcc2c8f6d5159021501 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 7 May 2019 23:10:05 +0100 Subject: [PATCH 412/506] Remove obsolete configs: - no crashes - test unfinished track --- src/openrct2-ui/windows/Options.cpp | 29 +++++++------------ src/openrct2/config/Config.cpp | 7 ----- src/openrct2/config/Config.h | 2 -- src/openrct2/interface/InteractiveConsole.cpp | 22 -------------- src/openrct2/localisation/StringIds.h | 2 -- 5 files changed, 10 insertions(+), 52 deletions(-) diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index c41600f2fd..0392859bc7 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -173,7 +173,6 @@ enum WINDOW_OPTIONS_WIDGET_IDX { // Advanced WIDX_DEBUGGING_TOOLS = WIDX_PAGE_START, - WIDX_TEST_UNFINISHED_TRACKS, WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, WIDX_SAVE_PLUGIN_DATA_CHECKBOX, WIDX_STAY_CONNECTED_AFTER_DESYNC, @@ -359,17 +358,16 @@ static rct_widget window_options_misc_widgets[] = { static rct_widget window_options_advanced_widgets[] = { MAIN_OPTIONS_WIDGETS, { WWT_CHECKBOX, 2, 10, 299, 54, 65, STR_ENABLE_DEBUGGING_TOOLS, STR_ENABLE_DEBUGGING_TOOLS_TIP }, // Enable debugging tools - { WWT_CHECKBOX, 2, 10, 299, 69, 80, STR_TEST_UNFINISHED_TRACKS, STR_TEST_UNFINISHED_TRACKS_TIP }, // Test unfinished tracks - { WWT_CHECKBOX, 2, 10, 299, 84, 95, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM_TIP }, // Allow loading with incorrect checksum - { WWT_CHECKBOX, 2, 10, 299, 99, 110, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP }, // Export plug-in objects with saved games - { WWT_CHECKBOX, 2, 10, 299, 114, 125, STR_STAY_CONNECTED_AFTER_DESYNC, STR_STAY_CONNECTED_AFTER_DESYNC_TIP }, // Do not disconnect after the client desynchronises with the server - { WWT_CHECKBOX, 1, 10, 299, 129, 140, STR_ALWAYS_NATIVE_LOADSAVE, STR_ALWAYS_NATIVE_LOADSAVE_TIP }, // Use native load/save window - { WWT_DROPDOWN, 1, 165, 299, 145, 157, STR_NONE, STR_NONE }, // Autosave dropdown - { WWT_BUTTON, 1, 288, 298, 146, 156, STR_DROPDOWN_GLYPH, STR_AUTOSAVE_FREQUENCY_TIP }, // Autosave dropdown button - SPINNER_WIDGETS (1, 165, 299, 165, 176, STR_NONE, STR_AUTOSAVE_AMOUNT_TIP ), // Autosave amount spinner - { WWT_LABEL, 1, 23, 298, 184, 195, STR_PATH_TO_RCT1, STR_PATH_TO_RCT1_TIP }, // RCT 1 path text - { WWT_BUTTON, 1, 24, 289, 199, 212, STR_NONE, STR_STRING_TOOLTIP }, // RCT 1 path button - { WWT_BUTTON, 1, 289, 299, 199, 212, STR_CLOSE_X, STR_PATH_TO_RCT1_CLEAR_TIP }, // RCT 1 path clear button + { WWT_CHECKBOX, 2, 10, 299, 69, 80, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM_TIP }, // Allow loading with incorrect checksum + { WWT_CHECKBOX, 2, 10, 299, 84, 95, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP }, // Export plug-in objects with saved games + { WWT_CHECKBOX, 2, 10, 299, 99, 110, STR_STAY_CONNECTED_AFTER_DESYNC, STR_STAY_CONNECTED_AFTER_DESYNC_TIP }, // Do not disconnect after the client desynchronises with the server + { WWT_CHECKBOX, 1, 10, 299, 114, 125, STR_ALWAYS_NATIVE_LOADSAVE, STR_ALWAYS_NATIVE_LOADSAVE_TIP }, // Use native load/save window + { WWT_DROPDOWN, 1, 165, 299, 130, 142, STR_NONE, STR_NONE }, // Autosave dropdown + { WWT_BUTTON, 1, 288, 298, 131, 141, STR_DROPDOWN_GLYPH, STR_AUTOSAVE_FREQUENCY_TIP }, // Autosave dropdown button + SPINNER_WIDGETS (1, 165, 299, 150, 161, STR_NONE, STR_AUTOSAVE_AMOUNT_TIP ), // Autosave amount spinner + { WWT_LABEL, 1, 23, 298, 169, 180, STR_PATH_TO_RCT1, STR_PATH_TO_RCT1_TIP }, // RCT 1 path text + { WWT_BUTTON, 1, 24, 289, 184, 197, STR_NONE, STR_STRING_TOOLTIP }, // RCT 1 path button + { WWT_BUTTON, 1, 289, 299, 184, 197, STR_CLOSE_X, STR_PATH_TO_RCT1_CLEAR_TIP }, // RCT 1 path clear button { WIDGETS_END }, }; @@ -601,7 +599,6 @@ static uint64_t window_options_page_enabled_widgets[] = { MAIN_OPTIONS_ENABLED_WIDGETS | (1 << WIDX_DEBUGGING_TOOLS) | - (1 << WIDX_TEST_UNFINISHED_TRACKS) | (1 << WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM) | (1 << WIDX_SAVE_PLUGIN_DATA_CHECKBOX) | (1 << WIDX_STAY_CONNECTED_AFTER_DESYNC) | @@ -924,11 +921,6 @@ static void window_options_mouseup(rct_window* w, rct_widgetindex widgetIndex) config_save_default(); gfx_invalidate_screen(); break; - case WIDX_TEST_UNFINISHED_TRACKS: - gConfigGeneral.test_unfinished_tracks ^= 1; - config_save_default(); - window_invalidate(w); - break; case WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM: gConfigGeneral.allow_loading_with_incorrect_checksum = !gConfigGeneral .allow_loading_with_incorrect_checksum; @@ -1926,7 +1918,6 @@ static void window_options_invalidate(rct_window* w) case WINDOW_OPTIONS_PAGE_ADVANCED: widget_set_checkbox_value(w, WIDX_DEBUGGING_TOOLS, gConfigGeneral.debugging_tools); - widget_set_checkbox_value(w, WIDX_TEST_UNFINISHED_TRACKS, gConfigGeneral.test_unfinished_tracks); widget_set_checkbox_value( w, WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, gConfigGeneral.allow_loading_with_incorrect_checksum); widget_set_checkbox_value(w, WIDX_SAVE_PLUGIN_DATA_CHECKBOX, gConfigGeneral.save_plugin_data); diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index edb4251b28..34162c30e3 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -170,11 +170,6 @@ namespace Config model->use_vsync = reader->GetBoolean("use_vsync", true); model->virtual_floor_style = reader->GetEnum( "virtual_floor_style", VIRTUAL_FLOOR_STYLE_GLASSY, Enum_VirtualFloorStyle); - - // Default config setting is false until ghost trains are implemented #4540 - model->test_unfinished_tracks = reader->GetBoolean("test_unfinished_tracks", false); - - model->no_test_crashes = reader->GetBoolean("no_test_crashes", false); model->date_format = reader->GetEnum("date_format", platform_get_locale_date_format(), Enum_DateFormat); model->auto_staff_placement = reader->GetBoolean("auto_staff", true); model->handymen_mow_default = reader->GetBoolean("handymen_mow_default", false); @@ -250,8 +245,6 @@ namespace Config writer->WriteEnum("drawing_engine", model->drawing_engine, Enum_DrawingEngine); writer->WriteBoolean("uncap_fps", model->uncap_fps); writer->WriteBoolean("use_vsync", model->use_vsync); - writer->WriteBoolean("test_unfinished_tracks", model->test_unfinished_tracks); - writer->WriteBoolean("no_test_crashes", model->no_test_crashes); writer->WriteEnum("date_format", model->date_format, Enum_DateFormat); writer->WriteBoolean("auto_staff", model->auto_staff_placement); writer->WriteBoolean("handymen_mow_default", model->handymen_mow_default); diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index b346365967..790982c544 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -70,8 +70,6 @@ struct GeneralConfiguration int32_t window_snap_proximity; bool allow_loading_with_incorrect_checksum; bool save_plugin_data; - bool test_unfinished_tracks; - bool no_test_crashes; bool debugging_tools; int32_t autosave_frequency; int32_t autosave_amount; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 1a2e574e37..92d71a1d02 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -650,14 +650,6 @@ static int32_t cc_get(InteractiveConsole& console, const arguments_t& argv) { console.WriteFormatLine("console_small_font %d", gConfigInterface.console_small_font); } - else if (argv[0] == "test_unfinished_tracks") - { - console.WriteFormatLine("test_unfinished_tracks %d", gConfigGeneral.test_unfinished_tracks); - } - else if (argv[0] == "no_test_crashes") - { - console.WriteFormatLine("no_test_crashes %d", gConfigGeneral.no_test_crashes); - } else if (argv[0] == "location") { rct_window* w = window_get_main(); @@ -916,18 +908,6 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) config_save_default(); console.Execute("get console_small_font"); } - else if (argv[0] == "test_unfinished_tracks" && invalidArguments(&invalidArgs, int_valid[0])) - { - gConfigGeneral.test_unfinished_tracks = (int_val[0] != 0); - config_save_default(); - console.Execute("get test_unfinished_tracks"); - } - else if (argv[0] == "no_test_crashes" && invalidArguments(&invalidArgs, int_valid[0])) - { - gConfigGeneral.no_test_crashes = (int_val[0] != 0); - config_save_default(); - console.Execute("get no_test_crashes"); - } else if (argv[0] == "location" && invalidArguments(&invalidArgs, int_valid[0] && int_valid[1])) { rct_window* w = window_get_main(); @@ -1673,8 +1653,6 @@ static constexpr const utf8* console_variable_table[] = { "climate", "game_speed", "console_small_font", - "test_unfinished_tracks", - "no_test_crashes", "location", "window_scale", "window_limit", diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 838aa3f577..f139ce0d4c 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -2741,8 +2741,6 @@ enum STR_LOCALE_DECIMAL_POINT = 5152, STR_EDIT_THEMES_BUTTON = 5153, STR_HARDWARE_DISPLAY = 5154, // Unused - STR_TEST_UNFINISHED_TRACKS = 5155, - STR_TEST_UNFINISHED_TRACKS_TIP = 5156, STR_CHEAT_UNLOCK_PRICES = 5157, STR_QUIT_TO_MENU = 5158, STR_EXIT_OPENRCT2 = 5159, From 5f1f428bce5f4b57c4f710c8931848409ef18095 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 May 2019 17:41:29 +0100 Subject: [PATCH 413/506] Add and use Ride::SupportsStatus --- src/openrct2-ui/windows/Ride.cpp | 183 ++++++++++++++++------------- src/openrct2/ride/Ride.cpp | 17 +++ src/openrct2/ride/Ride.h | 1 + src/openrct2/ride/Vehicle.cpp | 8 +- src/openrct2/ride/Vehicle.h | 1 + src/openrct2/ride/VehiclePaint.cpp | 11 +- 6 files changed, 130 insertions(+), 91 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 61ef2f47a3..673d9cc3b8 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2062,12 +2062,30 @@ static void window_ride_main_mouseup(rct_window* w, rct_widgetindex widgetIndex) */ static void window_ride_main_resize(rct_window* w) { - const int32_t offset = gCheatsAllowArbitraryRideTypeChanges ? 15 : 0; - w->flags |= WF_RESIZABLE; - int32_t minHeight = 180 + offset; + int32_t minHeight = 180; if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE) - minHeight = 200 + offset + RCT1_LIGHT_OFFSET - - (ride_type_has_flag(get_ride(w->number)->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 * 2 : 0); + { + minHeight += 20 + RCT1_LIGHT_OFFSET; + + auto ride = get_ride(w->number); + if (ride != nullptr) + { + if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) + { + minHeight += 14; + } + if (ride->SupportsStatus(RIDE_STATUS_TESTING)) + { + minHeight += 14; + } + } + } + if (gCheatsAllowArbitraryRideTypeChanges) + { + minHeight += 15; + } + + w->flags |= WF_RESIZABLE; window_set_resize(w, 316, minHeight, 500, 450); window_ride_init_viewport(w); } @@ -2136,60 +2154,68 @@ static void window_ride_show_view_dropdown(rct_window* w, rct_widget* widget) */ static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) { - Ride* ride; - int32_t numItems, highlightedIndex = 0; - - ride = get_ride(w->number); - - numItems = 0; - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_CLOSE_RIDE; - numItems++; - - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) + auto ride = get_ride(w->number); + auto numItems = 0; + if (ride->SupportsStatus(RIDE_STATUS_CLOSED)) + { + gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[numItems] = STR_CLOSE_RIDE; + numItems++; + } + if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) { gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; gDropdownItemsArgs[numItems] = STR_SIMULATE_RIDE; numItems++; - + } + if (ride->SupportsStatus(RIDE_STATUS_TESTING)) + { gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; gDropdownItemsArgs[numItems] = STR_TEST_RIDE; numItems++; } - - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_OPEN_RIDE; - numItems++; + if (ride->SupportsStatus(RIDE_STATUS_OPEN)) + { + gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[numItems] = STR_OPEN_RIDE; + numItems++; + } window_dropdown_show_text( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[1], 0, numItems); auto checkedIndex = -1; + auto highlightedIndex = -1; switch (ride->status) { case RIDE_STATUS_CLOSED: checkedIndex = 0; highlightedIndex = 0; - if ((ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - || (ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE)) - break; - - highlightedIndex = 3; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + && !(ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE)) + { + highlightedIndex = 3; + if (ride->SupportsStatus(RIDE_STATUS_TESTING) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + { highlightedIndex = 2; + } + } break; case RIDE_STATUS_SIMULATING: checkedIndex = 1; highlightedIndex = 2; if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + { highlightedIndex = 0; + } break; case RIDE_STATUS_TESTING: checkedIndex = 2; highlightedIndex = 3; if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + { highlightedIndex = 3; + } break; case RIDE_STATUS_OPEN: checkedIndex = 3; @@ -2197,19 +2223,13 @@ static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) break; } - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) - { - // Open item is now index 1 - if (checkedIndex == 3) - checkedIndex = 1; - if (highlightedIndex == 3) - highlightedIndex = 1; - } + // "Open" index can differ, set to last item index + if (checkedIndex == 3) + checkedIndex = numItems - 1; + if (highlightedIndex == 3) + highlightedIndex = numItems - 1; - if (checkedIndex != -1) - { - dropdown_set_checked(checkedIndex, true); - } + dropdown_set_checked(checkedIndex, true); gDropdownDefaultIndex = highlightedIndex; } @@ -2399,23 +2419,25 @@ static void window_ride_main_mousedown(rct_window* w, rct_widgetindex widgetInde */ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) { - Ride* ride; - int32_t status = 0; - switch (widgetIndex) { case WIDX_VIEW_DROPDOWN: if (dropdownIndex == -1) { - dropdownIndex = w->ride.view; - ride = get_ride(w->number); - dropdownIndex++; - if (dropdownIndex != 0 && dropdownIndex <= ride->num_vehicles - && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) - dropdownIndex = ride->num_vehicles + 1; - - if (dropdownIndex >= gDropdownNumItems) - dropdownIndex = 0; + dropdownIndex = w->ride.view + 1; + auto ride = get_ride(w->number); + if (ride != nullptr) + { + if (dropdownIndex != 0 && dropdownIndex <= ride->num_vehicles + && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) + { + dropdownIndex = ride->num_vehicles + 1; + } + if (dropdownIndex >= gDropdownNumItems) + { + dropdownIndex = 0; + } + } } w->ride.view = dropdownIndex; @@ -2423,30 +2445,34 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex window_invalidate(w); break; case WIDX_OPEN: - if (dropdownIndex == -1) - dropdownIndex = gDropdownHighlightedIndex; - - ride = get_ride(w->number); - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) && dropdownIndex != 0) - dropdownIndex += 2; - - switch (dropdownIndex) + { + auto ride = get_ride(w->number); + if (ride != nullptr) { - case 0: - status = RIDE_STATUS_CLOSED; - break; - case 1: - status = RIDE_STATUS_SIMULATING; - break; - case 2: - status = RIDE_STATUS_TESTING; - break; - case 3: - status = RIDE_STATUS_OPEN; - break; + if (dropdownIndex == -1) + { + dropdownIndex = gDropdownHighlightedIndex; + } + auto status = RIDE_STATUS_CLOSED; + switch (dropdownIndex) + { + case 0: + status = RIDE_STATUS_CLOSED; + break; + case 1: + status = RIDE_STATUS_SIMULATING; + break; + case 2: + status = RIDE_STATUS_TESTING; + break; + case 3: + status = RIDE_STATUS_OPEN; + break; + } + ride_set_status(ride, status); } - ride_set_status(ride, status); break; + } case WIDX_RIDE_TYPE_DROPDOWN: if (dropdownIndex != -1 && dropdownIndex < RIDE_TYPE_COUNT) { @@ -2602,10 +2628,9 @@ static void window_ride_main_invalidate(rct_window* w) { window_ride_main_widgets[WIDX_OPEN].type = WWT_EMPTY; window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN; - window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type - = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN); - window_ride_main_widgets[WIDX_TEST_LIGHT].type - = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN); + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type = ride->SupportsStatus(RIDE_STATUS_SIMULATING) ? WWT_IMGBTN + : WWT_EMPTY; + window_ride_main_widgets[WIDX_TEST_LIGHT].type = ride->SupportsStatus(RIDE_STATUS_TESTING) ? WWT_IMGBTN : WWT_EMPTY; window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN; height = 62; @@ -2624,10 +2649,6 @@ static void window_ride_main_invalidate(rct_window* w) window_ride_main_widgets[WIDX_OPEN_LIGHT].top = height; window_ride_main_widgets[WIDX_OPEN_LIGHT].bottom = height + 13; height += 14 - 24 + RCT1_LIGHT_OFFSET; - - w->min_height = 200 + RCT1_LIGHT_OFFSET - (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 : 0); - if (w->height < w->min_height) - window_event_resize_call(w); } else { diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 4763cc3198..a73f5f439b 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -973,6 +973,23 @@ bool Ride::CanHaveMultipleCircuits() const return true; } +bool Ride::SupportsStatus(int32_t s) const +{ + switch (s) + { + case RIDE_STATUS_CLOSED: + case RIDE_STATUS_OPEN: + return true; + case RIDE_STATUS_SIMULATING: + return ( + !ride_type_has_flag(type, RIDE_TYPE_FLAG_NO_TEST_MODE) && ride_type_has_flag(type, RIDE_TYPE_FLAG_HAS_TRACK)); + case RIDE_STATUS_TESTING: + return !ride_type_has_flag(type, RIDE_TYPE_FLAG_NO_TEST_MODE); + default: + return false; + } +} + #pragma region Initialisation functions /** diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 4b122ba6ad..ce2826af24 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -382,6 +382,7 @@ public: bool IsPoweredLaunched() const; bool IsBlockSectioned() const; bool CanHaveMultipleCircuits() const; + bool SupportsStatus(int32_t s) const; void StopGuestsQueuing(); diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 678d4fcfd4..6f6dc23a38 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2285,7 +2285,7 @@ static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle) num_seats_on_train &= 0x7F; - if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) + if (ride->SupportsStatus(RIDE_STATUS_TESTING)) { if (vehicle->time_waiting < 20) { @@ -10048,3 +10048,9 @@ const rct_vehicle* rct_vehicle::GetCar(size_t carIndex) const } return car; } + +bool rct_vehicle::IsGhost() const +{ + auto r = get_ride(ride); + return r != nullptr && r->status == RIDE_STATUS_SIMULATING; +} diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 76635f76fa..ce41e0b116 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -235,6 +235,7 @@ struct rct_vehicle : rct_sprite_common const rct_vehicle* GetHead() const; const rct_vehicle* GetCar(size_t carIndex) const; void Invalidate(); + bool IsGhost() const; }; struct train_ref diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index e7d40507d4..c4f37d73f8 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -899,13 +899,6 @@ static void vehicle_sprite_paint( } vehicle_boundbox bb = VehicleBoundboxes[vehicleEntry->draw_order][ecx]; - bool isGhost = false; - auto ride = get_ride(vehicle->ride); - if (ride != nullptr && ride->status == RIDE_STATUS_SIMULATING) - { - isGhost = true; - } - if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) { baseImage_id += (vehicle->spin_sprite / 8) & 31; @@ -917,7 +910,7 @@ static void vehicle_sprite_paint( int32_t image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | IMAGE_TYPE_REMAP_2_PLUS; - if (isGhost) + if (vehicle->IsGhost()) { image_id &= 0x7FFFF; image_id |= CONSTRUCTION_MARKER; @@ -944,7 +937,7 @@ static void vehicle_sprite_paint( image_id += (vehicleEntry->no_vehicle_images * vehicle->animation_frame); } - if (isGhost) + if (vehicle->IsGhost()) { image_id &= 0x7FFFF; image_id |= CONSTRUCTION_MARKER; From 5c8aa743f614946ee4e3cbc1cfa4fe4890bddc4a Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 May 2019 17:55:53 +0100 Subject: [PATCH 414/506] Implement ghost drawing for special vehicles --- src/openrct2/ride/coaster/VirginiaReel.cpp | 6 +- src/openrct2/ride/gentle/ObservationTower.cpp | 7 ++- src/openrct2/ride/thrill/LaunchedFreefall.cpp | 63 ++++++++++--------- src/openrct2/ride/thrill/RotoDrop.cpp | 57 ++++++++++------- src/openrct2/ride/water/RiverRapids.cpp | 7 ++- src/openrct2/ride/water/SubmarineRide.cpp | 12 ++-- 6 files changed, 89 insertions(+), 63 deletions(-) diff --git a/src/openrct2/ride/coaster/VirginiaReel.cpp b/src/openrct2/ride/coaster/VirginiaReel.cpp index 3336da22c3..336a887593 100644 --- a/src/openrct2/ride/coaster/VirginiaReel.cpp +++ b/src/openrct2/ride/coaster/VirginiaReel.cpp @@ -196,10 +196,14 @@ void vehicle_visual_virginia_reel( const vehicle_boundbox* bb = &_virginiaReelBoundbox[j]; image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + if (vehicle->IsGhost()) + { + image_id = (image_id & 0x7FFFF) | CONSTRUCTION_MARKER; + } sub_98197C( session, image_id, 0, 0, bb->length_x, bb->length_y, bb->length_z, z, bb->offset_x, bb->offset_y, bb->offset_z + z); - if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0) + if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0 && !vehicle->IsGhost()) { uint8_t riding_peep_sprites[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; for (int32_t i = 0; i < vehicle->num_peeps; i++) diff --git a/src/openrct2/ride/gentle/ObservationTower.cpp b/src/openrct2/ride/gentle/ObservationTower.cpp index 0a4bcab880..14ef1225a5 100644 --- a/src/openrct2/ride/gentle/ObservationTower.cpp +++ b/src/openrct2/ride/gentle/ObservationTower.cpp @@ -54,8 +54,11 @@ void vehicle_visual_observation_tower( baseImage_id = (vehicle->animation_frame * 2) + vehicleEntry->base_image_id + 8; } - image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) - | IMAGE_TYPE_REMAP_2_PLUS; + image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_3(vehicle->colours.body_colour, vehicle->colours.trim_colour << 24); + if (vehicle->IsGhost()) + { + image_id = (image_id & 0x7FFFF) | CONSTRUCTION_MARKER; + } paint_struct* ps = sub_98197C(session, image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1); if (ps != nullptr) { diff --git a/src/openrct2/ride/thrill/LaunchedFreefall.cpp b/src/openrct2/ride/thrill/LaunchedFreefall.cpp index 39e9aa980e..27cdffbc9f 100644 --- a/src/openrct2/ride/thrill/LaunchedFreefall.cpp +++ b/src/openrct2/ride/thrill/LaunchedFreefall.cpp @@ -35,48 +35,49 @@ void vehicle_visual_launched_freefall( paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const rct_vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry) { - int32_t image_id; - int32_t baseImage_id = vehicleEntry->base_image_id + ((vehicle->restraints_position / 64) * 2); + auto imageFlags = SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + if (vehicle->IsGhost()) + { + imageFlags = CONSTRUCTION_MARKER; + } // Draw back: - image_id = (baseImage_id + 2) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + int32_t baseImage_id = vehicleEntry->base_image_id + ((vehicle->restraints_position / 64) * 2); + auto image_id = (baseImage_id + 2) | imageFlags; sub_98197C(session, image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1); // Draw front: - image_id = (baseImage_id + 1) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + image_id = (baseImage_id + 1) | imageFlags; sub_98197C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); // Draw peeps: - if (session->DPI.zoom_level < 2) + if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0 && !vehicle->IsGhost()) { - if (vehicle->num_peeps > 0) + baseImage_id = vehicleEntry->base_image_id + 9; + if ((vehicle->restraints_position / 64) == 3) { - baseImage_id = vehicleEntry->base_image_id + 9; - if ((vehicle->restraints_position / 64) == 3) - { - baseImage_id += 2; // Draw peeps sitting without transparent area between them for restraints - } - image_id = (baseImage_id + ((((imageDirection / 8) + 0) & 3) * 3)) - | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[0], vehicle->peep_tshirt_colours[1]); + baseImage_id += 2; // Draw peeps sitting without transparent area between them for restraints + } + image_id = (baseImage_id + ((((imageDirection / 8) + 0) & 3) * 3)) + | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[0], vehicle->peep_tshirt_colours[1]); + sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); + if (vehicle->num_peeps > 2) + { + image_id = (baseImage_id + ((((imageDirection / 8) + 1) & 3) * 3)) + | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[2], vehicle->peep_tshirt_colours[3]); + sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); + } + if (vehicle->num_peeps > 4) + { + image_id = (baseImage_id + ((((imageDirection / 8) + 2) & 3) * 3)) + | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[4], vehicle->peep_tshirt_colours[5]); + sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); + } + if (vehicle->num_peeps > 6) + { + image_id = (baseImage_id + ((((imageDirection / 8) + 3) & 3) * 3)) + | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[6], vehicle->peep_tshirt_colours[7]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); - if (vehicle->num_peeps > 2) - { - image_id = (baseImage_id + ((((imageDirection / 8) + 1) & 3) * 3)) - | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[2], vehicle->peep_tshirt_colours[3]); - sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); - } - if (vehicle->num_peeps > 4) - { - image_id = (baseImage_id + ((((imageDirection / 8) + 2) & 3) * 3)) - | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[4], vehicle->peep_tshirt_colours[5]); - sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); - } - if (vehicle->num_peeps > 6) - { - image_id = (baseImage_id + ((((imageDirection / 8) + 3) & 3) * 3)) - | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[6], vehicle->peep_tshirt_colours[7]); - sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); - } } } diff --git a/src/openrct2/ride/thrill/RotoDrop.cpp b/src/openrct2/ride/thrill/RotoDrop.cpp index 2c07534575..bebfc4fb1e 100644 --- a/src/openrct2/ride/thrill/RotoDrop.cpp +++ b/src/openrct2/ride/thrill/RotoDrop.cpp @@ -35,6 +35,12 @@ void vehicle_visual_roto_drop( paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const rct_vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry) { + auto imageFlags = SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + if (vehicle->IsGhost()) + { + imageFlags = CONSTRUCTION_MARKER; + } + int32_t image_id; int32_t baseImage_id = (vehicleEntry->base_image_id + 4) + ((vehicle->animation_frame / 4) & 0x3); if (vehicle->restraints_position >= 64) @@ -44,39 +50,42 @@ void vehicle_visual_roto_drop( } // Draw back: - image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + image_id = baseImage_id | imageFlags; sub_98197C(session, image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1); // Draw front: - image_id = (baseImage_id + 4) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + image_id = (baseImage_id + 4) | imageFlags; sub_98197C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); - uint8_t riding_peep_sprites[64]; - std::fill_n(riding_peep_sprites, sizeof(riding_peep_sprites), 0xFF); - for (int32_t i = 0; i < vehicle->num_peeps; i++) + if (vehicle->num_peeps > 0 && !vehicle->IsGhost()) { - uint8_t cl = (i & 3) * 16; - cl += (i & 0xFC); - cl += vehicle->animation_frame / 4; - cl += (imageDirection / 8) * 16; - cl &= 0x3F; - riding_peep_sprites[cl] = vehicle->peep_tshirt_colours[i]; - } - - // Draw riding peep sprites in back to front order: - for (int32_t j = 0; j <= 48; j++) - { - int32_t i = (j % 2) ? (48 - (j / 2)) : (j / 2); - if (riding_peep_sprites[i] != 0xFF) + uint8_t riding_peep_sprites[64]; + std::fill_n(riding_peep_sprites, sizeof(riding_peep_sprites), 0xFF); + for (int32_t i = 0; i < vehicle->num_peeps; i++) { - baseImage_id = vehicleEntry->base_image_id + 20 + i; - if (vehicle->restraints_position >= 64) + uint8_t cl = (i & 3) * 16; + cl += (i & 0xFC); + cl += vehicle->animation_frame / 4; + cl += (imageDirection / 8) * 16; + cl &= 0x3F; + riding_peep_sprites[cl] = vehicle->peep_tshirt_colours[i]; + } + + // Draw riding peep sprites in back to front order: + for (int32_t j = 0; j <= 48; j++) + { + int32_t i = (j % 2) ? (48 - (j / 2)) : (j / 2); + if (riding_peep_sprites[i] != 0xFF) { - baseImage_id += 64; - baseImage_id += vehicle->restraints_position / 64; + baseImage_id = vehicleEntry->base_image_id + 20 + i; + if (vehicle->restraints_position >= 64) + { + baseImage_id += 64; + baseImage_id += vehicle->restraints_position / 64; + } + image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_1(riding_peep_sprites[i]); + sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } - image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_1(riding_peep_sprites[i]); - sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } } diff --git a/src/openrct2/ride/water/RiverRapids.cpp b/src/openrct2/ride/water/RiverRapids.cpp index b6886dc5bf..ccb28bd6ff 100644 --- a/src/openrct2/ride/water/RiverRapids.cpp +++ b/src/openrct2/ride/water/RiverRapids.cpp @@ -223,10 +223,15 @@ void vehicle_visual_river_rapids( const vehicle_boundbox* bb = &_riverRapidsBoundbox[j]; image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour); + if (vehicle->IsGhost()) + { + image_id &= 0x7FFFF; + image_id |= CONSTRUCTION_MARKER; + } sub_98197C( session, image_id, 0, 0, bb->length_x, bb->length_y, bb->length_z, z, bb->offset_x, bb->offset_y, bb->offset_z + z); - if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0) + if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0 && !vehicle->IsGhost()) { // Draw peeps: (this particular vehicle doesn't sort them back to front like others so the back ones sometimes clip, but // that's how the original does it...) diff --git a/src/openrct2/ride/water/SubmarineRide.cpp b/src/openrct2/ride/water/SubmarineRide.cpp index 22080563e7..576f5ab0d2 100644 --- a/src/openrct2/ride/water/SubmarineRide.cpp +++ b/src/openrct2/ride/water/SubmarineRide.cpp @@ -24,6 +24,12 @@ void vehicle_visual_submarine( paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const rct_vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry) { + auto imageFlags = SPRITE_ID_PALETTE_COLOUR_3(vehicle->colours.body_colour, vehicle->colours.trim_colour); + if (vehicle->IsGhost()) + { + imageFlags = CONSTRUCTION_MARKER; + } + int32_t baseImage_id = imageDirection; int32_t image_id; if (vehicle->restraints_position >= 64) @@ -53,8 +59,7 @@ void vehicle_visual_submarine( vehicle_boundbox bb = VehicleBoundboxes[vehicleEntry->draw_order][imageDirection / 2]; - image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) - | IMAGE_TYPE_REMAP_2_PLUS; + image_id = baseImage_id | imageFlags; paint_struct* ps = sub_98197C( session, image_id, 0, 0, bb.length_x, bb.length_y, bb.length_z, z, bb.offset_x, bb.offset_y, bb.offset_z + z); if (ps != nullptr) @@ -62,8 +67,7 @@ void vehicle_visual_submarine( ps->tertiary_colour = vehicle->colours_extended; } - image_id = (baseImage_id + 1) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) - | IMAGE_TYPE_REMAP_2_PLUS; + image_id = (baseImage_id + 1) | imageFlags; ps = sub_98197C(session, image_id, 0, 0, bb.length_x, bb.length_y, 2, z, bb.offset_x, bb.offset_y, bb.offset_z + z - 10); if (ps != nullptr) { From 94caa4665433d3a2bad30be4ea546f85e0db24fe Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 8 May 2019 18:01:24 +0100 Subject: [PATCH 415/506] Allow modification of ride entrance during simulation --- src/openrct2/ride/Ride.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index a73f5f439b..a4009bb45a 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5430,7 +5430,7 @@ int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying) if (!ride_mode_check_valid_station_numbers(ride)) return 0; - if (!ride_check_for_entrance_exit(ride->id)) + if (status != RIDE_STATUS_SIMULATING && !ride_check_for_entrance_exit(ride->id)) { loc_6B51C0(ride); return 0; From f0f09c7f6b3178e192659d6d722b3e5369039817 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 8 May 2019 21:56:38 +0200 Subject: [PATCH 416/506] Fix tests --- test/testpaint/Compat.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index 393c02db0a..d6fe6632ef 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -435,3 +435,9 @@ StationObject* ride_get_station_object(const Ride* ride) { return nullptr; } + +bool rct_vehicle::IsGhost() const +{ + auto r = get_ride(ride); + return r != nullptr && r->status == RIDE_STATUS_SIMULATING; +} From 5fa0c18455f7a95aae36f0c64031b1ca658c9e72 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 May 2019 12:32:59 +0100 Subject: [PATCH 417/506] Do not provide test results for simulate --- src/openrct2/ride/Vehicle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 6f6dc23a38..ca66f928ab 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3254,7 +3254,7 @@ static void vehicle_update_departing(rct_vehicle* vehicle) vehicle_update_test_finish(vehicle); } } - else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS)) + else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS) && !vehicle->IsGhost()) { vehicle_test_reset(vehicle); } @@ -4238,7 +4238,7 @@ static void vehicle_update_travelling_cable_lift(rct_vehicle* vehicle) vehicle_update_test_finish(vehicle); } } - else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS)) + else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS) && !vehicle->IsGhost()) { vehicle_test_reset(vehicle); } From 62ff1e753414d501b81b43aa47d87d63167d96eb Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 12 May 2019 12:46:22 +0100 Subject: [PATCH 418/506] Prevent breakdown during simulation --- data/language/en-GB.txt | 1 + src/openrct2/actions/RideSetStatus.hpp | 10 +++++++++- src/openrct2/localisation/StringIds.h | 1 + src/openrct2/ride/Ride.cpp | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index ebd2c98aad..2afccea9a9 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3773,6 +3773,7 @@ STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} STR_6323 :Simulating STR_6324 :Simulate STR_6325 :{SMALLFONT}{BLACK}Simulate ride/attraction +STR_6326 :Can't simulate {POP16}{POP16}{POP16}{STRINGID}... ############# # Scenarios # diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index 3e5adc6eb8..b3a94a36c3 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -25,6 +25,7 @@ static rct_string_id _StatusErrorTitles[] = { STR_CANT_CLOSE, STR_CANT_OPEN, STR_CANT_TEST, + STR_CANT_SIMULATE, }; DEFINE_GAME_ACTION(RideSetStatusAction, GAME_COMMAND_SET_RIDE_STATUS, GameActionResult) @@ -73,7 +74,14 @@ public: if (_status != ride->status) { - if (_status == RIDE_STATUS_TESTING || _status == RIDE_STATUS_SIMULATING) + if (_status == RIDE_STATUS_SIMULATING && (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) + { + // Simulating will force clear the track, so make sure player can't cheat around a break down + res->Error = GA_ERROR::DISALLOWED; + res->ErrorMessage = STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING; + return res; + } + else if (_status == RIDE_STATUS_TESTING || _status == RIDE_STATUS_SIMULATING) { if (!ride_is_valid_for_test(ride, _status, 0)) { diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index f139ce0d4c..d6e2388c42 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3960,6 +3960,7 @@ enum STR_SIMULATING = 6323, STR_SIMULATE_RIDE = 6324, STR_SIMULATE_RIDE_TIP = 6325, + STR_CANT_SIMULATE = 6326, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index a4009bb45a..140cb4dfe4 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -2483,7 +2483,7 @@ static void ride_breakdown_update(Ride* ride) if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) return; - if (ride->status == RIDE_STATUS_CLOSED) + if (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_SIMULATING) return; if (!ride->CanBreakDown()) From 5289113c955b5863cc16dd89126cec003653c28d Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 23 May 2019 18:29:29 +0100 Subject: [PATCH 419/506] Add simulate button to ride construction window --- src/openrct2-ui/windows/RideConstruction.cpp | 39 ++++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index e5ed3c16f2..b70f403394 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -79,6 +79,7 @@ enum { WIDX_SEAT_ROTATION_ANGLE_SPINNER, WIDX_SEAT_ROTATION_ANGLE_SPINNER_UP, WIDX_SEAT_ROTATION_ANGLE_SPINNER_DOWN, + WIDX_SIMULATE, }; validate_global_widx(WC_RIDE_CONSTRUCTION, WIDX_CONSTRUCT); @@ -113,8 +114,8 @@ static rct_widget window_ride_construction_widgets[] = { { WWT_IMGBTN, 1, 3, 162, 164, 333, 0xFFFFFFFF, STR_RIDE_CONSTRUCTION_CONSTRUCT_SELECTED_SECTION_TIP }, { WWT_FLATBTN, 1, 60, 105, 338, 361, SPR_DEMOLISH_CURRENT_SECTION, STR_RIDE_CONSTRUCTION_REMOVE_HIGHLIGHTED_SECTION_TIP }, { WWT_FLATBTN, 1, 50, 71, 29, 52, SPR_RIDE_CONSTRUCTION_LEFT_CURVE_LARGE, STR_RIDE_CONSTRUCTION_LEFT_CURVE_LARGE_TIP }, - { WWT_FLATBTN, 1, 20, 43, 338, 361, SPR_PREVIOUS, STR_RIDE_CONSTRUCTION_MOVE_TO_PREVIOUS_SECTION_TIP }, - { WWT_FLATBTN, 1, 122, 145, 338, 361, SPR_NEXT, STR_RIDE_CONSTRUCTION_MOVE_TO_NEXT_SECTION_TIP }, + { WWT_FLATBTN, 1, 30, 53, 338, 361, SPR_PREVIOUS, STR_RIDE_CONSTRUCTION_MOVE_TO_PREVIOUS_SECTION_TIP }, + { WWT_FLATBTN, 1, 112, 135, 338, 361, SPR_NEXT, STR_RIDE_CONSTRUCTION_MOVE_TO_NEXT_SECTION_TIP }, { WWT_GROUPBOX, 0, 3, 162, 362, 389, 0xFFFFFFFF, STR_NONE }, { WWT_BUTTON, 1, 9, 78, 372, 383, STR_RIDE_CONSTRUCTION_ENTRANCE, STR_RIDE_CONSTRUCTION_ENTRANCE_TIP }, { WWT_BUTTON, 1, 87, 156, 372, 383, STR_RIDE_CONSTRUCTION_EXIT, STR_RIDE_CONSTRUCTION_EXIT_TIP }, @@ -124,6 +125,7 @@ static rct_widget window_ride_construction_widgets[] = { { WWT_FLATBTN, 1, 123, 146, 132, 155, SPR_RIDE_CONSTRUCTION_O_SHAPED_TRACK, STR_RIDE_CONSTRUCTION_O_SHAPED_ENCLOSED_TRACK_TIP }, { WWT_GROUPBOX, 0, 96, 162, 120, 160, STR_RIDE_CONSTRUCTION_SEAT_ROT, STR_NONE }, SPINNER_WIDGETS (1, 101, 158, 138, 149, 0, STR_RIDE_CONSTRUCTION_SELECT_SEAT_ROTATION_ANGLE_TIP), + { WWT_FLATBTN, 1, 139, 162, 338, 361, SPR_TESTING, STR_SIMULATE_RIDE_TIP }, { WIDGETS_END } }; @@ -540,8 +542,8 @@ rct_window* window_ride_construction_open() | (1ULL << WIDX_SLOPE_DOWN) | (1ULL << WIDX_LEVEL) | (1ULL << WIDX_SLOPE_UP) | (1ULL << WIDX_SLOPE_UP_STEEP) | (1ULL << WIDX_CHAIN_LIFT) | (1ULL << WIDX_BANK_LEFT) | (1ULL << WIDX_BANK_STRAIGHT) | (1ULL << WIDX_BANK_RIGHT) | (1ULL << WIDX_CONSTRUCT) | (1ULL << WIDX_DEMOLISH) | (1ULL << WIDX_LEFT_CURVE_LARGE) | (1ULL << WIDX_PREVIOUS_SECTION) - | (1ULL << WIDX_NEXT_SECTION) | (1ULL << WIDX_ENTRANCE) | (1ULL << WIDX_EXIT) | (1ULL << WIDX_RIGHT_CURVE_LARGE) - | (1ULL << WIDX_ROTATE) | (1ULL << WIDX_U_TRACK) | (1ULL << WIDX_O_TRACK) + | (1ULL << WIDX_NEXT_SECTION) | (1ULL << WIDX_SIMULATE) | (1ULL << WIDX_ENTRANCE) | (1ULL << WIDX_EXIT) + | (1ULL << WIDX_RIGHT_CURVE_LARGE) | (1ULL << WIDX_ROTATE) | (1ULL << WIDX_U_TRACK) | (1ULL << WIDX_O_TRACK) | (1ULL << WIDX_SEAT_ROTATION_ANGLE_SPINNER_UP) | (1ULL << WIDX_SEAT_ROTATION_ANGLE_SPINNER_DOWN); window_init_scroll_widgets(w); @@ -674,6 +676,16 @@ static void window_ride_construction_mouseup(rct_window* w, rct_widgetindex widg case WIDX_EXIT: window_ride_construction_exit_click(w); break; + case WIDX_SIMULATE: + { + auto ride = get_ride(_currentRideIndex); + if (ride != nullptr) + { + auto status = ride->status == RIDE_STATUS_SIMULATING ? RIDE_STATUS_CLOSED : RIDE_STATUS_SIMULATING; + ride_set_status(ride, status); + } + break; + } } } @@ -2252,6 +2264,25 @@ static void window_ride_construction_invalidate(rct_window* w) window_ride_construction_widgets[WIDX_SEAT_ROTATION_ANGLE_SPINNER].text = RideConstructionSeatAngleRotationStrings [_currentSeatRotationAngle]; + // Simulate button + auto& simulateWidget = w->widgets[WIDX_SIMULATE]; + simulateWidget.type = WWT_EMPTY; + if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) + { + if (ride->status == RIDE_STATUS_CLOSED) + { + simulateWidget.type = WWT_FLATBTN; + simulateWidget.image = SPR_CLOSED; + simulateWidget.tooltip = STR_SIMULATE_RIDE_TIP; + } + else if (ride->status == RIDE_STATUS_SIMULATING) + { + simulateWidget.type = WWT_FLATBTN; + simulateWidget.image = SPR_TESTING | (COLOUR_WHITE << 19 | COLOUR_WHITE << 24 | IMAGE_TYPE_REMAP); + simulateWidget.tooltip = STR_CLOSE_RIDE_TIP; + } + } + // Set window title arguments set_format_arg(4, rct_string_id, ride->name); set_format_arg(6, uint32_t, ride->name_arguments); From 5ef07300083f2f38bc9188d57b3d4ddb443648a8 Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 23 May 2019 18:41:17 +0100 Subject: [PATCH 420/506] Remove simulate from ride window --- src/openrct2-ui/windows/Ride.cpp | 181 ++++++++++++++++--------------- 1 file changed, 93 insertions(+), 88 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 673d9cc3b8..d8ffcad281 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2070,10 +2070,12 @@ static void window_ride_main_resize(rct_window* w) auto ride = get_ride(w->number); if (ride != nullptr) { +#ifdef __SIMULATE_IN_RIDE_WINDOW__ if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) { minHeight += 14; } +#endif if (ride->SupportsStatus(RIDE_STATUS_TESTING)) { minHeight += 14; @@ -2148,89 +2150,80 @@ static void window_ride_show_view_dropdown(rct_window* w, rct_widget* widget) dropdown_set_checked(w->ride.view, true); } -/** - * - * rct2: 0x006AF64C - */ -static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) +static uint8_t window_ride_get_next_default_status(const Ride* ride) { - auto ride = get_ride(w->number); - auto numItems = 0; - if (ride->SupportsStatus(RIDE_STATUS_CLOSED)) - { - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_CLOSE_RIDE; - numItems++; - } - if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) - { - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_SIMULATE_RIDE; - numItems++; - } - if (ride->SupportsStatus(RIDE_STATUS_TESTING)) - { - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_TEST_RIDE; - numItems++; - } - if (ride->SupportsStatus(RIDE_STATUS_OPEN)) - { - gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[numItems] = STR_OPEN_RIDE; - numItems++; - } - - window_dropdown_show_text( - w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[1], 0, numItems); - - auto checkedIndex = -1; - auto highlightedIndex = -1; switch (ride->status) { + default: case RIDE_STATUS_CLOSED: - checkedIndex = 0; - highlightedIndex = 0; - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - && !(ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE)) + if ((ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + || (ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE)) { - highlightedIndex = 3; - if (ride->SupportsStatus(RIDE_STATUS_TESTING) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) - { - highlightedIndex = 2; - } + return RIDE_STATUS_CLOSED; + } + else if (ride->SupportsStatus(RIDE_STATUS_TESTING) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + { + return RIDE_STATUS_TESTING; + } + else + { + return RIDE_STATUS_OPEN; } - break; case RIDE_STATUS_SIMULATING: - checkedIndex = 1; - highlightedIndex = 2; - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) - { - highlightedIndex = 0; - } - break; + return RIDE_STATUS_TESTING; case RIDE_STATUS_TESTING: - checkedIndex = 2; - highlightedIndex = 3; - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) - { - highlightedIndex = 3; - } - break; + return (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) ? RIDE_STATUS_OPEN : RIDE_STATUS_CLOSED; case RIDE_STATUS_OPEN: - checkedIndex = 3; - highlightedIndex = 0; - break; + return RIDE_STATUS_CLOSED; } +} - // "Open" index can differ, set to last item index - if (checkedIndex == 3) - checkedIndex = numItems - 1; - if (highlightedIndex == 3) - highlightedIndex = numItems - 1; +struct RideStatusDropdownInfo +{ + struct Ride* Ride{}; + uint8_t CurrentStatus{}; + uint8_t DefaultStatus{}; - dropdown_set_checked(checkedIndex, true); - gDropdownDefaultIndex = highlightedIndex; + int32_t NumItems{}; + int32_t CheckedIndex = -1; + int32_t DefaultIndex = -1; +}; + +static void window_ride_set_dropdown(RideStatusDropdownInfo& info, uint8_t status, rct_string_id text) +{ + if (info.Ride->SupportsStatus(status)) + { + auto index = info.NumItems; + gDropdownItemsFormat[index] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[index] = text; + if (info.CurrentStatus == status) + { + info.CheckedIndex = index; + } + if (info.DefaultStatus == status) + { + info.DefaultIndex = index; + } + info.NumItems++; + } +} + +static void window_ride_show_open_dropdown(rct_window* w, rct_widget* widget) +{ + RideStatusDropdownInfo info; + info.Ride = get_ride(w->number); + info.CurrentStatus = info.Ride->status; + info.DefaultStatus = window_ride_get_next_default_status(info.Ride); + window_ride_set_dropdown(info, RIDE_STATUS_CLOSED, STR_CLOSE_RIDE); +#ifdef __SIMULATE_IN_RIDE_WINDOW__ + window_ride_set_dropdown(info, RIDE_STATUS_SIMULATING, STR_SIMULATE_RIDE); +#endif + window_ride_set_dropdown(info, RIDE_STATUS_TESTING, STR_TEST_RIDE); + window_ride_set_dropdown(info, RIDE_STATUS_OPEN, STR_OPEN_RIDE); + window_dropdown_show_text( + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, w->colours[1], 0, info.NumItems); + dropdown_set_checked(info.CheckedIndex, true); + gDropdownDefaultIndex = info.DefaultIndex; } static void populate_ride_type_dropdown() @@ -2449,25 +2442,28 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex auto ride = get_ride(w->number); if (ride != nullptr) { - if (dropdownIndex == -1) + auto status = RIDE_STATUS_CLOSED; + if (dropdownIndex < 0) { dropdownIndex = gDropdownHighlightedIndex; } - auto status = RIDE_STATUS_CLOSED; - switch (dropdownIndex) + if (dropdownIndex < (int32_t)std::size(gDropdownItemsArgs)) { - case 0: - status = RIDE_STATUS_CLOSED; - break; - case 1: - status = RIDE_STATUS_SIMULATING; - break; - case 2: - status = RIDE_STATUS_TESTING; - break; - case 3: - status = RIDE_STATUS_OPEN; - break; + switch (gDropdownItemsArgs[dropdownIndex]) + { + case STR_CLOSE_RIDE: + status = RIDE_STATUS_CLOSED; + break; + case STR_SIMULATE_RIDE: + status = RIDE_STATUS_SIMULATING; + break; + case STR_TEST_RIDE: + status = RIDE_STATUS_TESTING; + break; + case STR_OPEN_RIDE: + status = RIDE_STATUS_OPEN; + break; + } } ride_set_status(ride, status); } @@ -2582,10 +2578,16 @@ static void window_ride_main_invalidate(rct_window* w) }; window_ride_main_widgets[WIDX_OPEN].image = spriteIds[ride->status]; +#ifdef __SIMULATE_IN_RIDE_WINDOW__ window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (ride->status == RIDE_STATUS_CLOSED) * 2 + widget_is_pressed(w, WIDX_CLOSE_LIGHT); window_ride_main_widgets[WIDX_SIMULATE_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + (ride->status == RIDE_STATUS_SIMULATING) * 2 + widget_is_pressed(w, WIDX_SIMULATE_LIGHT); +#else + window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + + (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_SIMULATING) * 2 + + widget_is_pressed(w, WIDX_CLOSE_LIGHT); +#endif window_ride_main_widgets[WIDX_TEST_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + (ride->status == RIDE_STATUS_TESTING) * 2 + widget_is_pressed(w, WIDX_TEST_LIGHT); window_ride_main_widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (ride->status == RIDE_STATUS_OPEN) * 2 @@ -2628,8 +2630,11 @@ static void window_ride_main_invalidate(rct_window* w) { window_ride_main_widgets[WIDX_OPEN].type = WWT_EMPTY; window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN; - window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type = ride->SupportsStatus(RIDE_STATUS_SIMULATING) ? WWT_IMGBTN - : WWT_EMPTY; + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type = WWT_EMPTY; +#ifdef __SIMULATE_IN_RIDE_WINDOW__ + if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].type = WWT_IMGBTN; +#endif window_ride_main_widgets[WIDX_TEST_LIGHT].type = ride->SupportsStatus(RIDE_STATUS_TESTING) ? WWT_IMGBTN : WWT_EMPTY; window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN; From 26185b9e72d2e1ec872c213767c2f4d4c2020236 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 25 May 2019 10:24:30 +0100 Subject: [PATCH 421/506] Change simulate to toggle button --- src/openrct2-ui/windows/RideConstruction.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index b70f403394..f192eeff08 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2269,17 +2269,14 @@ static void window_ride_construction_invalidate(rct_window* w) simulateWidget.type = WWT_EMPTY; if (ride->SupportsStatus(RIDE_STATUS_SIMULATING)) { - if (ride->status == RIDE_STATUS_CLOSED) + simulateWidget.type = WWT_FLATBTN; + if (ride->status == RIDE_STATUS_SIMULATING) { - simulateWidget.type = WWT_FLATBTN; - simulateWidget.image = SPR_CLOSED; - simulateWidget.tooltip = STR_SIMULATE_RIDE_TIP; + w->pressed_widgets |= (1ULL << WIDX_SIMULATE); } - else if (ride->status == RIDE_STATUS_SIMULATING) + else { - simulateWidget.type = WWT_FLATBTN; - simulateWidget.image = SPR_TESTING | (COLOUR_WHITE << 19 | COLOUR_WHITE << 24 | IMAGE_TYPE_REMAP); - simulateWidget.tooltip = STR_CLOSE_RIDE_TIP; + w->pressed_widgets &= ~(1ULL << WIDX_SIMULATE); } } From bab7711c5b20711f3c69f5f9929876c2bd81c6fc Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 25 May 2019 10:25:50 +0100 Subject: [PATCH 422/506] Add new simulate icon. --- resources/g2/icons/simulate.png | Bin 0 -> 811 bytes resources/g2/sprites.json | 5 +++++ src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2/sprites.h | 3 ++- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 resources/g2/icons/simulate.png diff --git a/resources/g2/icons/simulate.png b/resources/g2/icons/simulate.png new file mode 100644 index 0000000000000000000000000000000000000000..173bc128e1982746a96d09522dcde7ec42421da4 GIT binary patch literal 811 zcmaKq;fvFD7{{OKAcx117gaM1qZ}QCk-5GI7+BCab4PYmE{E}!L5C6JtkT1P5&EJ+ z#16U_bE-F#mps6Z)s>^i7pL)mhR9?x43iZEUY2v3 zmNyK&QmNGIj_(Ii)Ju}_WWr>D=RnHM=JTmyFAe zbA+j+ZH;mard1Kby3+Oaq*EOw?#4J0NlAGEE{R52G*Qu(jZl;U zkN{K+({bD+Nt>cvj%!I$r%>pd<_pI`VMsEm3{PaGG^bLcPAev(*__c3DqgPEmffxz zB!x6fX2lFA(>aaJ>w;dDs*dUedJvmYQj15;!A6MlkdlEYK)MW+jj;|P`cyvT^;oe6 zhC8++)RO3w#*!tGwiK?Z32j4;D_Xy9486)YtZ&2~8b)}ErD%m=3%pR0WlPf8!?a zMoy}#(`RMhs&$%v62+4N4{8oGWZYEKc9CwBd9NzB8-i2|L08V`X8i3CUnq!Y+ukSn2}h`LpjxUdbLg`5D2gcUWy zEYUSvY`R*zeRcl%chgqAb@AA;42PdRIx`JlE-id~{GHwx@q@X_{LI@Yf6{AjTG!`4 zoFARKv${gckMCwL|8V<#xIp}~d1KG!rQNr_efQQn`e^?*e;i%EXZ(3!^Q(V<86At@y_}=>Z jkB1Istatus]; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index f192eeff08..6c04a3c26b 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -125,7 +125,7 @@ static rct_widget window_ride_construction_widgets[] = { { WWT_FLATBTN, 1, 123, 146, 132, 155, SPR_RIDE_CONSTRUCTION_O_SHAPED_TRACK, STR_RIDE_CONSTRUCTION_O_SHAPED_ENCLOSED_TRACK_TIP }, { WWT_GROUPBOX, 0, 96, 162, 120, 160, STR_RIDE_CONSTRUCTION_SEAT_ROT, STR_NONE }, SPINNER_WIDGETS (1, 101, 158, 138, 149, 0, STR_RIDE_CONSTRUCTION_SELECT_SEAT_ROTATION_ANGLE_TIP), - { WWT_FLATBTN, 1, 139, 162, 338, 361, SPR_TESTING, STR_SIMULATE_RIDE_TIP }, + { WWT_FLATBTN, 1, 139, 162, 338, 361, SPR_G2_SIMULATE, STR_SIMULATE_RIDE_TIP }, { WIDGETS_END } }; diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index ee35b4c50c..8047b63c92 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -842,8 +842,9 @@ enum SPR_G2_TOOLBAR_MULTIPLAYER_PRESSED = SPR_G2_BEGIN + 123, SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 124, SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 125, + SPR_G2_SIMULATE = SPR_G2_BEGIN + 126, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 126, + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 127, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From d1f48fab53a7167942c6c4bd30f5bb47c12f9eff Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 25 May 2019 14:15:42 +0200 Subject: [PATCH 423/506] Add RCT1 traffic light sprites for ride simulate status. --- resources/g2/icons/rct1_simulate_off.png | Bin 0 -> 541 bytes .../g2/icons/rct1_simulate_off_pressed.png | Bin 0 -> 500 bytes resources/g2/icons/rct1_simulate_on.png | Bin 0 -> 574 bytes resources/g2/icons/rct1_simulate_on_pressed.png | Bin 0 -> 569 bytes resources/g2/sprites.json | 12 ++++++++++++ src/openrct2-ui/windows/Ride.cpp | 16 ++++++++++------ src/openrct2/sprites.h | 9 +++++++-- 7 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 resources/g2/icons/rct1_simulate_off.png create mode 100644 resources/g2/icons/rct1_simulate_off_pressed.png create mode 100644 resources/g2/icons/rct1_simulate_on.png create mode 100644 resources/g2/icons/rct1_simulate_on_pressed.png diff --git a/resources/g2/icons/rct1_simulate_off.png b/resources/g2/icons/rct1_simulate_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c7a7c402a6f21dcf2832f8cea39d1301b53225d4 GIT binary patch literal 541 zcmaKpv5V7i0EK@=Fy-!Qz$ir{RICsoLxvzhfu->7qirL#)_ zfI@Y>vbp#ZN6jBw?4?&W$b9vu9=3;Jnm-G2u3Ij7fGtgu(}{viqh6~-?Bp2je}q^8l`EP0aOK; z1Cbug_J6+Fzq?S9+up1T;M(^ucNTD^TDjiHkDnfVD1h^M_U5~LXCA%3eEPz<7uoOC z^@G2+#}(|;sc-k4{nyX7KQ>-+zgBV&AFRMvrOziX9)Gess2oYIuGK4VS8qN32cRz0 A3IG5A literal 0 HcmV?d00001 diff --git a/resources/g2/icons/rct1_simulate_off_pressed.png b/resources/g2/icons/rct1_simulate_off_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..0f5b7e05d16216427ea0862815ecd5b43d1593a0 GIT binary patch literal 500 zcmaKpv5V6H7{$Lkg&eJChkyYy!eu!BRv3>^ex?;r5Ndyn7x-syfr+AQ5I z0l;SMQT1Tex39f%W0l(W&mj?|6c7J|*wt}5n^}*rB z#5mr%b@d9~yFYxN%s+p5b5+_VF8VirKRMcp)@yezoYwg+`)NISdhe(Vr(N>J-~0aC P>+foNjq3Ts literal 0 HcmV?d00001 diff --git a/resources/g2/icons/rct1_simulate_on.png b/resources/g2/icons/rct1_simulate_on.png new file mode 100644 index 0000000000000000000000000000000000000000..6e4318614276596b26f9481a79cf30c32569876a GIT binary patch literal 574 zcmaKqv5V7S0L8yMhmk?Ri(Wr>>cS#7UY?EtSbD#GXJ>1H|4|mhFp45smVvM&%c80(hGE#Y<9VGR z7z~H;bV`wcp#fi76~)Z%Zcf`H>n3eC_@*ayeYGE&qp`~ph(NC@rK~RGEE#uHs%@~o zE%ZHQ*sD*5?ko;C6i5Wn7+^u9sUW_Yj+&WiA5A7?GL@3Kl_UWM01tqKAWAx|qo{@B zE={+2zE`V7y8hR365mIu48~+hK1WM9rx1cp$ri0PSff=s=t8$Ib%wQE9wj-9hD1ru ziwdjM`MM)H9i zPzB&NLN(KD7lnPIHe%~z(Vb}B*cwc|$vm1RDf#ZvVydObl`;f3e|>+rfX!mz)=nyV zaa_6xE~l2i?US#x^?CgKv{C(B`El)V|M1W8ho|q#U$4CR`8$A*$hTjL*z5Zz)#V%T dH2QQkH@bdO-8ehy-D{k`ptw~oeB6BS-ka|?;5HUlMpc#5lHAsho9fZqJjt(7S?;r5Ndyn7z-a)-qSzo=j z3IJHI-Yf4cdgIJ1=N7s7`u7-sC9i&ecYA^VQK3{S;W$Rq6vr`=Bq)lk>$+__zTXYQ zL6W4?DUJb(1T3>A2>E8SsP1EiN!l&e^Tl4EM6o#%goepe1 z^5vv&OcHmNh7}lyC{QV2agZlNftee6`Dp}a6D*sG+1$#qumk`LfCxcyE~mk;g&;0T zc38IGXbd&&uj6Dv0OR=*RlwLHDIyga~h#>tnxk8pHy;nI`r_{!rKH>sCL@2)manS&PoLA?CxQ~&L)Bk=Rr^7n+f X{^sGPWgge&X9uWm*UInjK6v^ML3rm| literal 0 HcmV?d00001 diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index dc71034051..df0cf72aba 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -435,6 +435,18 @@ "x_offset": 2, "y_offset": 2 }, + { + "path": "icons/rct1_simulate_off.png" + }, + { + "path": "icons/rct1_simulate_off_pressed.png" + }, + { + "path": "icons/rct1_simulate_on.png" + }, + { + "path": "icons/rct1_simulate_on_pressed.png" + }, { "path": "font/latin/ae-uc-small.png", "y_offset": 0, diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 23125671d2..79dbf87ed9 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2581,15 +2581,19 @@ static void window_ride_main_invalidate(rct_window* w) #ifdef __SIMULATE_IN_RIDE_WINDOW__ window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (ride->status == RIDE_STATUS_CLOSED) * 2 + widget_is_pressed(w, WIDX_CLOSE_LIGHT); - window_ride_main_widgets[WIDX_SIMULATE_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + window_ride_main_widgets[WIDX_SIMULATE_LIGHT].image = SPR_G2_RCT1_SIMULATE_BUTTON_0 + (ride->status == RIDE_STATUS_SIMULATING) * 2 + widget_is_pressed(w, WIDX_SIMULATE_LIGHT); -#else - window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 - + (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_SIMULATING) * 2 - + widget_is_pressed(w, WIDX_CLOSE_LIGHT); -#endif window_ride_main_widgets[WIDX_TEST_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + (ride->status == RIDE_STATUS_TESTING) * 2 + widget_is_pressed(w, WIDX_TEST_LIGHT); +#else + window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (ride->status == RIDE_STATUS_CLOSED) * 2 + + widget_is_pressed(w, WIDX_CLOSE_LIGHT); + + auto baseSprite = ride->status == RIDE_STATUS_SIMULATING ? SPR_G2_RCT1_SIMULATE_BUTTON_0 : SPR_G2_RCT1_TEST_BUTTON_0; + window_ride_main_widgets[WIDX_TEST_LIGHT].image = baseSprite + + (ride->status == RIDE_STATUS_TESTING || ride->status == RIDE_STATUS_SIMULATING) * 2 + + widget_is_pressed(w, WIDX_TEST_LIGHT); +#endif window_ride_main_widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (ride->status == RIDE_STATUS_OPEN) * 2 + widget_is_pressed(w, WIDX_OPEN_LIGHT); diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 8047b63c92..cc108d0dc4 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -842,9 +842,14 @@ enum SPR_G2_TOOLBAR_MULTIPLAYER_PRESSED = SPR_G2_BEGIN + 123, SPR_G2_MULTIPLAYER_SYNC = SPR_G2_BEGIN + 124, SPR_G2_MULTIPLAYER_DESYNC = SPR_G2_BEGIN + 125, - SPR_G2_SIMULATE = SPR_G2_BEGIN + 126, - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 127, + SPR_G2_SIMULATE = SPR_G2_BEGIN + 126, + SPR_G2_RCT1_SIMULATE_BUTTON_0 = SPR_G2_BEGIN + 127, + SPR_G2_RCT1_SIMULATE_BUTTON_1 = SPR_G2_BEGIN + 128, + SPR_G2_RCT1_SIMULATE_BUTTON_2 = SPR_G2_BEGIN + 129, + SPR_G2_RCT1_SIMULATE_BUTTON_3 = SPR_G2_BEGIN + 130, + + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 131, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, From 1dd696d4534b5654794c899c721e9bf9894e9dae Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 26 May 2019 12:00:46 +0100 Subject: [PATCH 424/506] Do not clear construction / peeps when querying ride entrance / exit --- src/openrct2/actions/RideEntranceExitPlaceAction.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp index 83e77d84e1..97bdb28ac8 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp @@ -89,9 +89,6 @@ public: return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_NOT_ALLOWED_TO_MODIFY_STATION); } - ride_clear_for_construction(ride); - ride_remove_peeps(ride); - const auto location = _isExit ? ride_get_exit_location(ride, _stationNum) : ride_get_entrance_location(ride, _stationNum); From 63b16496664d9726f45cb7c001d9a261cb0acb2a Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 28 May 2019 16:53:31 +0100 Subject: [PATCH 425/506] Do not clear construction / peeps for ghost entrance / exits --- src/openrct2/actions/RideEntranceExitPlaceAction.hpp | 7 +++++-- src/openrct2/actions/RideEntranceExitRemoveAction.hpp | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp index 97bdb28ac8..3dd6ebc504 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.hpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.hpp @@ -153,8 +153,11 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle); } - ride_clear_for_construction(ride); - ride_remove_peeps(ride); + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + { + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + } const auto location = _isExit ? ride_get_exit_location(ride, _stationNum) : ride_get_entrance_location(ride, _stationNum); diff --git a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp index 88ce3f3536..0b67bbddf0 100644 --- a/src/openrct2/actions/RideEntranceExitRemoveAction.hpp +++ b/src/openrct2/actions/RideEntranceExitRemoveAction.hpp @@ -123,9 +123,12 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_NONE); } - ride_clear_for_construction(ride); - ride_remove_peeps(ride); - invalidate_test_results(ride); + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + { + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + invalidate_test_results(ride); + } bool found = false; TileElement* tileElement = map_get_first_element_at(_loc.x / 32, _loc.y / 32); From ca32357dad128c5358fbf5ea3998ded7ee85e7ec Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 28 May 2019 22:05:15 +0100 Subject: [PATCH 426/506] Use bool for isApplying --- src/openrct2/actions/RideSetStatus.hpp | 10 +++++----- src/openrct2/ride/Ride.cpp | 4 ++-- src/openrct2/ride/Ride.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index b3a94a36c3..bcf3245ba1 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -83,7 +83,7 @@ public: } else if (_status == RIDE_STATUS_TESTING || _status == RIDE_STATUS_SIMULATING) { - if (!ride_is_valid_for_test(ride, _status, 0)) + if (!ride_is_valid_for_test(ride, _status, false)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; @@ -92,7 +92,7 @@ public: } else if (_status == RIDE_STATUS_OPEN) { - if (!ride_is_valid_for_open(ride, _status == RIDE_STATUS_OPEN, 0)) + if (!ride_is_valid_for_open(ride, _status == RIDE_STATUS_OPEN, false)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; @@ -153,7 +153,7 @@ public: ride_clear_for_construction(ride); ride_remove_peeps(ride); - if (!ride_is_valid_for_test(ride, _status, 1)) + if (!ride_is_valid_for_test(ride, _status, true)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; @@ -194,14 +194,14 @@ public: if (_status == RIDE_STATUS_TESTING) { - if (!ride_is_valid_for_test(ride, _status, 1)) + if (!ride_is_valid_for_test(ride, _status, true)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; return res; } } - else if (!ride_is_valid_for_open(ride, _status == RIDE_STATUS_OPEN, 1)) + else if (!ride_is_valid_for_open(ride, _status == RIDE_STATUS_OPEN, true)) { res->Error = GA_ERROR::UNKNOWN; res->ErrorMessage = gGameCommandErrorText; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 140cb4dfe4..30e26f8fa7 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5407,7 +5407,7 @@ static TileElement* loc_6B4F6B(ride_id_t rideIndex, int32_t x, int32_t y) return nullptr; } -int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying) +int32_t ride_is_valid_for_test(Ride* ride, int32_t status, bool isApplying) { int32_t stationIndex; CoordsXYE trackElement, problematicTrackElement = {}; @@ -5546,7 +5546,7 @@ int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying) * * rct2: 0x006B4EEA */ -int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, int32_t isApplying) +int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, bool isApplying) { int32_t stationIndex; CoordsXYE trackElement, problematicTrackElement = {}; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index ce2826af24..8b115a0470 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1075,8 +1075,8 @@ void ride_measurements_update(); rct_ride_measurement* ride_get_measurement(Ride* ride, rct_string_id* message); void ride_breakdown_add_news_item(Ride* ride); Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection); -int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, int32_t isApplying); -int32_t ride_is_valid_for_test(Ride* ride, int32_t status, int32_t isApplying); +int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, bool isApplying); +int32_t ride_is_valid_for_test(Ride* ride, int32_t status, bool isApplying); int32_t ride_initialise_construction_window(Ride* ride); void ride_construction_invalidate_current_track(); int32_t sub_6C683D( From 8d5e083998b871ca15daeca2bf8e0ec346054670 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 28 May 2019 22:06:56 +0100 Subject: [PATCH 427/506] Remove duplicate divisions --- src/openrct2/ride/thrill/LaunchedFreefall.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/openrct2/ride/thrill/LaunchedFreefall.cpp b/src/openrct2/ride/thrill/LaunchedFreefall.cpp index 27cdffbc9f..8a157f64b1 100644 --- a/src/openrct2/ride/thrill/LaunchedFreefall.cpp +++ b/src/openrct2/ride/thrill/LaunchedFreefall.cpp @@ -58,24 +58,25 @@ void vehicle_visual_launched_freefall( { baseImage_id += 2; // Draw peeps sitting without transparent area between them for restraints } - image_id = (baseImage_id + ((((imageDirection / 8) + 0) & 3) * 3)) + auto directionOffset = imageDirection / 8; + image_id = (baseImage_id + (((directionOffset + 0) & 3) * 3)) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[0], vehicle->peep_tshirt_colours[1]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); if (vehicle->num_peeps > 2) { - image_id = (baseImage_id + ((((imageDirection / 8) + 1) & 3) * 3)) + image_id = (baseImage_id + (((directionOffset + 1) & 3) * 3)) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[2], vehicle->peep_tshirt_colours[3]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } if (vehicle->num_peeps > 4) { - image_id = (baseImage_id + ((((imageDirection / 8) + 2) & 3) * 3)) + image_id = (baseImage_id + (((directionOffset + 2) & 3) * 3)) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[4], vehicle->peep_tshirt_colours[5]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } if (vehicle->num_peeps > 6) { - image_id = (baseImage_id + ((((imageDirection / 8) + 3) & 3) * 3)) + image_id = (baseImage_id + (((directionOffset + 3) & 3) * 3)) | SPRITE_ID_PALETTE_COLOUR_2(vehicle->peep_tshirt_colours[6], vehicle->peep_tshirt_colours[7]); sub_98199C(session, image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1); } From efac635cfa9a0362af7176c43a127bc2de14fae7 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 28 May 2019 22:37:54 +0100 Subject: [PATCH 428/506] Do not update ride measurements when simulating --- src/openrct2/ride/Ride.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 30e26f8fa7..1d67f49bcc 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -3152,7 +3152,7 @@ void ride_measurements_update() continue; Ride* ride = get_ride(measurement->ride_index); - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) || ride->status == RIDE_STATUS_SIMULATING) continue; if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) From 4d7c78fa3afe7cc22e73c4ba7dac1d2c0a64976a Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 29 May 2019 04:00:23 +0000 Subject: [PATCH 429/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 1 + data/language/ko-KR.txt | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 3473fef7ad..7cc54cc14e 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3789,6 +3789,7 @@ STR_6318 :Detekována síťová desynchronizace.{NEWLINE}Log: {STRING} STR_6319 :{WINDOW_COLOUR_2}Uzavřený brzdný blok STR_6320 :{WINDOW_COLOUR_2}Nezničitelné STR_6321 :{WINDOW_COLOUR_2}Rozbitá část +STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} ############################################################################### ## RCT2 Scenarios diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index c0cd623702..948854bfc1 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -135,7 +135,7 @@ STR_0552 : STR_0553 : STR_0554 :차량이 선형 유도 모터에 의해 긴 평지 트랙을 따라 가속된 뒤, 수직 상승 트랙에 의해 위로 상승한 뒤 다시 뒤로 자유낙하하여 탑승장에 돌아옵니다. STR_0555 :손님은 엘리베이터에 탑승하여 한쪽에서 다른쪽으로 이동할 수 있습니다. -STR_0556 :폭이 넓은 차량이 수직으로 기울어진 트랙을 따라 내려오면서 최고의 자유 낙하를 경험하게 해줍니다. +STR_0556 :폭이 넓은 차량이 수직으로 기울어진 트랙을 따라 내려오면서 최고의 자유 낙하를 경험할 수 있습니다. STR_0557 : STR_0558 : STR_0559 : @@ -3314,7 +3314,7 @@ STR_5854 :{SMALLFONT}{BLACK}놀이기구 음악 켜기/끄기 STR_5855 :{SMALLFONT}{BLACK}전체화면, 창 모드, 전체화면 (창모드) 중에서 선택합니다. STR_5856 :{SMALLFONT}{BLACK}전체화면에서 사용할 게임 해상도를 설정합니다. STR_5857 :{SMALLFONT}{BLACK}게임 설정 -STR_5858 :{SMALLFONT}{BLACK}CPU 대신 GPU를 이용하여 화면을 표시합니다. 스크린 캡처 소프트웨어의 호환성을 향상해줍니다. 약간의 속도 저하가 발생할 수 있습니다. +STR_5858 :{SMALLFONT}{BLACK}CPU 대신 GPU를 이용하여 화면을 표시합니다. 스크린 캡처 소프트웨어의 호환성을 향상시켜줍니다. 약간의 속도 저하가 발생할 수 있습니다. STR_5859 :{SMALLFONT}{BLACK}시각적으로 더 부드러운 게임 플레이를 위해 프레임 제한을 해제합니다. 설정을 끄면 게임이 40 FPS로 실행됩니다. STR_5860 :오리지널 트랙 표시 방식 전환 STR_5861 :키 인증 실패 @@ -3516,7 +3516,7 @@ STR_6057 :{SMALLFONT}{BLACK}메인 메뉴에 음소거를 설정할 수 있 STR_6058 :음소거 STR_6059 :» STR_6060 :손님이 돈을 쓰면 화면에 표시 -STR_6061 :{SMALLFONT}{BLACK}손님들이 돈을 사용하면{NEWLINE}화면에 움직이는 글씨로 표시해줍니다. +STR_6061 :{SMALLFONT}{BLACK}손님들이 돈을 사용하면{NEWLINE}화면에 움직이는 글씨로 표시합니다. STR_6062 :{OUTLINE}{GREEN}+ {CURRENCY2DP} STR_6063 :{OUTLINE}{RED}- {CURRENCY2DP} STR_6064 :모든 땅 소유 @@ -3576,7 +3576,7 @@ STR_6117 :탑승객들은 한 바퀴를 운행하는 편안한 좌석에 앉 STR_6118 :큰 놀이기구를 탈 용기가 없는 사람들을 위한 얌전한 롤러코스터입니다. STR_6119 :높이 제한이 있지만, 값싸고 건설하기 쉬운 롤러코스터입니다. STR_6120 :{BABYBLUE}{STRINGID}에 새로운 차량이 추가되었습니다:{NEWLINE}{STRINGID} -STR_6121 :{SMALLFONT}{BLACK}공원이 소유한 땅을 맵 끝까지 모든 방향으로 확장해줍니다. +STR_6121 :{SMALLFONT}{BLACK}공원이 소유한 땅을 맵 끝까지 모든 방향으로 확장합니다. STR_6122 :이 시나리오에 롤러코스터가 충분히 많이 있지 않습니다! STR_6123 :공원에 사용된 오브젝트 불러오기 오류 STR_6124 :오브젝트 이름 @@ -3658,7 +3658,7 @@ STR_6199 :날짜 설정 STR_6200 :날짜 초기화 STR_6201 :{MONTH} STR_6202 :가상 지면 표시 -STR_6203 :{SMALLFONT}{BLACK}이 설정을 켜면, Ctrl이나 Shift 키를 누르고 있을 때 오브젝트의 수직 설치에 도움이 되는 가상 지면을 표시해줍니다. +STR_6203 :{SMALLFONT}{BLACK}이 설정을 켜면, Ctrl이나 Shift 키를 누르고 있을 때 오브젝트의 수직 설치에 도움이 되는 가상 지면을 표시합니다. STR_6204 :벽돌 STR_6205 :철 STR_6206 :회색 절벽 @@ -3777,6 +3777,7 @@ STR_6318 :네트워크 비동기화가 감지되었습니다.{NEWLINE}로그 STR_6319 :{WINDOW_COLOUR_2}블록 브레이크 닫기 STR_6320 :{WINDOW_COLOUR_2}파괴 불가 STR_6321 :{WINDOW_COLOUR_2}기물 부서짐 +STR_6322 :{WINDOW_COLOUR_2}스프라이트 ID: {BLACK}{INT32} ############# From 951f5009ef7ca8825bd181246a33aae9586cb681 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 29 May 2019 19:15:50 +0200 Subject: [PATCH 430/506] Refactor window storage to use std::list instead of std::vector --- src/openrct2-ui/UiContext.cpp | 7 +- src/openrct2-ui/input/MouseInput.cpp | 15 +- src/openrct2-ui/interface/Window.cpp | 18 +- src/openrct2/interface/Viewport.cpp | 12 +- src/openrct2/interface/Window.cpp | 226 ++++++++++++++--------- src/openrct2/interface/Window.h | 5 +- src/openrct2/interface/Window_internal.h | 4 +- 7 files changed, 170 insertions(+), 117 deletions(-) diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 0c2b9b6b80..197b38ae9f 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -784,9 +784,10 @@ private: DrawRainFunc drawFunc) { rct_window* w{}; - for (auto i = window_get_index(original_w) + 1;; i++) + auto itStart = window_get_iterator(original_w); + for (auto it = std::next(itStart);; it++) { - if (i >= g_window_list.size()) + if (it == g_window_list.end()) { // Loop ended, draw rain for original_w auto vp = original_w->viewport; @@ -806,7 +807,7 @@ private: return; } - w = g_window_list[i].get(); + w = it->get(); if (right <= w->x || bottom <= w->y) { continue; diff --git a/src/openrct2-ui/input/MouseInput.cpp b/src/openrct2-ui/input/MouseInput.cpp index 9978cac6f2..4f4244449a 100644 --- a/src/openrct2-ui/input/MouseInput.cpp +++ b/src/openrct2-ui/input/MouseInput.cpp @@ -106,10 +106,13 @@ static void input_update_tooltip(rct_window* w, rct_widgetindex widgetIndex, int void game_handle_input() { // NOTE: g_window_list may change during the event callbacks. - for (size_t i = g_window_list.size(); i > 0; i--) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = g_window_list[i - 1]; + auto itNext = std::next(it); + auto& w = *it; window_event_periodic_update_call(w.get()); + it = itNext; } invalidate_all_windows_after_input(); @@ -136,11 +139,13 @@ void game_handle_input() process_mouse_tool(x, y); } - // NOTE: g_window_list may change during the event callbacks. - for (size_t i = g_window_list.size(); i > 0; i--) + it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = g_window_list[i - 1]; + auto itNext = std::next(it); + auto& w = *it; window_event_unknown_08_call(w.get()); + it = itNext; } } diff --git a/src/openrct2-ui/interface/Window.cpp b/src/openrct2-ui/interface/Window.cpp index 6ee962f876..7b8146da4f 100644 --- a/src/openrct2-ui/interface/Window.cpp +++ b/src/openrct2-ui/interface/Window.cpp @@ -105,31 +105,31 @@ rct_window* window_create( } // Find right position to insert new window - auto dstIndex = g_window_list.size(); + auto itDestPos = g_window_list.end(); if (flags & WF_STICK_TO_BACK) { - for (size_t i = 0; i < g_window_list.size(); i++) + for (auto it = g_window_list.begin(); it != g_window_list.end(); it++) { - if (!(g_window_list[i]->flags & WF_STICK_TO_BACK)) + if (!((*it)->flags & WF_STICK_TO_BACK)) { - dstIndex = i; + itDestPos = it; } } } else if (!(flags & WF_STICK_TO_FRONT)) { - for (size_t i = g_window_list.size(); i > 0; i--) + for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) { - if (!(g_window_list[i - 1]->flags & WF_STICK_TO_FRONT)) + if (!((*it)->flags & WF_STICK_TO_FRONT)) { - dstIndex = i; + itDestPos = it.base(); break; } } } - g_window_list.insert(g_window_list.begin() + dstIndex, std::make_unique()); - auto w = g_window_list[dstIndex].get(); + auto itNew = g_window_list.insert(itDestPos, std::make_unique()); + auto w = itNew->get(); // Setup window w->classification = cls; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index b85c0201c2..7c661bdabb 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -254,9 +254,10 @@ static void viewport_redraw_after_shift( || viewport->x >= window->x + window->width || viewport->y + viewport->height <= window->y || viewport->y >= window->y + window->height) { - auto nextWindowIndex = window_get_index(window) + 1; - auto nextWindow = nextWindowIndex >= g_window_list.size() ? nullptr : g_window_list[nextWindowIndex].get(); - viewport_redraw_after_shift(dpi, nextWindow, viewport, x, y); + auto itWindowPos = window_get_iterator(window); + auto itNextWindow = itWindowPos != g_window_list.end() ? std::next(itWindowPos) : g_window_list.end(); + viewport_redraw_after_shift( + dpi, itNextWindow == g_window_list.end() ? nullptr : itNextWindow->get(), viewport, x, y); return; } @@ -368,9 +369,10 @@ static void viewport_redraw_after_shift( static void viewport_shift_pixels( rct_drawpixelinfo* dpi, rct_window* window, rct_viewport* viewport, int16_t x_diff, int16_t y_diff) { - for (auto i = window_get_index(window); i < g_window_list.size(); i++) + auto it = window_get_iterator(window); + for (; it != g_window_list.end(); it++) { - auto w = g_window_list[i].get(); + auto w = it->get(); if (!(w->flags & WF_TRANSPARENT)) continue; if (w->viewport == viewport) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index c29279a90a..0bea48d6fc 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -35,8 +35,9 @@ #include #include #include +#include -std::vector> g_window_list; +std::list> g_window_list; rct_window* gWindowAudioExclusive; uint16_t TextInputDescriptionArgs[4]; @@ -80,16 +81,11 @@ static int32_t window_draw_split( rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); -size_t window_get_index(const rct_window* w) +std::list>::iterator window_get_iterator(const rct_window* w) { - for (size_t i = 0; i < g_window_list.size(); i++) - { - if (g_window_list[i].get() == w) - { - return i; - } - } - return std::numeric_limits::max(); + return std::find_if(g_window_list.begin(), g_window_list.end(), [w](const std::unique_ptr& w2) -> bool { + return w == w2.get(); + }); } /** @@ -100,25 +96,26 @@ void window_dispatch_update_all() { // gTooltipNotShownTicks++; - // The window list can change during update calls, so use index based iteration - for (auto i = g_window_list.size(); i > 0; i--) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - if (i - 1 < g_window_list.size()) - { - auto& w = g_window_list[i - 1]; - window_event_update_call(w.get()); - } + auto itNext = std::next(it); + window_event_update_call((*it).get()); + it = itNext; } } void window_update_all_viewports() { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - if (w->viewport != nullptr && window_is_visible(w.get())) + auto itNext = std::next(it); + if ((*it)->viewport != nullptr && window_is_visible((*it).get())) { - viewport_update_position(w.get()); + viewport_update_position((*it).get()); } + it = itNext; } } @@ -137,16 +134,22 @@ void window_update_all() if (gWindowUpdateTicks >= 1000) { gWindowUpdateTicks = 0; - for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) + + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto w = it->get(); + auto itNext = std::next(it); + auto w = (*it).get(); window_event_periodic_update_call(w); + it = itNext; } } // Border flash invalidation - for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { + auto itNext = std::next(it); auto w = it->get(); if (w->flags & WF_WHITE_BORDER_MASK) { @@ -156,6 +159,7 @@ void window_update_all() window_invalidate(w); } } + it = itNext; } auto windowManager = OpenRCT2::GetContext()->GetUiContext()->GetWindowManager(); @@ -238,10 +242,13 @@ void window_close(rct_window* window) // Invalidate the window (area) window_invalidate(window); - auto index = window_get_index(window); - if (index != std::numeric_limits::max()) + for (auto it = g_window_list.begin(); it != g_window_list.end(); it++) { - g_window_list.erase(g_window_list.begin() + index); + if ((*it).get() == window) + { + g_window_list.erase(it); + break; + } } } @@ -252,14 +259,16 @@ void window_close(rct_window* window) */ void window_close_by_class(rct_windowclass cls) { - for (size_t i = 0; i < g_window_list.size(); i++) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = *g_window_list[i]; - if (w.classification == cls) + auto itNext = std::next(it); + auto w = it->get(); + if (w->classification == cls) { - window_close(&w); - i--; + window_close(w); } + it = itNext; } } @@ -271,14 +280,16 @@ void window_close_by_class(rct_windowclass cls) */ void window_close_by_number(rct_windowclass cls, rct_windownumber number) { - for (size_t i = 0; i < g_window_list.size(); i++) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = *g_window_list[i]; - if (w.classification == cls && w.number == number) + auto itNext = std::next(it); + auto w = it->get(); + if (w->classification == cls && w->number == number) { - window_close(&w); - i--; + window_close(w); } + it = itNext; } } @@ -334,10 +345,10 @@ void window_close_top() for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) { - auto& w = **it; - if (!(w.flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) + auto& w = (*it); + if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) { - window_close(&w); + window_close(w.get()); break; } } @@ -351,26 +362,30 @@ void window_close_top() void window_close_all() { window_close_by_class(WC_DROPDOWN); - for (size_t i = g_window_list.size(); i > 0; i--) + + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = *g_window_list[i - 1]; - if (!(w.flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - { - window_close(&w); - } + auto itNext = std::next(it); + auto w = it->get(); + window_close(w); + it = itNext; } } void window_close_all_except_class(rct_windowclass cls) { window_close_by_class(WC_DROPDOWN); - for (size_t i = g_window_list.size(); i > 0; i--) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = *g_window_list[i - 1]; - if (w.classification != cls && !(w.flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) + auto itNext = std::next(it); + auto w = it->get(); + if (w->classification != cls && !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) { - window_close(&w); + window_close(w); } + it = itNext; } } @@ -379,13 +394,16 @@ void window_close_all_except_class(rct_windowclass cls) */ void window_close_all_except_flags(uint16_t flags) { - for (size_t i = g_window_list.size(); i > 0; i--) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - auto& w = *g_window_list[i - 1]; - if (!(w.flags & flags)) + auto itNext = std::next(it); + auto w = it->get(); + if (!(w->flags & flags)) { - window_close(&w); + window_close(w); } + it = itNext; } } @@ -397,18 +415,18 @@ rct_window* window_find_from_point(int32_t x, int32_t y) { for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) { - auto& w = **it; - if (x < w.x || x >= w.x + w.width || y < w.y || y >= w.y + w.height) + auto& w = *it; + if (x < w->x || x >= w->x + w->width || y < w->y || y >= w->y + w->height) continue; - if (w.flags & WF_NO_BACKGROUND) + if (w->flags & WF_NO_BACKGROUND) { - auto widgetIndex = window_find_widget_from_point(&w, x, y); + auto widgetIndex = window_find_widget_from_point(w.get(), x, y); if (widgetIndex == -1) continue; } - return &w; + return w.get(); } return nullptr; @@ -473,12 +491,16 @@ void window_invalidate(rct_window* window) */ void window_invalidate_by_class(rct_windowclass cls) { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { + auto itNext = std::next(it); + auto w = it->get(); if (w->classification == cls) { - window_invalidate(w.get()); + window_invalidate(w); } + it = itNext; } } @@ -488,12 +510,16 @@ void window_invalidate_by_class(rct_windowclass cls) */ void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number) { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { + auto itNext = std::next(it); + auto w = it->get(); if (w->classification == cls && w->number == number) { - window_invalidate(w.get()); + window_invalidate(w); } + it = itNext; } } @@ -502,9 +528,13 @@ void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number) */ void window_invalidate_all() { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { - window_invalidate(w.get()); + auto itNext = std::next(it); + auto w = it->get(); + window_invalidate(w); + it = itNext; } } @@ -536,12 +566,16 @@ void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex) */ void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex) { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { + auto itNext = std::next(it); + auto w = it->get(); if (w->classification == cls) { - widget_invalidate(w.get(), widgetIndex); + widget_invalidate(w, widgetIndex); } + it = itNext; } } @@ -551,12 +585,16 @@ void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex */ void widget_invalidate_by_number(rct_windowclass cls, rct_windownumber number, rct_widgetindex widgetIndex) { - for (auto& w : g_window_list) + auto it = g_window_list.begin(); + while (it != g_window_list.end()) { + auto itNext = std::next(it); + auto w = it->get(); if (w->classification == cls && w->number == number) { - widget_invalidate(w.get(), widgetIndex); + widget_invalidate(w, widgetIndex); } + it = itNext; } } @@ -640,25 +678,25 @@ rct_window* window_bring_to_front(rct_window* w) { if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) { - size_t srcIndex = window_get_index(w); - if (srcIndex != std::numeric_limits::max()) + auto itSourcePos = window_get_iterator(w); + if (itSourcePos != g_window_list.end()) { - auto wptr = std::move(g_window_list[srcIndex]); - g_window_list.erase(g_window_list.begin() + srcIndex); + auto wptr = std::move(*itSourcePos); + g_window_list.erase(itSourcePos); // Insert in front of the first non-stick-to-front window - size_t dstIndex = 0; - for (size_t i = g_window_list.size(); i > 0; i--) + auto itDestPos = g_window_list.begin(); + for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) { - auto& w2 = *g_window_list[i - 1]; - if (!(w2.flags & WF_STICK_TO_FRONT)) + auto& w2 = *it; + if (!(w2->flags & WF_STICK_TO_FRONT)) { - dstIndex = i; + itDestPos = it.base(); break; } } - g_window_list.insert(g_window_list.begin() + dstIndex, std::move(wptr)); + g_window_list.insert(itDestPos, std::move(wptr)); window_invalidate(w); if (w->x + w->width < 20) @@ -854,6 +892,8 @@ void window_set_location(rct_window* w, int32_t x, int32_t y, int32_t z) */ void window_scroll_to_location(rct_window* w, int32_t x, int32_t y, int32_t z) { + log_info("YEP"); + LocationXYZ16 location_3d = { (int16_t)x, (int16_t)y, (int16_t)z }; assert(w != nullptr); @@ -890,15 +930,11 @@ void window_scroll_to_location(rct_window* w, int32_t x, int32_t y, int32_t z) { int16_t x2 = w->viewport->x + (int16_t)(w->viewport->width * window_scroll_locations[i][0]); int16_t y2 = w->viewport->y + (int16_t)(w->viewport->height * window_scroll_locations[i][1]); - for (auto w2i = window_get_index(w); w2i <= g_window_list.size(); w2i++) - { - if (w2i == g_window_list.size()) - { - found = true; - break; - } - auto& w2 = g_window_list[w2i]; + auto it = window_get_iterator(w); + for (; it != g_window_list.end(); it++) + { + auto w2 = (*it).get(); int16_t x1 = w2->x - 10; int16_t y1 = w2->y - 10; if (x2 >= x1 && x2 <= w2->width + x1 + 20) @@ -912,6 +948,10 @@ void window_scroll_to_location(rct_window* w, int32_t x, int32_t y, int32_t z) } } } + if (it == g_window_list.end()) + { + found = true; + } if (i >= (int32_t)std::size(window_scroll_locations)) { i = 0; @@ -1151,10 +1191,10 @@ void window_draw(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t to return; // Draw the window in this region - for (size_t i = window_get_index(w); i < g_window_list.size(); i++) + for (auto it = window_get_iterator(w); it != g_window_list.end(); it++) { // Don't draw overlapping opaque windows, they won't have changed - auto v = g_window_list[i].get(); + auto v = (*it).get(); if ((w == v || (v->flags & WF_TRANSPARENT)) && window_is_visible(v)) { window_draw_single(dpi, v, left, top, right, bottom); @@ -1170,10 +1210,11 @@ static int32_t window_draw_split( rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom) { // Divide the draws up for only the visible regions of the window recursively - for (auto i = window_get_index(w) + 1; i < g_window_list.size(); i++) + auto itPos = window_get_iterator(w); + for (auto it = std::next(itPos); it != g_window_list.end(); it++) { // Check if this window overlaps w - auto topwindow = g_window_list[i].get(); + auto topwindow = it->get(); if (topwindow->x >= right || topwindow->y >= bottom) continue; if (topwindow->x + topwindow->width <= left || topwindow->y + topwindow->height <= top) @@ -2068,9 +2109,10 @@ bool window_is_visible(rct_window* w) } // start from the window above the current - for (auto i = window_get_index(w) + 1; i < g_window_list.size(); i++) + auto itPos = window_get_iterator(w); + for (auto it = std::next(itPos); it != g_window_list.end(); it++) { - auto& w_other = *g_window_list[i]; + auto& w_other = *(*it); // if covered by a higher window, no rendering needed if (w_other.x <= w->x && w_other.y <= w->y && w_other.x + w_other.width >= w->x + w->width diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index b6a0e24ec8..780b42e312 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -14,6 +14,8 @@ #include "../ride/RideTypes.h" #include +#include +#include struct rct_drawpixelinfo; struct rct_window; @@ -580,7 +582,8 @@ extern colour_t gCurrentWindowColours[4]; extern bool gDisableErrorWindowSound; -size_t window_get_index(const rct_window* w); +std::list>::iterator window_get_iterator(const rct_window* w); + void window_dispatch_update_all(); void window_update_all_viewports(); void window_update_all(); diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index 6aa64f1e2b..dde8a72076 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -11,8 +11,8 @@ #include "Window.h" +#include #include -#include struct rct_research_item; struct rct_object_entry; @@ -104,4 +104,4 @@ struct rct_window }; // rct2: 0x01420078 -extern std::vector> g_window_list; +extern std::list> g_window_list; From 67f1359936bdd70a5153304160d125d2144e3835 Mon Sep 17 00:00:00 2001 From: James Warwood Date: Thu, 30 May 2019 09:33:13 +0100 Subject: [PATCH 431/506] Fix: Unable to change colours of scrolling wall banner sign via sign dialog (#9303) 1. Check in SignSetStlyeAction query was accidentally inverting value of wallFound boolean 2. Code in action execution was not looping through the tile elements to find the correct wall piece like the query did (which meant just fixing 1. would cause a segfault) Moved code to find relevant wall tile element into new helper function banner_get_scrolling_wall_tile_element() in Banner; use in both query and action to avoid any duplication of search logic. --- src/openrct2/actions/SignSetStyleAction.hpp | 27 ++++++--------------- src/openrct2/network/Network.cpp | 2 +- src/openrct2/world/Banner.cpp | 26 ++++++++++++++++++++ src/openrct2/world/Banner.h | 1 + 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/openrct2/actions/SignSetStyleAction.hpp b/src/openrct2/actions/SignSetStyleAction.hpp index dae643cf23..7493d0fc24 100644 --- a/src/openrct2/actions/SignSetStyleAction.hpp +++ b/src/openrct2/actions/SignSetStyleAction.hpp @@ -77,23 +77,9 @@ public: } else { - TileElement* tileElement = map_get_first_element_at(coords.x / 32, coords.y / 32); - bool wallFound = false; - do - { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL) - continue; + WallElement* wallElement = banner_get_scrolling_wall_tile_element(static_cast(_bannerIndex)); - rct_scenery_entry* scenery_entry = tileElement->AsWall()->GetEntry(); - if (scenery_entry->wall.scrolling_mode == SCROLLING_MODE_NONE) - continue; - if (tileElement->AsWall()->GetBannerIndex() != (BannerIndex)_bannerIndex) - continue; - wallFound = true; - break; - } while (!(tileElement++)->IsLastForTile()); - - if (!wallFound == false) + if (!wallElement) { log_warning("Invalid game command for setting sign style, banner id '%d' not found", _bannerIndex); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); @@ -121,10 +107,11 @@ public: } else { - TileElement* tileElement = map_get_first_element_at(coords.x / 32, coords.y / 32); - tileElement->AsWall()->SetPrimaryColour(_mainColour); - tileElement->AsWall()->SetSecondaryColour(_textColour); - map_invalidate_tile(coords.x, coords.y, tileElement->base_height * 8, tileElement->clearance_height * 8); + WallElement* wallElement = banner_get_scrolling_wall_tile_element(static_cast(_bannerIndex)); + + wallElement->SetPrimaryColour(_mainColour); + wallElement->SetSecondaryColour(_textColour); + map_invalidate_tile(coords.x, coords.y, wallElement->base_height * 8, wallElement->clearance_height * 8); } auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 3429d978fb..4bc9502f69 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 "35" +#define NETWORK_STREAM_VERSION "36" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index f0f3aa0ce6..4ec4bd87a2 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -128,6 +128,32 @@ TileElement* banner_get_tile_element(BannerIndex bannerIndex) return nullptr; } +WallElement* banner_get_scrolling_wall_tile_element(BannerIndex bannerIndex) +{ + rct_banner* banner = &gBanners[bannerIndex]; + TileElement* tileElement = map_get_first_element_at(banner->x, banner->y); + + if (tileElement == nullptr) + return nullptr; + + do + { + auto wallElement = tileElement->AsWall(); + + if (wallElement == nullptr) + continue; + + rct_scenery_entry* scenery_entry = wallElement->GetEntry(); + if (scenery_entry->wall.scrolling_mode == SCROLLING_MODE_NONE) + continue; + if (wallElement->GetBannerIndex() != bannerIndex) + continue; + return wallElement; + } while (!(tileElement++)->IsLastForTile()); + + return nullptr; +} + /** * * rct2: 0x006B7D86 diff --git a/src/openrct2/world/Banner.h b/src/openrct2/world/Banner.h index 962bfb119f..b504d66a0f 100644 --- a/src/openrct2/world/Banner.h +++ b/src/openrct2/world/Banner.h @@ -49,6 +49,7 @@ extern rct_banner gBanners[MAX_BANNERS]; void banner_init(); BannerIndex create_new_banner(uint8_t flags); TileElement* banner_get_tile_element(BannerIndex bannerIndex); +WallElement* banner_get_scrolling_wall_tile_element(BannerIndex bannerIndex); uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z); void banner_reset_broken_index(); void fix_duplicated_banners(); From bc14f427a5cac7aa3dd9dc2a46b52eb31da4d34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 30 May 2019 20:49:54 +0200 Subject: [PATCH 432/506] Fix #9322: Peep crashing the game trying to find a ride to look at --- distribution/changelog.txt | 1 + src/openrct2/peep/Guest.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b1877ade72..f584c8b6d7 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -48,6 +48,7 @@ - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Fix: [#9240] Crash when passing directory instead of save file. - Fix: [#9293] Issue with the native load/save dialog. +- Fix: [#9322] Peep crashing the game trying to find a ride to look at. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 2a82a05de6..a7118a158f 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -6278,6 +6278,11 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV surfaceElement = map_get_surface_element_at({ peep->next_x, peep->next_y }); tileElement = surfaceElement; + if (tileElement == nullptr) + { + return false; + } + do { // Ghosts are purely this-client-side and should not cause any interaction, @@ -6312,6 +6317,11 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV surfaceElement = map_get_surface_element_at({ x, y }); tileElement = surfaceElement; + if (tileElement == nullptr) + { + return false; + } + do { // Ghosts are purely this-client-side and should not cause any interaction, @@ -6541,6 +6551,11 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV // TODO: extract loop A tileElement = surfaceElement; + if (tileElement == nullptr) + { + return false; + } + do { // Ghosts are purely this-client-side and should not cause any interaction, From 02ef545f1b87fe720ddeb2894e00462b4f47b732 Mon Sep 17 00:00:00 2001 From: aw20368 Date: Thu, 30 May 2019 14:51:56 -0400 Subject: [PATCH 433/506] Fix #9314: Trying to delete ride piece while paused moves the selection (#9332) Failed track removal was triggering a move to the next piece. Changed to move only upon successful removal. --- src/openrct2-ui/windows/RideConstruction.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 408d789a8c..757ab9c66f 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1932,12 +1932,15 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) { _currentTrackBegin.x, _currentTrackBegin.y, _currentTrackBegin.z, _currentTrackPieceDirection }); trackRemoveAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { - _stationConstructed = get_ride(w->number)->num_stations != 0; - window_ride_construction_mouseup_demolish_next_piece(x, y, z, direction, type); if (result->Error != GA_ERROR::OK) { window_ride_construction_update_active_elements(); } + else + { + _stationConstructed = get_ride(w->number)->num_stations != 0; + window_ride_construction_mouseup_demolish_next_piece(x, y, z, direction, type); + } }); GameActions::Execute(&trackRemoveAction); From 3ee6be0dbf8bad7b80a3542c1b9b2c263758f6c2 Mon Sep 17 00:00:00 2001 From: aw20368 Date: Thu, 30 May 2019 16:41:54 -0400 Subject: [PATCH 434/506] Fix #9288: Replace repeated 3d to 2d functions (#9301) Replaced duplicate 3d to 2d code with translate_3d_to_2d_with_z(...). --- src/openrct2/interface/Screenshot.cpp | 54 +++++---------------------- src/openrct2/ride/Ride.cpp | 25 ++----------- src/openrct2/world/Map.cpp | 2 + src/openrct2/world/Sprite.cpp | 30 +++------------ 4 files changed, 21 insertions(+), 90 deletions(-) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 591a465aa3..8e921cb9b0 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -253,30 +253,13 @@ void screenshot_giant() int32_t centreX = (mapSize / 2) * 32 + 16; int32_t centreY = (mapSize / 2) * 32 + 16; - int32_t x = 0, y = 0; int32_t z = tile_element_height(centreX, centreY); - switch (rotation) - { - case 0: - x = centreY - centreX; - y = ((centreX + centreY) / 2) - z; - break; - case 1: - x = -centreY - centreX; - y = ((-centreX + centreY) / 2) - z; - break; - case 2: - x = -centreY + centreX; - y = ((-centreX - centreY) / 2) - z; - break; - case 3: - x = centreY + centreX; - y = ((centreX - centreY) / 2) - z; - break; - } - viewport.view_x = x - ((viewport.view_width << zoom) / 2); - viewport.view_y = y - ((viewport.view_height << zoom) / 2); + CoordsXYZ centreCoords3d = { centreX, centreY, z }; + CoordsXY centreCoords2d = translate_3d_to_2d_with_z(rotation, centreCoords3d); + + viewport.view_x = centreCoords2d.x - ((viewport.view_width << zoom) / 2); + viewport.view_y = centreCoords2d.y - ((viewport.view_height << zoom) / 2); viewport.zoom = zoom; gCurrentRotation = rotation; @@ -531,30 +514,13 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption if (centreMapY) customY = (mapSize / 2) * 32 + 16; - int32_t x = 0, y = 0; int32_t z = tile_element_height(customX, customY); - switch (customRotation) - { - case 0: - x = customY - customX; - y = ((customX + customY) / 2) - z; - break; - case 1: - x = -customY - customX; - y = ((-customX + customY) / 2) - z; - break; - case 2: - x = -customY + customX; - y = ((-customX - customY) / 2) - z; - break; - case 3: - x = customY + customX; - y = ((customX - customY) / 2) - z; - break; - } + CoordsXYZ coords3d = { customX, customY, z }; - viewport.view_x = x - ((viewport.view_width << customZoom) / 2); - viewport.view_y = y - ((viewport.view_height << customZoom) / 2); + CoordsXY coords2d = translate_3d_to_2d_with_z(customRotation, coords3d); + + viewport.view_x = coords2d.x - ((viewport.view_width << customZoom) / 2); + viewport.view_y = coords2d.y - ((viewport.view_height << customZoom) / 2); viewport.zoom = customZoom; gCurrentRotation = customRotation; } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9345dc4adc..0d927af848 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7899,28 +7899,9 @@ StationObject* ride_get_station_object(const Ride* ride) LocationXY16 ride_get_rotated_coords(int16_t x, int16_t y, int16_t z) { - LocationXY16 rotatedCoords = { 0, 0 }; - - switch (get_current_rotation()) - { - case 0: - rotatedCoords.x = y - x; - rotatedCoords.y = ((y + x) / 2) - z; - break; - case 1: - rotatedCoords.x = -x - y; - rotatedCoords.y = ((y - x) / 2) - z; - break; - case 2: - rotatedCoords.x = x - y; - rotatedCoords.y = ((-y - x) / 2) - z; - break; - case 3: - rotatedCoords.x = y + x; - rotatedCoords.y = ((x - y) / 2) - z; - break; - } - + CoordsXYZ coords3d = { x, y, z }; + CoordsXY coords2d = translate_3d_to_2d_with_z(get_current_rotation(), coords3d); + LocationXY16 rotatedCoords = { (int16_t)coords2d.x, (int16_t)coords2d.y }; return rotatedCoords; } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 8117a00413..00fa260a61 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -143,6 +143,8 @@ LocationXY16 coordinate_3d_to_2d(const LocationXYZ16* coordinate_3d, int32_t rot switch (rotation) { + // this function has to use right-shift (... >> 1) since dividing + // by 2 with (... / 2) can differ by -1 and cause issues (see PR #9301) default: case 0: coordinate_2d.x = coordinate_3d->y - coordinate_3d->x; diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index dfdd09b3e1..1ddf780591 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -642,31 +642,13 @@ void sprite_move(int16_t x, int16_t y, int16_t z, rct_sprite* sprite) void sprite_set_coordinates(int16_t x, int16_t y, int16_t z, rct_sprite* sprite) { - int16_t new_x = x, new_y = y, start_x = x; - switch (get_current_rotation()) - { - case 0: - new_x = new_y - new_x; - new_y = (new_y + start_x) / 2 - z; - break; - case 1: - new_x = -new_y - new_x; - new_y = (new_y - start_x) / 2 - z; - break; - case 2: - new_x = -new_y + new_x; - new_y = (-new_y - start_x) / 2 - z; - break; - case 3: - new_x = new_y + new_x; - new_y = (-new_y + start_x) / 2 - z; - break; - } + CoordsXYZ coords3d = { x, y, z }; + CoordsXY newCoords = translate_3d_to_2d_with_z(get_current_rotation(), coords3d); - sprite->generic.sprite_left = new_x - sprite->generic.sprite_width; - sprite->generic.sprite_right = new_x + sprite->generic.sprite_width; - sprite->generic.sprite_top = new_y - sprite->generic.sprite_height_negative; - sprite->generic.sprite_bottom = new_y + sprite->generic.sprite_height_positive; + sprite->generic.sprite_left = newCoords.x - sprite->generic.sprite_width; + sprite->generic.sprite_right = newCoords.x + sprite->generic.sprite_width; + sprite->generic.sprite_top = newCoords.y - sprite->generic.sprite_height_negative; + sprite->generic.sprite_bottom = newCoords.y + sprite->generic.sprite_height_positive; sprite->generic.x = x; sprite->generic.y = y; sprite->generic.z = z; From dd0649dfed9a67e0c2ab330741042ee71ecfc212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 3 Jun 2019 10:26:02 +0200 Subject: [PATCH 435/506] Add version info resource to avoid/reduce false positive virus detection (#9335) --- appveyor.yml | 3 +++ resources/OpenRCT2.rc | 41 ++++++++++++++++++++++++++++++++++++++++- resources/version.h | 2 ++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 resources/version.h diff --git a/appveyor.yml b/appveyor.yml index b22470d496..5a5d3893b1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,9 @@ platform: - Win32 - x64 configuration: Release +before_build: +- ps: Set-Content -Path '.\resources\version.h' -Value "#define OPENRCT2_FILE_VERSION $($env:APPVEYOR_BUILD_VERSION -replace "\.", ",")" +- ps: Add-Content -Path '.\resources\version.h' -Value "#define OPENRCT2_PRODUCT_VERSION `"$($env:APPVEYOR_BUILD_VERSION)-$($env:APPVEYOR_REPO_COMMIT.Substring(0,10))`"" build: parallel: true project: openrct2.proj diff --git a/resources/OpenRCT2.rc b/resources/OpenRCT2.rc index f9ccc2fd1f..18c7441445 100644 --- a/resources/OpenRCT2.rc +++ b/resources/OpenRCT2.rc @@ -1,6 +1,7 @@ // Microsoft Visual C++ generated resource script. // #include "resource.h" +#include "version.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -15,8 +16,45 @@ ///////////////////////////////////////////////////////////////////////////// // English (United Kingdom) resources -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) || defined(AFX_TARG_ENG) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(65001) + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENRCT2_FILE_VERSION + PRODUCTVERSION OPENRCT2_FILE_VERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "CompanyName", "OpenRCT2 Team" + VALUE "FileDescription", "Main executable for OpenRCT2" + VALUE "FileVersion", OPENRCT2_PRODUCT_VERSION + VALUE "LegalCopyright", "Copyright (c) 2014-2019 OpenRCT2 developers" + VALUE "ProductName", "OpenRCT2" + VALUE "ProductVersion", OPENRCT2_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -67,3 +105,4 @@ IDI_ICON ICON "logo\\icon.ico" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED + diff --git a/resources/version.h b/resources/version.h new file mode 100644 index 0000000000..fcaebecce6 --- /dev/null +++ b/resources/version.h @@ -0,0 +1,2 @@ +#define OPENRCT2_FILE_VERSION 0, 0, 0, 0 +#define OPENRCT2_PRODUCT_VERSION "0.0.0.0-00000000" From af65811f50eef30da84e6ddddd96148dbf9638f3 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 3 Jun 2019 18:59:23 +0200 Subject: [PATCH 436/506] Remove useless log_info --- src/openrct2/interface/Window.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 0bea48d6fc..398542689b 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -892,8 +892,6 @@ void window_set_location(rct_window* w, int32_t x, int32_t y, int32_t z) */ void window_scroll_to_location(rct_window* w, int32_t x, int32_t y, int32_t z) { - log_info("YEP"); - LocationXYZ16 location_3d = { (int16_t)x, (int16_t)y, (int16_t)z }; assert(w != nullptr); From 4dea507e509ac473f01479c2ff00cc3887785721 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Mon, 3 Jun 2019 22:49:45 +0200 Subject: [PATCH 437/506] Fix #9360: sticky windows can be closed --- src/openrct2/interface/Window.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 0bea48d6fc..8a27297683 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -363,12 +363,14 @@ void window_close_all() { window_close_by_class(WC_DROPDOWN); - auto it = g_window_list.begin(); - while (it != g_window_list.end()) + for (auto it = g_window_list.begin(); it != g_window_list.end();) { auto itNext = std::next(it); auto w = it->get(); - window_close(w); + if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) + { + window_close(w); + } it = itNext; } } From d6975a8f23be5abac2d94f1f2a5147a7af6b4d50 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 4 Jun 2019 07:02:55 +0200 Subject: [PATCH 438/506] Fix #9365: Crash when bringing window to front --- src/openrct2/interface/Window.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 0bea48d6fc..c0ff64c0a9 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -681,9 +681,6 @@ rct_window* window_bring_to_front(rct_window* w) auto itSourcePos = window_get_iterator(w); if (itSourcePos != g_window_list.end()) { - auto wptr = std::move(*itSourcePos); - g_window_list.erase(itSourcePos); - // Insert in front of the first non-stick-to-front window auto itDestPos = g_window_list.begin(); for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) @@ -696,7 +693,7 @@ rct_window* window_bring_to_front(rct_window* w) } } - g_window_list.insert(itDestPos, std::move(wptr)); + g_window_list.splice(itDestPos, g_window_list, itSourcePos); window_invalidate(w); if (w->x + w->width < 20) From 3823befa108a59dff9eeba9f48271bdccdd86cbe Mon Sep 17 00:00:00 2001 From: aw20368 Date: Tue, 4 Jun 2019 14:34:39 -0400 Subject: [PATCH 439/506] Fix #7323 Tunnel entrances not rendering in 'highlight path issues' (#9339) Hiding path scenery caused function that draws tunnel to prematurely return. Changed to only skip drawing scenery. --- distribution/changelog.txt | 1 + .../paint/tile_element/Paint.Path.cpp | 61 +++++++++++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index fa13bbc4ae..421d6fadca 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -24,6 +24,7 @@ - Fix: [#6006] Objects higher than 6 metres are considered trees (original bug). - Fix: [#7039] Map window not rendering properly when using OpenGL. - Fix: [#7045] Theme window's colour pickers not drawn properly on OpenGL. +- Fix: [#7323] Tunnel entrances not rendering in 'highlight path issues' mode if they have benches inside. - Fix: [#7729] Money Input Prompt breaks on certain values. - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 02f24592bd..16525683ef 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -690,6 +690,8 @@ static void sub_6A3F61( if (dpi->zoom_level <= 1) { + bool paintScenery = true; + if (!gTrackDesignSaveMode) { if (tile_element->AsPath()->HasAddition()) @@ -705,45 +707,50 @@ static void sub_6A3F61( // Can be null if the object is not loaded. if (sceneryEntry == nullptr) - return; - - if ((session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES) && !(tile_element->AsPath()->IsBroken()) + { + paintScenery = false; + } + else if ( + (session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES) && !(tile_element->AsPath()->IsBroken()) && !(sceneryEntry->path_bit.draw_type == PATH_BIT_DRAW_TYPE_BINS)) { - return; + paintScenery = false; } - - switch (sceneryEntry->path_bit.draw_type) + else { - case PATH_BIT_DRAW_TYPE_LIGHTS: - path_bit_lights_paint( - session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); - break; - case PATH_BIT_DRAW_TYPE_BINS: - path_bit_bins_paint( - session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); - break; - case PATH_BIT_DRAW_TYPE_BENCHES: - path_bit_benches_paint( - session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); - break; - case PATH_BIT_DRAW_TYPE_JUMPING_FOUNTAINS: - path_bit_jumping_fountains_paint(session, sceneryEntry, height, sceneryImageFlags, dpi); - break; - } + switch (sceneryEntry->path_bit.draw_type) + { + case PATH_BIT_DRAW_TYPE_LIGHTS: + path_bit_lights_paint( + session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); + break; + case PATH_BIT_DRAW_TYPE_BINS: + path_bit_bins_paint( + session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); + break; + case PATH_BIT_DRAW_TYPE_BENCHES: + path_bit_benches_paint( + session, sceneryEntry, tile_element, height, (uint8_t)connectedEdges, sceneryImageFlags); + break; + case PATH_BIT_DRAW_TYPE_JUMPING_FOUNTAINS: + path_bit_jumping_fountains_paint(session, sceneryEntry, height, sceneryImageFlags, dpi); + break; + } - session->InteractionType = VIEWPORT_INTERACTION_ITEM_FOOTPATH; + session->InteractionType = VIEWPORT_INTERACTION_ITEM_FOOTPATH; - if (sceneryImageFlags != 0) - { - session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; + if (sceneryImageFlags != 0) + { + session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; + } } } } // Redundant zoom-level check removed - sub_6A4101(session, tile_element, height, connectedEdges, word_F3F038, railingEntry, imageFlags); + if (paintScenery) + sub_6A4101(session, tile_element, height, connectedEdges, word_F3F038, railingEntry, imageFlags); } // This is about tunnel drawing From df263eb1f6c08aa4f693a57b5a0fbdd4034d5c2f Mon Sep 17 00:00:00 2001 From: aw20368 Date: Tue, 4 Jun 2019 17:27:36 -0400 Subject: [PATCH 440/506] Fix #5896 Fences not always removed when building a tracked ride through (#9341) Fence removal did not account for track direction. Added the rotation for the track/fence intersection test. --- distribution/changelog.txt | 1 + src/openrct2/actions/TrackPlaceAction.hpp | 1 + src/openrct2/core/Numerics.hpp | 24 +++++++++++++++++++++++ src/openrct2/network/Network.cpp | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 421d6fadca..ecee6c3e2b 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -16,6 +16,7 @@ - Change: [#8427] Ghost elements now show up as white on the mini-map. - Change: [#8688] Move common actions from debug menu into cheats menu. - Fix: [#2294] Clients crashing the server with invalid object selection. +- Fix: [#4568, #5896] Incorrect fences removed when building a tracked ride through - Fix: [#5103] OpenGL: ride track preview not rendered. - Fix: [#5889] Giant screenshot does not work while using OpenGL renderer. - Fix: [#5579] Network desync immediately after connecting. diff --git a/src/openrct2/actions/TrackPlaceAction.hpp b/src/openrct2/actions/TrackPlaceAction.hpp index d55e38745f..ef8e7c9443 100644 --- a/src/openrct2/actions/TrackPlaceAction.hpp +++ b/src/openrct2/actions/TrackPlaceAction.hpp @@ -491,6 +491,7 @@ public: // Remove walls in the directions this track intersects uint8_t intersectingDirections = (*wallEdges)[blockIndex]; intersectingDirections ^= 0x0F; + intersectingDirections = rol4(intersectingDirections, _origin.direction); for (int32_t i = 0; i < 4; i++) { if (intersectingDirections & (1 << i)) diff --git a/src/openrct2/core/Numerics.hpp b/src/openrct2/core/Numerics.hpp index 4de93adfd8..e699e0c8a0 100644 --- a/src/openrct2/core/Numerics.hpp +++ b/src/openrct2/core/Numerics.hpp @@ -30,6 +30,18 @@ namespace Numerics return (((_UIntType)(x) << shift) | ((_UIntType)(x) >> (limits::digits - shift))); } + /** + * Bitwise left rotate of lowest 4 bits + * @param x unsigned 8-bit integer value + * @param shift positions to shift + * @return rotated value + */ + [[maybe_unused]] static constexpr uint8_t rol4(uint8_t x, size_t shift) + { + x &= 0x0F; + return (x << shift | x >> (4 - shift)) & 0x0F; + } + /** * Bitwise right rotate * @tparam _UIntType unsigned integral type @@ -44,4 +56,16 @@ namespace Numerics return (((_UIntType)(x) >> shift) | ((_UIntType)(x) << (limits::digits - shift))); } + /** + * Bitwise right rotate of lowest 4 bits + * @param x unsigned 8-bit integer value + * @param shift positions to shift + * @return rotated value + */ + [[maybe_unused]] static constexpr uint8_t ror4(uint8_t x, size_t shift) + { + x &= 0x0F; + return (x >> shift | x << (4 - shift)) & 0x0F; + } + } // namespace Numerics diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 4bc9502f69..cdb314d5c9 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 "36" +#define NETWORK_STREAM_VERSION "37" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 834d1e828a7bb25cdaa165bd315a553c5579a537 Mon Sep 17 00:00:00 2001 From: aw20368 Date: Wed, 5 Jun 2019 03:33:39 -0400 Subject: [PATCH 441/506] Fix #7829 Rotated information kiosk can cause 'unreachable' messages (#9337) Some entrance directions were lost upon rotation. Corrected rotation of entrance directions. --- distribution/changelog.txt | 1 + src/openrct2/ride/Ride.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index ecee6c3e2b..b72053ac31 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -30,6 +30,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#7913] RCT1/RCT2 title sequence timing is off. - Fix: [#7700, #8079, #8969] Crash when unloading buggy custom rides. +- Fix: [#7829] Rotated information kiosk can cause 'unreachable' messages. - Fix: [#7878] Scroll shortcut keys ignore SHIFT/CTRL/ALT modifiers. - Fix: [#8219] Faulty folder recreation in "save" folder. - Fix: [#8480, #8535] Crash when mirroring track design. diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index c464f35783..6ddcdcc923 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -3503,7 +3503,7 @@ static void ride_shop_connected(Ride* ride) if (trackElement == nullptr) return; - uint16_t entrance_directions = 0; + uint8_t entrance_directions = 0; uint8_t track_type = trackElement->GetTrackType(); ride = get_ride(trackElement->GetRideIndex()); if (ride == nullptr) @@ -3512,16 +3512,15 @@ static void ride_shop_connected(Ride* ride) } if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE)) { - entrance_directions = FlatRideTrackSequenceProperties[track_type][0]; + entrance_directions = FlatRideTrackSequenceProperties[track_type][0] & 0xF; } else { - entrance_directions = TrackSequenceProperties[track_type][0]; + entrance_directions = TrackSequenceProperties[track_type][0] & 0xF; } uint8_t tile_direction = trackElement->GetDirection(); - entrance_directions <<= tile_direction; - entrance_directions = ((entrance_directions >> 12) | entrance_directions) & 0xF; + entrance_directions = rol4(entrance_directions, tile_direction); // Now each bit in entrance_directions stands for an entrance direction to check if (entrance_directions == 0) From 7dc0068f6e5e129ea0fc7c3fc042fb174e8e24a1 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 6 Jun 2019 04:00:25 +0000 Subject: [PATCH 442/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/hu-HU.txt | 108 +++++++++++++++++++++++++++++++++++++++- data/language/ko-KR.txt | 4 ++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index a008b09b2b..966dfebe4d 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -153,6 +153,7 @@ STR_0584 :Speciális, az utasok pedálozásával hajtott biciklik futnak egy STR_0588 :Különálló kocsik futnak a cikcakkos, hajtűkanyarokkal és éles esésekkel teli pálya alatt STR_0589 :Egy nagy, repülőszőnyeg-témájú kocsi, amely ciklikusan fel-le mozog a 4 kar végén STR_0590 :Az utasok egy alámerült tengeralattjáróban utaznak végig egy víz alatti pályán +STR_0591 :A tutaj alakú csónakok szelíden kanyarognak a folyó pályája mentén STR_0599 :Egy kompakt hullámvasút különálló kocsikkal és sima, csavaros esésekkel STR_0600 :Motoros bányavonatok futnak egy sima és csavaros pálya mentén STR_0602 :A hullámvasút vonatai aszinkronmotoros gyorsítással hagyják el az állomást, hogy átszáguldjanak a csavaros fordítókon @@ -1097,7 +1098,7 @@ STR_1727 :Az építési jogok nem eladók! STR_1728 :Nem vásárolhatók meg az építési jogok... STR_1729 :A terület nem a park tulajdona! STR_1730 :{RED}Zárva -STR_1731 :{WHITE}{STRINGID} +STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Építés STR_1733 :Mód STR_1734 :{WINDOW_COLOUR_2}Körök száma: @@ -1135,6 +1136,8 @@ STR_1768 :Nem változtatható meg a lengések száma... STR_1769 :{WINDOW_COLOUR_2}Lengések száma: STR_1770 :{SMALLFONT}{BLACK}A teljes lengések száma STR_1771 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1773 :Csak egy élményfotó-szakasz engedélyezett játékonként +STR_1774 :Csak egy kábeles felvonószakasz engedélyezett játékonként STR_1777 :Játékok zenéje STR_1778 :{STRINGID} - - STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} Panda jelmez @@ -1230,6 +1233,8 @@ STR_1871 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COM STR_1873 :{WINDOW_COLOUR_2}Bevétel: {BLACK}{CURRENCY2DP} óránként STR_1874 :{WINDOW_COLOUR_2}Nyereség: {BLACK}{CURRENCY2DP} óránként STR_1875 :{BLACK} {SPRITE}{BLACK} {STRINGID} +STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}Játékok ellenőrzése +STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}Játékok javítása STR_1878 :{WINDOW_COLOUR_2}Ellenőrzés: STR_1879 :Minden 10. percben STR_1880 :Minden 20. percben @@ -1274,6 +1279,7 @@ STR_1920 :Nem tudod visszafizetni a kölcsönt! STR_1921 :{SMALLFONT}{BLACK}Új játék indítása STR_1922 :{SMALLFONT}{BLACK}Mentett játék folytatása STR_1924 :{SMALLFONT}{BLACK}Kilépés +STR_1925 :Nem helyezhető ide ember... STR_1926 :{SMALLFONT} STR_1927 :{YELLOW}{STRINGID} meghibásodott STR_1928 :{RED}{STRINGID} ütközött! @@ -1293,6 +1299,7 @@ STR_1941 :{SMALLFONT}{BLACK}A vendég által használt játékok STR_1942 :{SMALLFONT}{BLACK}A vendég pénzügyi információi STR_1943 :{SMALLFONT}{BLACK}A vendég legutóbbi gondolatai STR_1944 :{SMALLFONT}{BLACK}A vendégnél lévő dolgok +STR_1945 :{SMALLFONT}{BLACK}Az alkalmazott utasításai és beállításai STR_1946 :{SMALLFONT}{BLACK}A szórakoztató jelmezének kiválasztása STR_1947 :{SMALLFONT}{BLACK}A választott típusú alkalmazottak járőrözési területe és a legközelebbi alkalmazott megkeresése STR_1948 :{SMALLFONT}{BLACK}Új alkalmazott felvétele a kiválasztott munkakörbe @@ -1302,6 +1309,8 @@ STR_1951 :Parkérték grafikon STR_1952 :Nyereség grafikon STR_1953 :Marketing STR_1954 :Kutatás finanszírozása +STR_1955 :{WINDOW_COLOUR_2}Körök száma: +STR_1956 :{SMALLFONT}{BLACK}A pálya köreinek száma játékonként STR_1957 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_1958 :{COMMA16} STR_1959 :Nem változtatható meg a körök száma... @@ -1544,6 +1553,7 @@ STR_2210 :{SMALLFONT}{BLACK}A park mindeneseinek listája STR_2211 :{SMALLFONT}{BLACK}A park gépészeinek listája STR_2212 :{SMALLFONT}{BLACK}A park biztonsági őreinek lilistája STR_2213 :{SMALLFONT}{BLACK}A park szórakoztatóinak listája +STR_2214 :Szünet közben nem lehet építeni! STR_2215 :{STRINGID}{NEWLINE}({STRINGID}) STR_2216 :{WINDOW_COLOUR_2}{COMMA16}°C STR_2217 :{WINDOW_COLOUR_2}{COMMA16}°F @@ -1720,6 +1730,15 @@ STR_2396 :{BLACK}Az ételek, italok és szuvenírek utáni havi bevételed le STR_2397 :Nincs STR_2398 :A vendégek száma STR_2399 :A park értéke egy meghatározott időpontban +STR_2400 :Érezd jól magad +STR_2401 :Építsd meg a lehető legjobb játékot +STR_2402 :Építs 10 hullámvasutat +STR_2403 :Vendégek száma a parkban +STR_2404 :Havi bevétel a játékjegyekből +STR_2405 :Építs 10 meghatározott hosszú hullámvasuat +STR_2406 :Fejezd be 5 hullámvasút építését +STR_2407 :Fizesd vissza a kölcsönt és érj el egy meghatározott park értéket +STR_2408 :Havi nyereség ételből/szuvenírből STR_2409 :{WINDOW_COLOUR_2}Folyamatban lévő marketingkampányok STR_2410 :{BLACK}Nincs STR_2411 :{WINDOW_COLOUR_2}Rendelkezésre álló marketingkampányok @@ -1779,6 +1798,10 @@ STR_2474 :{SMALLFONT}{BLACK}Új vízi játékok kutatása STR_2475 :{SMALLFONT}{BLACK}Új boltok és bódék kutatása STR_2476 :{SMALLFONT}{BLACK}Új díszletek és témák kutatása STR_2477 :{SMALLFONT}{BLACK}A játék/épület üzemmódjának kiválasztása +STR_2478 :{SMALLFONT}{BLACK}Grafikon a sebesség időbeli alakulásáról +STR_2479 :{SMALLFONT}{BLACK}Grafikon a magasság időbeli alakulásáról +STR_2480 :{SMALLFONT}{BLACK}Grafikon a függőleges gyorsulás időbeli alakulásáról +STR_2481 :{SMALLFONT}{BLACK}Grafikon az oldalirányú gyorsulás időbeli alakulásáról STR_2482 :{SMALLFONT}{BLACK}Nyereség: {CURRENCY} hetente, Park értéke: {CURRENCY} STR_2483 :{WINDOW_COLOUR_2}Heti nyereség: {BLACK}+{CURRENCY2DP} STR_2484 :{WINDOW_COLOUR_2}Heti nyereség: {RED}{CURRENCY2DP} @@ -2286,6 +2309,11 @@ STR_3068 :Egyéb parkok STR_3070 :Lejtés vízszinthez STR_3071 :{WINDOW_COLOUR_2}Ugyanez az ár mindenhol a parkban STR_3072 :{SMALLFONT}{BLACK}Válaszd ki, hogy ezt az árat használják-e mindenhol a parkban +STR_3073 :{RED}FIGYELMEZTETÉS: A parkod értékelése 700 alá esett !{NEWLINE}Ha 4 héten belül nem növeled az értékelést, a parkod be lesz zárva +STR_3074 :{RED}FIGYELMEZTETÉS: A parkod értékelése még mindig 700 alatt van !{NEWLINE}3 heted van növelni az értékelést +STR_3075 :{RED}FIGYELMEZTETÉS: A parkod értékelése még mindig 700 alatt van !NEWLINE}Csak 2 heted van növelni az értékelést, vagy a parkod be lesz zárva +STR_3076 :{RED}VÉGSŐ FIGYELMEZTETÉS: A parkod értékelése még mindig 700 alatt van !{NEWLINE}Már csak 7 nap van, mielőtt a parkod be lesz zárva, hacsak nem növeled az értékelést +STR_3077 :{RED}BEZÁRÁSI ÉRTESÍTŐ: A parkod be lett zárva ! STR_3090 :{SMALLFONT}{BLACK}A bejárat, a kijárat és az állomás stílusának kiválasztása STR_3091 :Nem távolíthatod el ezt a szakaszt! STR_3092 :Nem mozgathatod vagy módosíthatod a játék állomását! @@ -2308,6 +2336,7 @@ STR_3109 :Megnyitás STR_3110 :{WINDOW_COLOUR_2}Térközszakaszok: {BLACK}{COMMA16} STR_3111 :{SMALLFONT}{BLACK}Az építéshez kattints a tervre STR_3112 :{SMALLFONT}{BLACK}Az átnevezéshez vagy a törléshez kattints a tervre +STR_3113 :Másik terv választása STR_3114 :{SMALLFONT}{BLACK}Vissza a tervek választásához STR_3115 :{SMALLFONT}{BLACK}A játékterv mentése STR_3116 :{SMALLFONT}{BLACK}A játékterv mentése (Nem lehet, amíg a játék nem lett letesztelve és nincsenek statisztikák generálva) @@ -2326,13 +2355,37 @@ STR_3128 :Játékterv mentése STR_3129 :Játékterv mentése díszletekkel STR_3130 :Mentés STR_3131 :Mégse +STR_3132 :{BLACK}Klikkelj azokra a díszeletelemekre, amelyeket a játéktervvel együtt el akarsz menteni… STR_3133 :Nem építhető lejtőre +STR_3134 :{RED}(A terv el nem érhető díszletet tartalmaz) +STR_3135 :{RED}(A járműterv nem elérhető - Befolyásolhatja a játék teljesítményét) +STR_3136 :Figyelmeztetés: A terv alternatív járműtípussal lesz megépítve és lehet, hogy nem az elvártnak megfelelően fog teljesíteni +STR_3137 :Közeli díszletek kiválasztása +STR_3138 :Kiválasztás törlése +STR_3139 :A kábeles felvonó nem tud üzemelni ebben a működési módban +STR_3140 :A kábeles felvonónak közvetlenül az állomás után kell kezdődnie STR_3142 :{WINDOW_COLOUR_2}Befogadóképesség: {BLACK}{STRINGID} STR_3143 :{SMALLFONT}{BLACK}Emberek megjelenítése a térképen STR_3144 :{SMALLFONT}{BLACK}Játékok és bódék megjelenítése a térképen STR_3162 :Nem lehet elég memóriát lefoglalni STR_3163 :Új adat telepítése: STR_3164 :{BLACK}{COMMA16} kiválasztva (maximum {COMMA16}) +STR_3167 :{WINDOW_COLOUR_2}Tartalmaz: {BLACK}{COMMA16} objektumot +STR_3169 :A következő objektumok adatai nem találhatóak: +STR_3170 :Nincs elég hely a grafika számára +STR_3171 :Túl sok ilyen típusú objektum van kiválasztva +STR_3172 :Előbb ki kell választani ezeket az objektumokat: {STRING} +STR_3173 :Az objektum jelenleg használatban van +STR_3174 :Az objektum egy másik objektumhoz szükséges +STR_3175 :Erre az objektumra mindig szükség van +STR_3176 :Az objektum nem választható ki +STR_3177 :Az objektum kiválasztása nem vonható vissza +STR_3178 :Legalább egy útobjektumot ki kell választani +STR_3179 :Legalább egy játék járművet/játékot ki kell választani +STR_3180 :Érvénytelen objektumkijelölés +STR_3181 :Objektum kiválasztás - {STRINGID} +STR_3182 :A parkbejárat típusát ki kell választani +STR_3183 :A víz típusát ki kell választani STR_3184 :Játékok és járműveik STR_3185 :Kis díszletek STR_3186 :Nagy díszletek @@ -2364,6 +2417,10 @@ STR_3212 :{POP16}{COMMA16} x {PUSH16}{COMMA16} STR_3213 :Nem csökkenthető tovább a térkép mérete STR_3214 :Nem növelhető tovább a térkép mérete STR_3215 :Túl közel van a térkép széléhez +STR_3217 :Birtokolt föld +STR_3218 :Birtokolt építési jogok +STR_3219 :Eladó föld +STR_3220 :Eladó építési jogok STR_3232 :Beállítások - pénzügyi STR_3233 :Beállítások - vendégek STR_3234 :Beállítások - park @@ -3123,6 +3180,36 @@ STR_6065 :Felhasználói tevékenységek naplózása STR_6066 :{SMALLFONT}{BLACK}Minden felhasználói tevékenységet naplóz a felhasználói mappádban lévő fájlokba STR_6067 :Szerver elindítva. STR_6068 :Szerver leállítva. +STR_6069 :{STRING} ki lett rúgva a szerverről {STRING} által. +STR_6070 :{STRING} a(z) '{STRING}' csoportba lett rakva {STRING} által. +STR_6071 :{STRING} egy új játékoscsoportot hozott létre '{STRING}' néven. +STR_6072 :{STRING} törölte a(z) '{String}' játékoscsoportot. +STR_6073 :{STRING} módosította a(z) '{String}' játékoscsoport engedélyeit. +STR_6074 :{STRING} megváltoztatta egy játékoscsoport nevét. Régi név: '{STRING}' / Új név: '{STRING}' +STR_6075 :{STRING} megváltoztatta az alap játékoscsoportot erre: '{String}'. +STR_6076 :{STRING} használt/bekapcsolt egy csalást: '{STRING}'. +STR_6077 :Pénz hozzáadása +STR_6078 :{STRING} új játékot hozott létre: '{STRING}'. +STR_6079 :{STRING} lerombolta a(z) '{STRING}' játékot. +STR_6080 :{STRING} megváltoztatta a(z) '{STRING}' játék kinézetét. +STR_6081 :{STRING} megváltoztatta a(z) '{STRING}' játék státuszát erre: zárva +STR_6082 :{STRING} megváltoztatta a(z) '{STRING}' játék státuszát erre: nyitva +STR_6083 :{STRING} megváltoztatta a(z) '{STRING}' játék státuszát erre: tesztelés +STR_6084 :{STRING} megváltoztatta '{STRING}' járműbeállításait. +STR_6085 :{STRING} megváltoztatta '{STRING}' játékbeállításait. +STR_6086 :{STRING} átnevezett egy játékot. Régi név: '{STRING}' / Új név: '{STRING}' +STR_6087 :{STRING} megváltoztatta a(z) '{STRING}' játék árát erre: {STRING} +STR_6088 :{STRING} megváltoztatta a(z) '{STRING}' játék másodlagos árát erre: {STRING} +STR_6089 :{STRING} átnevezte a parkot. Régi név: '{STRING}' / Új név: '{STRING}' +STR_6090 :{STRING} megnyitotta a parkot. +STR_6091 :{STRING} bezárta a parkot. +STR_6092 :{STRING} megváltoztatta a park belépési díját: {STRING} +STR_6093 :{STRING} egy új díszletet rakott le. +STR_6094 :{STRING} eltávolított egy díszletet. +STR_6095 :{STRING} módosított egy díszletet. +STR_6096 :{STRING} megváltoztatta egy tábla feliratát: '{STRING}'. +STR_6097 :{STRING} lerakta '{STRING}' játék egy pályaelemét. +STR_6098 :{STRING} eltávolított egy pályaelemet valamelyik játékról. STR_6099 :Kapcsolódtál a szerverhez. STR_6100 :Bontottad a kapcsolatot a szerverrel. STR_6101 :Nem csökken a játékok értéke @@ -3317,6 +3404,25 @@ STR_6305 :Többszálúság STR_6306 :{SMALLFONT}{BLACK}Kísérleti beállítás, mellyel bekapcsolható a több szálon történő megjelenítés, instabilitást okozhat. STR_6307 :Színséma: {BLACK}{STRINGID} STR_6308 :„{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Újracsatlakozás +STR_6310 :{WINDOW_COLOUR_2}Pozíció: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Következő: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(felület) +STR_6313 :(lejtő {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Úti cél: {BLACK}{INT32}, {INT32} tolerancia {INT32} +STR_6315 :{WINDOW_COLOUR_2}Útkeresési cél: {BLACK}{INT32}, {INT32}, {INT32} irány {INT32} +STR_6316 :{WINDOW_COLOUR_2}Útkeresési előzmények: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} irány {INT32} +STR_6318 :Hálózati szinkronizációs hiba észlelve.{NEWLINE}Naplófájl: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Blokkolófék zárva +STR_6320 :{WINDOW_COLOUR_2}Elpusztíthatatlan +STR_6321 :{WINDOW_COLOUR_2}Törött hozzáadott elem +STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} +STR_6323 :Szimuláció folyamatban +STR_6324 :Szimulálás +STR_6325 :{SMALLFONT}{BLACK}Játék/épület szimulálása +STR_6326 :{POP16}{POP16}{POP16}{STRINGID} nem szimulálható... + ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 948854bfc1..f828d8c7a3 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3778,6 +3778,10 @@ STR_6319 :{WINDOW_COLOUR_2}블록 브레이크 닫기 STR_6320 :{WINDOW_COLOUR_2}파괴 불가 STR_6321 :{WINDOW_COLOUR_2}기물 부서짐 STR_6322 :{WINDOW_COLOUR_2}스프라이트 ID: {BLACK}{INT32} +STR_6323 :가상 운행 중 +STR_6324 :가상 운행 +STR_6325 :{SMALLFONT}{BLACK}놀이기구 가상 운행 +STR_6326 :{POP16}{POP16}{POP16}{STRINGID}의 가상 운행을 시작할 수 없습니다... ############# From f98d027a14c29e450eead0f09977c9c90894a90c Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 6 Jun 2019 02:14:38 +0200 Subject: [PATCH 443/506] Fix #9377: accumulate a list of windows to close before actual closing --- src/openrct2/interface/Window.cpp | 76 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index beb7e4585e..00d487faec 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -259,16 +259,15 @@ void window_close(rct_window* window) */ void window_close_by_class(rct_windowclass cls) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) + std::vector closeList; + for (auto& w : g_window_list) { - auto itNext = std::next(it); - auto w = it->get(); if (w->classification == cls) - { - window_close(w); - } - it = itNext; + closeList.push_back(w.get()); + } + for (auto& w : closeList) + { + window_close(w); } } @@ -280,16 +279,15 @@ void window_close_by_class(rct_windowclass cls) */ void window_close_by_number(rct_windowclass cls, rct_windownumber number) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) + std::vector closeList; + for (auto& w : g_window_list) { - auto itNext = std::next(it); - auto w = it->get(); if (w->classification == cls && w->number == number) - { - window_close(w); - } - it = itNext; + closeList.push_back(w.get()); + } + for (auto& w : closeList) + { + window_close(w); } } @@ -342,7 +340,6 @@ void window_close_top() if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) if (gS6Info.editor_step != EDITOR_STEP_LANDSCAPE_EDITOR) return; - for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) { auto& w = (*it); @@ -363,31 +360,31 @@ void window_close_all() { window_close_by_class(WC_DROPDOWN); - for (auto it = g_window_list.begin(); it != g_window_list.end();) + std::vector closeList; + for (auto& w : g_window_list) { - auto itNext = std::next(it); - auto w = it->get(); if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - { - window_close(w); - } - it = itNext; + closeList.push_back(w.get()); + } + for (auto& w : closeList) + { + window_close(w); } } void window_close_all_except_class(rct_windowclass cls) { window_close_by_class(WC_DROPDOWN); - auto it = g_window_list.begin(); - while (it != g_window_list.end()) + + std::vector closeList; + for (auto& w : g_window_list) { - auto itNext = std::next(it); - auto w = it->get(); if (w->classification != cls && !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - { - window_close(w); - } - it = itNext; + closeList.push_back(w.get()); + } + for (auto& w : closeList) + { + window_close(w); } } @@ -396,16 +393,15 @@ void window_close_all_except_class(rct_windowclass cls) */ void window_close_all_except_flags(uint16_t flags) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) + std::vector closeList; + for (auto& w : g_window_list) { - auto itNext = std::next(it); - auto w = it->get(); if (!(w->flags & flags)) - { - window_close(w); - } - it = itNext; + closeList.push_back(w.get()); + } + for (auto& w : closeList) + { + window_close(w); } } From e0cf4763981595ce916f41d31ef481dfbb5846af Mon Sep 17 00:00:00 2001 From: aw20368 Date: Sat, 25 May 2019 09:53:11 -0400 Subject: [PATCH 444/506] Fix #8723 Use rotate_map_coordinates to rotate coordinate Added Rotate to CoordsXY, TileCoordsXY and used them to replace redundant rotation code. --- src/openrct2-ui/windows/RideConstruction.cpp | 80 ++--------- src/openrct2/paint/Paint.cpp | 17 +-- src/openrct2/ride/Ride.cpp | 139 +++++-------------- src/openrct2/ride/TrackDesign.cpp | 29 +--- src/openrct2/windows/_legacy.cpp | 27 +--- src/openrct2/world/Location.hpp | 75 ++++++++++ src/openrct2/world/Map.cpp | 25 +--- src/openrct2/world/TileInspector.cpp | 116 ++++------------ 8 files changed, 163 insertions(+), 345 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 408d789a8c..2373bb6b3e 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2325,26 +2325,7 @@ static void window_ride_construction_draw_track_piece( y = 0; } - int16_t tmp; - switch (trackDirection & 3) - { - case 1: - tmp = x; - x = y; - y = -tmp; - break; - case 2: - x = -x; - y = -y; - break; - case 3: - tmp = x; - x = -y; - y = tmp; - break; - case 0: - break; - } + rotate_map_coordinates(&x, &y, trackDirection & 3); // this is actually case 0, but the other cases all jump to it x = 4112 + (x / 2); y = 4112 + (y / 2); @@ -2385,7 +2366,6 @@ static void sub_6CBCE2( { Ride* ride; const rct_preview_track* trackBlock; - int32_t offsetX, offsetY; paint_session* session = paint_session_alloc(dpi, 0); trackDirection &= 3; @@ -2406,33 +2386,15 @@ static void sub_6CBCE2( while (trackBlock->index != 255) { auto quarterTile = trackBlock->var_08.Rotate(trackDirection); - switch (trackDirection) - { - default: - case 0: - offsetX = trackBlock->x; - offsetY = trackBlock->y; - break; - case 1: - offsetX = trackBlock->y; - offsetY = -trackBlock->x; - break; - case 2: - offsetX = -trackBlock->x; - offsetY = -trackBlock->y; - break; - case 3: - offsetX = -trackBlock->y; - offsetY = trackBlock->x; - break; - } - int32_t x = originX + offsetX; - int32_t y = originY + offsetY; + CoordsXY coords = { originX, originY }; + CoordsXY offsets = { trackBlock->x, trackBlock->y }; + coords += offsets.Rotate(trackDirection); + int32_t baseZ = (originZ + trackBlock->z) >> 3; int32_t clearanceZ = ((trackBlock->var_07 + RideData5[ride->type].clearance_height) >> 3) + baseZ + 4; - int32_t tileX = x >> 5; - int32_t tileY = y >> 5; + int32_t tileX = coords.x >> 5; + int32_t tileY = coords.y >> 5; // Replace map elements with temporary ones containing track _backupTileElementArrays[0] = map_get_first_element_at(tileX + 0, tileY + 0); @@ -2462,7 +2424,7 @@ static void sub_6CBCE2( _tempTrackTileElement.AsTrack()->SetRideIndex(rideIndex); // Draw this map tile - sub_68B2B7(session, x, y); + sub_68B2B7(session, coords.x, coords.y); // Restore map elements map_set_tile_elements(tileX + 0, tileY + 0, _backupTileElementArrays[0]); @@ -3341,35 +3303,17 @@ static void window_ride_construction_select_map_tiles( } const rct_preview_track* trackBlock; - int32_t offsetX, offsetY; trackBlock = get_track_def_from_ride(ride, trackType); trackDirection &= 3; gMapSelectionTiles.clear(); while (trackBlock->index != 255) { - switch (trackDirection) - { - default: - case 0: - offsetX = trackBlock->x; - offsetY = trackBlock->y; - break; - case 1: - offsetX = trackBlock->y; - offsetY = -trackBlock->x; - break; - case 2: - offsetX = -trackBlock->x; - offsetY = -trackBlock->y; - break; - case 3: - offsetX = -trackBlock->y; - offsetY = trackBlock->x; - break; - } + CoordsXY coords = { x, y }; + CoordsXY offsets = { trackBlock->x, trackBlock->y }; + coords += offsets.Rotate(trackDirection); - gMapSelectionTiles.push_back({ x + offsetX, y + offsetY }); + gMapSelectionTiles.push_back(coords); trackBlock++; } } diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index a8e01cd343..85fb54f74a 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -84,21 +84,8 @@ static paint_struct* sub_9819_c( paint_struct* ps = &session->NextFreePaintStruct->basic; ps->image_id = image_id; - switch (session->CurrentRotation) - { - case 0: - rotate_map_coordinates(&offset.x, &offset.y, 0); - break; - case 1: - rotate_map_coordinates(&offset.x, &offset.y, 3); - break; - case 2: - rotate_map_coordinates(&offset.x, &offset.y, 2); - break; - case 3: - rotate_map_coordinates(&offset.x, &offset.y, 1); - break; - } + uint8_t swappedRotation = (session->CurrentRotation * 3) % 4; // swaps 1 and 3 + rotate_map_coordinates(&offset.x, &offset.y, swappedRotation); offset.x += session->SpritePosition.x; offset.y += session->SpritePosition.y; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9345dc4adc..d3bd1bcd1f 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -613,33 +613,12 @@ bool track_block_get_next(CoordsXYE* input, CoordsXYE* output, int32_t* z, int32 int32_t OriginZ = input->element->base_height * 8; uint8_t rotation = input->element->GetDirection(); - switch (rotation) - { - case 0: - x += trackCoordinate->x; - x -= trackBlock->x; - y += trackCoordinate->y; - y -= trackBlock->y; - break; - case 1: - x += trackCoordinate->y; - x -= trackBlock->y; - y -= trackCoordinate->x; - y += trackBlock->x; - break; - case 2: - x -= trackCoordinate->x; - x += trackBlock->x; - y -= trackCoordinate->y; - y += trackBlock->y; - break; - case 3: - x -= trackCoordinate->y; - x += trackBlock->y; - y += trackCoordinate->x; - y -= trackBlock->x; - break; - } + + CoordsXY coords = { x, y }; + CoordsXY trackCoordOffset = { trackCoordinate->x, trackCoordinate->y }; + CoordsXY trackBlockOffset = { trackBlock->x, trackBlock->y }; + coords += trackCoordOffset.Rotate(rotation); + coords += trackBlockOffset.Rotate(direction_reverse(rotation)); OriginZ -= trackBlock->z; OriginZ += trackCoordinate->z_end; @@ -647,7 +626,7 @@ bool track_block_get_next(CoordsXYE* input, CoordsXYE* output, int32_t* z, int32 uint8_t directionStart = ((trackCoordinate->rotation_end + rotation) & TILE_ELEMENT_DIRECTION_MASK) | (trackCoordinate->rotation_end & (1 << 2)); - return track_block_get_next_from_zero(x, y, OriginZ, ride, directionStart, output, z, direction, false); + return track_block_get_next_from_zero(coords.x, coords.y, OriginZ, ride, directionStart, output, z, direction, false); } /** @@ -713,25 +692,12 @@ bool track_block_get_previous_from_zero( outTrackBeginEnd->begin_y = y; outTrackBeginEnd->end_x = x; outTrackBeginEnd->end_y = y; - switch (nextRotation & 3) - { - case 0: - outTrackBeginEnd->begin_x -= nextTrackCoordinate->x; - outTrackBeginEnd->begin_y -= nextTrackCoordinate->y; - break; - case 1: - outTrackBeginEnd->begin_x -= nextTrackCoordinate->y; - outTrackBeginEnd->begin_y += nextTrackCoordinate->x; - break; - case 2: - outTrackBeginEnd->begin_x += nextTrackCoordinate->x; - outTrackBeginEnd->begin_y += nextTrackCoordinate->y; - break; - case 3: - outTrackBeginEnd->begin_x += nextTrackCoordinate->y; - outTrackBeginEnd->begin_y -= nextTrackCoordinate->x; - break; - } + + CoordsXY coords = { outTrackBeginEnd->begin_x, outTrackBeginEnd->begin_y }; + CoordsXY offsets = { nextTrackCoordinate->x, nextTrackCoordinate->y }; + coords += offsets.Rotate(direction_reverse(nextRotation)); + outTrackBeginEnd->begin_x = coords.x; + outTrackBeginEnd->begin_y = coords.y; outTrackBeginEnd->begin_z = tileElement->base_height * 8; outTrackBeginEnd->begin_z += get_track_def_from_ride(ride, tileElement->AsTrack()->GetTrackType())->z @@ -772,25 +738,9 @@ bool track_block_get_previous(int32_t x, int32_t y, TileElement* tileElement, tr int32_t z = tileElement->base_height * 8; uint8_t rotation = tileElement->GetDirection(); - switch (rotation) - { - case 0: - x -= trackBlock->x; - y -= trackBlock->y; - break; - case 1: - x -= trackBlock->y; - y += trackBlock->x; - break; - case 2: - x += trackBlock->x; - y += trackBlock->y; - break; - case 3: - x += trackBlock->y; - y -= trackBlock->x; - break; - } + CoordsXY coords = { x, y }; + CoordsXY offsets = { trackBlock->x, trackBlock->y }; + coords += offsets.Rotate(direction_reverse(rotation)); z -= trackBlock->z; z += trackCoordinate->z_begin; @@ -798,7 +748,7 @@ bool track_block_get_previous(int32_t x, int32_t y, TileElement* tileElement, tr rotation = ((trackCoordinate->rotation_begin + rotation) & TILE_ELEMENT_DIRECTION_MASK) | (trackCoordinate->rotation_begin & (1 << 2)); - return track_block_get_previous_from_zero(x, y, z, ride, rotation, outTrackBeginEnd); + return track_block_get_previous_from_zero(coords.x, coords.y, z, ride, rotation, outTrackBeginEnd); } /** @@ -1299,56 +1249,29 @@ int32_t sub_6C683D( int32_t sequence = tileElement->AsTrack()->GetSequenceIndex(); uint8_t mapDirection = tileElement->GetDirection(); - switch (mapDirection) - { - case TILE_ELEMENT_DIRECTION_WEST: - *x -= trackBlock[sequence].x; - *y -= trackBlock[sequence].y; - break; - case TILE_ELEMENT_DIRECTION_NORTH: - *x -= trackBlock[sequence].y; - *y += trackBlock[sequence].x; - break; - case TILE_ELEMENT_DIRECTION_EAST: - *x += trackBlock[sequence].x; - *y += trackBlock[sequence].y; - break; - case TILE_ELEMENT_DIRECTION_SOUTH: - *x += trackBlock[sequence].y; - *y -= trackBlock[sequence].x; - break; - } + TileCoordsXY offsets = { trackBlock[sequence].x, trackBlock[sequence].y }; + TileCoordsXY newCoords = { *x, *y }; + newCoords += offsets.Rotate(direction_reverse(mapDirection)); + + *x = newCoords.x; + *y = newCoords.y; + *z -= trackBlock[sequence].z; int32_t start_x = *x, start_y = *y, start_z = *z; *z += trackBlock[0].z; for (int32_t i = 0; trackBlock[i].index != 0xFF; ++i) { - int32_t cur_x = start_x, cur_y = start_y, cur_z = start_z; - switch (mapDirection) - { - case TILE_ELEMENT_DIRECTION_WEST: - cur_x += trackBlock[i].x; - cur_y += trackBlock[i].y; - break; - case TILE_ELEMENT_DIRECTION_NORTH: - cur_x += trackBlock[i].y; - cur_y -= trackBlock[i].x; - break; - case TILE_ELEMENT_DIRECTION_EAST: - cur_x -= trackBlock[i].x; - cur_y -= trackBlock[i].y; - break; - case TILE_ELEMENT_DIRECTION_SOUTH: - cur_x -= trackBlock[i].y; - cur_y += trackBlock[i].x; - break; - } + TileCoordsXY cur = { start_x, start_y }; + int32_t cur_z = start_z; + offsets.x = trackBlock[i].x; + offsets.y = trackBlock[i].y; + cur += offsets.Rotate(mapDirection); cur_z += trackBlock[i].z; - map_invalidate_tile_full(cur_x, cur_y); + map_invalidate_tile_full(cur.x, cur.y); - tileElement = map_get_first_element_at(cur_x / 32, cur_y / 32); + tileElement = map_get_first_element_at(cur.x / 32, cur.y / 32); successTileElement = nullptr; do { diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 8a64473623..7d99cfc255 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -811,7 +811,7 @@ static bool TrackDesignPlaceSceneryElementGetPlaceZ(rct_td6_scenery_element* sce } static bool TrackDesignPlaceSceneryElement( - CoordsXY mapCoord, LocationXY8 tile, uint8_t mode, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) + CoordsXY mapCoord, uint8_t mode, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ) { if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0) { @@ -1101,31 +1101,14 @@ static int32_t track_design_place_all_scenery( for (rct_td6_scenery_element* scenery = scenery_start; scenery->scenery_object.end_flag != 0xFF; scenery++) { uint8_t rotation = _currentTrackPieceDirection; - LocationXY8 tile = { (uint8_t)(originX / 32), (uint8_t)(originY / 32) }; - switch (rotation & 3) - { - case TILE_ELEMENT_DIRECTION_WEST: - tile.x += scenery->x; - tile.y += scenery->y; - break; - case TILE_ELEMENT_DIRECTION_NORTH: - tile.x += scenery->y; - tile.y -= scenery->x; - break; - case TILE_ELEMENT_DIRECTION_EAST: - tile.x -= scenery->x; - tile.y -= scenery->y; - break; - case TILE_ELEMENT_DIRECTION_SOUTH: - tile.x -= scenery->y; - tile.y += scenery->x; - break; - } + TileCoordsXY tileCoords = { originX / 32, originY / 32 }; + TileCoordsXY offsets = { scenery->x, scenery->y }; + tileCoords += offsets.Rotate(rotation); - CoordsXY mapCoord = { tile.x * 32, tile.y * 32 }; + CoordsXY mapCoord = { tileCoords.x * 32, tileCoords.y * 32 }; track_design_update_max_min_coordinates(mapCoord.x, mapCoord.y, originZ); - if (!TrackDesignPlaceSceneryElement(mapCoord, tile, mode, scenery, rotation, originZ)) + if (!TrackDesignPlaceSceneryElement(mapCoord, mode, scenery, rotation, originZ)) { return 0; } diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index d55d6f7029..1576eee659 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -386,28 +386,11 @@ bool window_ride_construction_update_state( trackDirection |= 0x04; } - switch (trackDirection & 0x03) - { - case 0: - x -= trackCoordinates->x; - y -= trackCoordinates->y; - break; - - case 1: - x -= trackCoordinates->y; - y += trackCoordinates->x; - break; - - case 2: - x += trackCoordinates->x; - y += trackCoordinates->y; - break; - - case 3: - x += trackCoordinates->y; - y -= trackCoordinates->x; - break; - } + CoordsXY offsets = { trackCoordinates->x, trackCoordinates->y }; + CoordsXY coords = { x, y }; + coords += offsets.Rotate(direction_reverse(trackDirection)); + x = (uint16_t)coords.x; + y = (uint16_t)coords.y; } else { diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index f074a480e2..d3b5d84b65 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -70,6 +70,47 @@ struct CoordsXY , y(_y) { } + + CoordsXY& operator+=(const CoordsXY rhs) + { + x += rhs.x; + y += rhs.y; + return *this; + } + + CoordsXY& operator-=(const CoordsXY rhs) + { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + CoordsXY Rotate(int32_t direction) + { + CoordsXY rotatedCoords; + switch (direction & 3) + { + default: + case 0: + rotatedCoords.x = x; + rotatedCoords.y = y; + break; + case 1: + rotatedCoords.x = y; + rotatedCoords.y = -x; + break; + case 2: + rotatedCoords.x = -x; + rotatedCoords.y = -y; + break; + case 3: + rotatedCoords.x = -y; + rotatedCoords.y = x; + break; + } + + return rotatedCoords; + } }; struct TileCoordsXY @@ -91,6 +132,40 @@ struct TileCoordsXY y += rhs.y; return *this; } + TileCoordsXY& operator-=(const TileCoordsXY rhs) + { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + TileCoordsXY Rotate(int32_t direction) + { + TileCoordsXY rotatedCoords; + switch (direction & 3) + { + default: + case 0: + rotatedCoords.x = x; + rotatedCoords.y = y; + break; + case 1: + rotatedCoords.x = y; + rotatedCoords.y = -x; + break; + case 2: + rotatedCoords.x = -x; + rotatedCoords.y = -y; + break; + case 3: + rotatedCoords.x = -y; + rotatedCoords.y = x; + break; + } + + return rotatedCoords; + } + int32_t x = 0, y = 0; }; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 8117a00413..8f17ba2605 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2577,25 +2577,12 @@ TileElement* map_get_track_element_at_with_direction_from_ride( void map_offset_with_rotation(int16_t* x, int16_t* y, int16_t offsetX, int16_t offsetY, uint8_t rotation) { - switch (rotation & 3) - { - case TILE_ELEMENT_DIRECTION_WEST: - *x += offsetX; - *y += offsetY; - break; - case TILE_ELEMENT_DIRECTION_NORTH: - *x += offsetY; - *y -= offsetX; - break; - case TILE_ELEMENT_DIRECTION_EAST: - *x -= offsetX; - *y -= offsetY; - break; - case TILE_ELEMENT_DIRECTION_SOUTH: - *x -= offsetY; - *y += offsetX; - break; - } + TileCoordsXY offsets = { offsetX, offsetY }; + TileCoordsXY newCoords = { *x, *y }; + newCoords += offsets.Rotate(rotation); + + *x = (int16_t)newCoords.x; + *y = (int16_t)newCoords.y; } WallElement* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32_t direction) diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 630389d180..a8266a0cc6 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -763,59 +763,28 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el trackBlock += trackElement->AsTrack()->GetSequenceIndex(); uint8_t originDirection = trackElement->GetDirection(); - switch (originDirection) - { - case 0: - originX -= trackBlock->x; - originY -= trackBlock->y; - break; - case 1: - originX -= trackBlock->y; - originY += trackBlock->x; - break; - case 2: - originX += trackBlock->x; - originY += trackBlock->y; - break; - case 3: - originX += trackBlock->y; - originY -= trackBlock->x; - break; - } + CoordsXY offsets = { trackBlock->x, trackBlock->y }; + CoordsXY coords = { originX, originY }; + coords += offsets.Rotate(direction_reverse(originDirection)); + originX = (int16_t)coords.x; + originY = (int16_t)coords.y; originZ -= trackBlock->z; trackBlock = get_track_def_from_ride(ride, type); for (; trackBlock->index != 255; trackBlock++) { - int16_t elemX = originX, elemY = originY, elemZ = originZ; - - switch (originDirection) - { - case 0: - elemX += trackBlock->x; - elemY += trackBlock->y; - break; - case 1: - elemX += trackBlock->y; - elemY -= trackBlock->x; - break; - case 2: - elemX -= trackBlock->x; - elemY -= trackBlock->y; - break; - case 3: - elemX -= trackBlock->y; - elemY += trackBlock->x; - break; - } - + CoordsXY elem = { originX, originY }; + int16_t elemZ = originZ; + offsets.x = trackBlock->x; + offsets.y = trackBlock->y; + elem += offsets.Rotate(originDirection); elemZ += trackBlock->z; - map_invalidate_tile_full(elemX, elemY); + map_invalidate_tile_full(elem.x, elem.y); bool found = false; - TileElement* tileElement = map_get_first_element_at(elemX >> 5, elemY >> 5); + TileElement* tileElement = map_get_first_element_at(elem.x >> 5, elem.y >> 5); do { if (tileElement->base_height != elemZ / 8) @@ -845,8 +814,7 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el // track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is for when // you decrease the map size. - openrct2_assert( - map_get_surface_element_at({ elemX, elemY }) != nullptr, "No surface at %d,%d", elemX >> 5, elemY >> 5); + openrct2_assert(map_get_surface_element_at(elem) != nullptr, "No surface at %d,%d", elem.x >> 5, elem.y >> 5); // Keep? // invalidate_test_results(ride); @@ -896,59 +864,28 @@ int32_t tile_inspector_track_set_chain( trackBlock += trackElement->AsTrack()->GetSequenceIndex(); uint8_t originDirection = trackElement->GetDirection(); - switch (originDirection) - { - case 0: - originX -= trackBlock->x; - originY -= trackBlock->y; - break; - case 1: - originX -= trackBlock->y; - originY += trackBlock->x; - break; - case 2: - originX += trackBlock->x; - originY += trackBlock->y; - break; - case 3: - originX += trackBlock->y; - originY -= trackBlock->x; - break; - } + CoordsXY offsets = { trackBlock->x, trackBlock->y }; + CoordsXY coords = { originX, originY }; + coords += offsets.Rotate(direction_reverse(originDirection)); + originX = (int16_t)coords.x; + originY = (int16_t)coords.y; originZ -= trackBlock->z; trackBlock = get_track_def_from_ride(ride, type); for (; trackBlock->index != 255; trackBlock++) { - int16_t elemX = originX, elemY = originY, elemZ = originZ; - - switch (originDirection) - { - case 0: - elemX += trackBlock->x; - elemY += trackBlock->y; - break; - case 1: - elemX += trackBlock->y; - elemY -= trackBlock->x; - break; - case 2: - elemX -= trackBlock->x; - elemY -= trackBlock->y; - break; - case 3: - elemX -= trackBlock->y; - elemY += trackBlock->x; - break; - } - + CoordsXY elem = { originX, originY }; + int16_t elemZ = originZ; + offsets.x = trackBlock->x; + offsets.y = trackBlock->y; + elem += offsets.Rotate(originDirection); elemZ += trackBlock->z; - map_invalidate_tile_full(elemX, elemY); + map_invalidate_tile_full(elem.x, elem.y); bool found = false; - TileElement* tileElement = map_get_first_element_at(elemX >> 5, elemY >> 5); + TileElement* tileElement = map_get_first_element_at(elem.x >> 5, elem.y >> 5); do { if (tileElement->base_height != elemZ / 8) @@ -978,8 +915,7 @@ int32_t tile_inspector_track_set_chain( // track_remove returns here on failure, not sure when this would ever be hit. Only thing I can think of is for when // you decrease the map size. - openrct2_assert( - map_get_surface_element_at({ elemX, elemY }) != nullptr, "No surface at %d,%d", elemX >> 5, elemY >> 5); + openrct2_assert(map_get_surface_element_at(elem) != nullptr, "No surface at %d,%d", elem.x >> 5, elem.y >> 5); // Keep? // invalidate_test_results(ride); From 6cfe9f373f7c174059fa41f219c611e657321e4f Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Fri, 7 Jun 2019 04:00:23 +0000 Subject: [PATCH 445/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/nl-NL.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index f760ce9f56..37c67a8feb 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -3784,6 +3784,11 @@ STR_6318 :Netwerkdesynchronisatie gedetecteerd.{NEWLINE}Logbestand: {STRING} STR_6319 :{WINDOW_COLOUR_2}Blokrem is gesloten STR_6320 :{WINDOW_COLOUR_2}Mag niet worden verwijderd STR_6321 :{WINDOW_COLOUR_2}Straatmeubel is kapot +STR_6322 :{WINDOW_COLOUR_2}Sprite-id: {BLACK}{INT32} +STR_6323 :Simulatie +STR_6324 :Simuleren +STR_6325 :{SMALLFONT}{BLACK}Testrit simuleren +STR_6326 :Kan {POP16}{POP16}{POP16}{STRINGID} niet in simulatiemodus zetten... ############# # Scenarios # From 9bca783fffe40f29c60ce31143414e8c303d1ab8 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sat, 8 Jun 2019 04:00:21 +0000 Subject: [PATCH 446/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index 7cc54cc14e..fbd20194fa 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3790,6 +3790,10 @@ STR_6319 :{WINDOW_COLOUR_2}Uzavřený brzdný blok STR_6320 :{WINDOW_COLOUR_2}Nezničitelné STR_6321 :{WINDOW_COLOUR_2}Rozbitá část STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} +STR_6323 :Probíhá simulace +STR_6324 :Simulovat +STR_6325 :{SMALLFONT}{BLACK}Simulovat atrakci +STR_6326 :Nelze simulovat {POP16}{POP16}{POP16}{STRINGID}... ############################################################################### ## RCT2 Scenarios From f5ac98c1e21bb22051ede003b8d9ad9ba7b9d1e3 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Thu, 30 May 2019 11:30:29 +0200 Subject: [PATCH 447/506] Early out when context creation fails --- src/openrct2/interface/Screenshot.cpp | 256 +++++++++++++------------- 1 file changed, 130 insertions(+), 126 deletions(-) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 8e921cb9b0..c9e22efee6 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -469,139 +469,143 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption gOpenRCT2Headless = true; auto context = CreateContext(); - if (context->Initialise()) + if (!context->Initialise()) { - drawing_engine_init(); + std::puts("Failed to initialize context."); + return -1; + } - try + drawing_engine_init(); + + try + { + context->LoadParkFromFile(inputPath); + } + catch (const std::exception& e) + { + std::printf("%s\n", e.what()); + drawing_engine_dispose(); + return -1; + } + + gIntroState = INTRO_STATE_NONE; + gScreenFlags = SCREEN_FLAGS_PLAYING; + + int32_t mapSize = gMapSize; + if (resolutionWidth == 0 || resolutionHeight == 0) + { + resolutionWidth = (mapSize * 32 * 2) >> customZoom; + resolutionHeight = (mapSize * 32 * 1) >> customZoom; + + resolutionWidth += 8; + resolutionHeight += 128; + } + + rct_viewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = resolutionWidth; + viewport.height = resolutionHeight; + viewport.view_width = viewport.width; + viewport.view_height = viewport.height; + viewport.var_11 = 0; + viewport.flags = 0; + + if (customLocation) + { + if (centreMapX) + customX = (mapSize / 2) * 32 + 16; + if (centreMapY) + customY = (mapSize / 2) * 32 + 16; + + int32_t z = tile_element_height(customX, customY); + CoordsXYZ coords3d = { customX, customY, z }; + + CoordsXY coords2d = translate_3d_to_2d_with_z(customRotation, coords3d); + + viewport.view_x = coords2d.x - ((viewport.view_width << customZoom) / 2); + viewport.view_y = coords2d.y - ((viewport.view_height << customZoom) / 2); + viewport.zoom = customZoom; + gCurrentRotation = customRotation; + } + else + { + viewport.view_x = gSavedViewX - (viewport.view_width / 2); + viewport.view_y = gSavedViewY - (viewport.view_height / 2); + viewport.zoom = gSavedViewZoom; + gCurrentRotation = gSavedViewRotation; + } + + if (options->weather != 0) + { + if (options->weather < 1 || options->weather > 6) { - context->LoadParkFromFile(inputPath); - } - catch (const std::exception& e) - { - std::printf("%s\n", e.what()); + std::printf("Weather can only be set to an integer value from 1 till 6."); drawing_engine_dispose(); return -1; } - gIntroState = INTRO_STATE_NONE; - gScreenFlags = SCREEN_FLAGS_PLAYING; - - int32_t mapSize = gMapSize; - if (resolutionWidth == 0 || resolutionHeight == 0) - { - resolutionWidth = (mapSize * 32 * 2) >> customZoom; - resolutionHeight = (mapSize * 32 * 1) >> customZoom; - - resolutionWidth += 8; - resolutionHeight += 128; - } - - rct_viewport viewport; - viewport.x = 0; - viewport.y = 0; - viewport.width = resolutionWidth; - viewport.height = resolutionHeight; - viewport.view_width = viewport.width; - viewport.view_height = viewport.height; - viewport.var_11 = 0; - viewport.flags = 0; - - if (customLocation) - { - if (centreMapX) - customX = (mapSize / 2) * 32 + 16; - if (centreMapY) - customY = (mapSize / 2) * 32 + 16; - - int32_t z = tile_element_height(customX, customY); - CoordsXYZ coords3d = { customX, customY, z }; - - CoordsXY coords2d = translate_3d_to_2d_with_z(customRotation, coords3d); - - viewport.view_x = coords2d.x - ((viewport.view_width << customZoom) / 2); - viewport.view_y = coords2d.y - ((viewport.view_height << customZoom) / 2); - viewport.zoom = customZoom; - gCurrentRotation = customRotation; - } - else - { - viewport.view_x = gSavedViewX - (viewport.view_width / 2); - viewport.view_y = gSavedViewY - (viewport.view_height / 2); - viewport.zoom = gSavedViewZoom; - gCurrentRotation = gSavedViewRotation; - } - - if (options->weather != 0) - { - if (options->weather < 1 || options->weather > 6) - { - std::printf("Weather can only be set to an integer value from 1 till 6."); - drawing_engine_dispose(); - return -1; - } - - uint8_t customWeather = options->weather - 1; - climate_force_weather(customWeather); - } - - // Ensure sprites appear regardless of rotation - reset_all_sprite_quadrant_placements(); - - rct_drawpixelinfo dpi; - dpi.x = 0; - dpi.y = 0; - dpi.width = resolutionWidth; - dpi.height = resolutionHeight; - dpi.pitch = 0; - dpi.zoom_level = 0; - dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); - dpi.DrawingEngine = context->GetDrawingEngine(); - - if (options->hide_guests) - { - viewport.flags |= VIEWPORT_FLAG_INVISIBLE_PEEPS; - } - - if (options->hide_sprites) - { - viewport.flags |= VIEWPORT_FLAG_INVISIBLE_SPRITES; - } - - if (options->mowed_grass) - { - CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); - } - - if (options->clear_grass || options->tidy_up_park) - { - CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); - } - - if (options->water_plants || options->tidy_up_park) - { - CheatsSet(CheatType::WaterPlants); - } - - if (options->fix_vandalism || options->tidy_up_park) - { - CheatsSet(CheatType::FixVandalism); - } - - if (options->remove_litter || options->tidy_up_park) - { - CheatsSet(CheatType::RemoveLitter); - } - - viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); - - rct_palette renderedPalette; - screenshot_get_rendered_palette(&renderedPalette); - - WriteDpiToFile(outputPath, &dpi, renderedPalette); - - free(dpi.bits); - drawing_engine_dispose(); + uint8_t customWeather = options->weather - 1; + climate_force_weather(customWeather); } + + // Ensure sprites appear regardless of rotation + reset_all_sprite_quadrant_placements(); + + rct_drawpixelinfo dpi; + dpi.x = 0; + dpi.y = 0; + dpi.width = resolutionWidth; + dpi.height = resolutionHeight; + dpi.pitch = 0; + dpi.zoom_level = 0; + dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); + dpi.DrawingEngine = context->GetDrawingEngine(); + + if (options->hide_guests) + { + viewport.flags |= VIEWPORT_FLAG_INVISIBLE_PEEPS; + } + + if (options->hide_sprites) + { + viewport.flags |= VIEWPORT_FLAG_INVISIBLE_SPRITES; + } + + if (options->mowed_grass) + { + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); + } + + if (options->clear_grass || options->tidy_up_park) + { + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); + } + + if (options->water_plants || options->tidy_up_park) + { + CheatsSet(CheatType::WaterPlants); + } + + if (options->fix_vandalism || options->tidy_up_park) + { + CheatsSet(CheatType::FixVandalism); + } + + if (options->remove_litter || options->tidy_up_park) + { + CheatsSet(CheatType::RemoveLitter); + } + + viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); + + rct_palette renderedPalette; + screenshot_get_rendered_palette(&renderedPalette); + + WriteDpiToFile(outputPath, &dpi, renderedPalette); + + free(dpi.bits); + drawing_engine_dispose(); + return 1; } From bffc012d16e5ccb6cfc5f00e92796b276a46f7f6 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Thu, 30 May 2019 14:34:20 +0200 Subject: [PATCH 448/506] Implement #1260: --transparent switch for screenshot command --- src/openrct2/cmdline/ScreenshotCommands.cpp | 1 + src/openrct2/interface/Screenshot.cpp | 7 +++++++ src/openrct2/interface/Screenshot.h | 1 + src/openrct2/interface/Viewport.h | 1 + src/openrct2/paint/tile_element/Paint.TileElement.cpp | 4 ++-- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/openrct2/cmdline/ScreenshotCommands.cpp b/src/openrct2/cmdline/ScreenshotCommands.cpp index a0ca954873..c0e8725ab7 100644 --- a/src/openrct2/cmdline/ScreenshotCommands.cpp +++ b/src/openrct2/cmdline/ScreenshotCommands.cpp @@ -24,6 +24,7 @@ static constexpr const CommandLineOptionDefinition ScreenshotOptionsDef[] { CMDLINE_TYPE_SWITCH, &options.fix_vandalism, NAC, "fix-vandalism", "fix vandalism for the screenshot" }, { CMDLINE_TYPE_SWITCH, &options.remove_litter, NAC, "remove-litter", "remove litter for the screenshot" }, { CMDLINE_TYPE_SWITCH, &options.tidy_up_park, NAC, "tidy-up-park", "clear grass, water plants, fix vandalism and remove litter" }, + { CMDLINE_TYPE_SWITCH, &options.transparent, NAC, "transparent", "make the background transparent" }, OptionTableEnd }; diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index c9e22efee6..0a4bdd176a 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -562,6 +562,8 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); dpi.DrawingEngine = context->GetDrawingEngine(); + std::memset(dpi.bits, PALETTE_INDEX_0, dpi.width * dpi.height); + if (options->hide_guests) { viewport.flags |= VIEWPORT_FLAG_INVISIBLE_PEEPS; @@ -597,6 +599,11 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption CheatsSet(CheatType::RemoveLitter); } + if (options->transparent) + { + viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND; + } + viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); rct_palette renderedPalette; diff --git a/src/openrct2/interface/Screenshot.h b/src/openrct2/interface/Screenshot.h index 8e0b3c60ab..f0e29bf8ba 100644 --- a/src/openrct2/interface/Screenshot.h +++ b/src/openrct2/interface/Screenshot.h @@ -28,6 +28,7 @@ struct ScreenshotOptions bool fix_vandalism = false; bool remove_litter = false; bool tidy_up_park = false; + bool transparent = false; }; void screenshot_check(); diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index 8c0ebac2e4..ec5a567c68 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -46,6 +46,7 @@ enum VIEWPORT_FLAG_SEETHROUGH_PATHS = (1 << 16), VIEWPORT_FLAG_CLIP_VIEW = (1 << 17), VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1 << 18), + VIEWPORT_FLAG_TRANSPARENT_BACKGROUND = (1 << 19), }; enum diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index 0632f8f7c0..baab66d438 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -57,7 +57,7 @@ void tile_element_paint_setup(paint_session* session, int32_t x, int32_t y) sub_68B3FB(session, x, y); } - else + else if (!(session->ViewFlags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND)) { blank_tiles_paint(session, x, y); } @@ -78,7 +78,7 @@ void sub_68B2B7(paint_session* session, int32_t x, int32_t y) sub_68B3FB(session, x, y); } - else + else if (!(session->ViewFlags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND)) { blank_tiles_paint(session, x, y); } From 5418eb6e3460736cec94d7faf9ac9e9b1b2608b3 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Thu, 30 May 2019 16:37:32 +0200 Subject: [PATCH 449/506] Add transparency setting to options window --- data/language/en-GB.txt | 2 ++ distribution/changelog.txt | 1 + src/openrct2-ui/windows/Options.cpp | 19 ++++++++++++++----- src/openrct2/config/Config.cpp | 2 ++ src/openrct2/config/Config.h | 1 + src/openrct2/interface/Screenshot.cpp | 6 ++++++ src/openrct2/localisation/StringIds.h | 3 +++ 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 2afccea9a9..d4841c26c4 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3774,6 +3774,8 @@ STR_6323 :Simulating STR_6324 :Simulate STR_6325 :{SMALLFONT}{BLACK}Simulate ride/attraction STR_6326 :Can't simulate {POP16}{POP16}{POP16}{STRINGID}... +STR_6327 :Transparent background for giant screenshots +STR_6328 :{SMALLFONT}{BLACK}With this option enabled, giant screenshots will have a transparent background instead of the default black colour. ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b72053ac31..8889f4e270 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.2.2+ (in development) ------------------------------------------------------------------------ - Feature: [#485] Rides can now be simulated with ghost trains during construction. +- Feature: [#1260] Option for making giant screenshots have a transparent background. - Feature: [#2339] Find local servers automatically when fetching servers. - Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker. - Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies. diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index 0392859bc7..946f377da4 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -97,6 +97,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_GRIDLINES_CHECKBOX, WIDX_UPPER_CASE_BANNERS_CHECKBOX, WIDX_SHOW_GUEST_PURCHASES_CHECKBOX, + WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX, WIDX_VIRTUAL_FLOOR_LABEL, WIDX_VIRTUAL_FLOOR, WIDX_VIRTUAL_FLOOR_DROPDOWN, @@ -245,16 +246,17 @@ static rct_widget window_options_display_widgets[] = { static rct_widget window_options_rendering_widgets[] = { MAIN_OPTIONS_WIDGETS, #define FRAME_RENDERING_START 53 - { WWT_GROUPBOX, 1, 5, 304, FRAME_RENDERING_START + 0, FRAME_RENDERING_START + 92, STR_RENDERING_GROUP, STR_NONE }, // Rendering group + { WWT_GROUPBOX, 1, 5, 304, FRAME_RENDERING_START + 0, FRAME_RENDERING_START + 107, STR_RENDERING_GROUP, STR_NONE }, // Rendering group { WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 15, FRAME_RENDERING_START + 26, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP }, // Landscape smoothing { WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 30, FRAME_RENDERING_START + 41, STR_GRIDLINES, STR_GRIDLINES_TIP }, // Gridlines { WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 45, FRAME_RENDERING_START + 56, STR_UPPERCASE_BANNERS, STR_UPPERCASE_BANNERS_TIP }, // Uppercase banners { WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 60, FRAME_RENDERING_START + 71, STR_SHOW_GUEST_PURCHASES, STR_SHOW_GUEST_PURCHASES_TIP }, // Guest purchases - { WWT_LABEL, 1, 10, 290, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_VIRTUAL_FLOOR_STYLE, STR_NONE }, // Virtual floor - { WWT_DROPDOWN, 1, 155, 299, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_NONE, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown - { WWT_BUTTON, 1, 288, 298, FRAME_RENDERING_START + 76, FRAME_RENDERING_START + 85, STR_DROPDOWN_GLYPH, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown + { WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_TRANSPARENT_SCREENSHOT, STR_TRANSPARENT_SCREENSHOT_TIP }, // Transparent screenshot + { WWT_LABEL, 1, 10, 290, FRAME_RENDERING_START + 90, FRAME_RENDERING_START + 101, STR_VIRTUAL_FLOOR_STYLE, STR_NONE }, // Virtual floor + { WWT_DROPDOWN, 1, 155, 299, FRAME_RENDERING_START + 90, FRAME_RENDERING_START + 101, STR_NONE, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown + { WWT_BUTTON, 1, 288, 298, FRAME_RENDERING_START + 91, FRAME_RENDERING_START + 100, STR_DROPDOWN_GLYPH, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown #undef FRAME_RENDERING_START -#define FRAME_EFFECTS_START 148 +#define FRAME_EFFECTS_START 163 { WWT_GROUPBOX, 1, 5, 304, FRAME_EFFECTS_START + 0, FRAME_EFFECTS_START + 78, STR_EFFECTS_GROUP, STR_NONE }, // Rendering group { WWT_CHECKBOX, 1, 10, 290, FRAME_EFFECTS_START + 15, FRAME_EFFECTS_START + 26, STR_CYCLE_DAY_NIGHT, STR_CYCLE_DAY_NIGHT_TIP }, // Cycle day-night { WWT_CHECKBOX, 1, 25, 290, FRAME_EFFECTS_START + 30, FRAME_EFFECTS_START + 41, STR_ENABLE_LIGHTING_EFFECTS, STR_ENABLE_LIGHTING_EFFECTS_TIP }, // Enable light fx @@ -536,6 +538,7 @@ static uint64_t window_options_page_enabled_widgets[] = { (1 << WIDX_GRIDLINES_CHECKBOX) | (1 << WIDX_UPPER_CASE_BANNERS_CHECKBOX) | (1 << WIDX_SHOW_GUEST_PURCHASES_CHECKBOX) | + (1 << WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX) | (1 << WIDX_VIRTUAL_FLOOR) | (1 << WIDX_VIRTUAL_FLOOR_DROPDOWN) | (1 << WIDX_DAY_NIGHT_CHECKBOX) | @@ -764,6 +767,11 @@ static void window_options_mouseup(rct_window* w, rct_widgetindex widgetIndex) config_save_default(); window_invalidate(w); break; + case WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX: + gConfigGeneral.transparent_screenshot ^= 1; + config_save_default(); + window_invalidate(w); + break; } break; @@ -1731,6 +1739,7 @@ static void window_options_invalidate(rct_window* w) widget_set_checkbox_value(w, WIDX_GRIDLINES_CHECKBOX, gConfigGeneral.always_show_gridlines); widget_set_checkbox_value(w, WIDX_DAY_NIGHT_CHECKBOX, gConfigGeneral.day_night_cycle); widget_set_checkbox_value(w, WIDX_SHOW_GUEST_PURCHASES_CHECKBOX, gConfigGeneral.show_guest_purchases); + widget_set_checkbox_value(w, WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX, gConfigGeneral.transparent_screenshot); widget_set_checkbox_value(w, WIDX_UPPER_CASE_BANNERS_CHECKBOX, gConfigGeneral.upper_case_banners); rct_string_id VirtualFloorStyleStrings[] = { STR_VIRTUAL_FLOOR_STYLE_DISABLED, STR_VIRTUAL_FLOOR_STYLE_TRANSPARENT, diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 34162c30e3..66db158fb4 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -208,6 +208,7 @@ namespace Config model->show_guest_purchases = reader->GetBoolean("show_guest_purchases", false); model->show_real_names_of_guests = reader->GetBoolean("show_real_names_of_guests", true); model->allow_early_completion = reader->GetBoolean("allow_early_completion", false); + model->transparent_screenshot = reader->GetBoolean("transparent_screenshot", false); } } @@ -281,6 +282,7 @@ namespace Config writer->WriteBoolean("show_real_names_of_guests", model->show_real_names_of_guests); writer->WriteBoolean("allow_early_completion", model->allow_early_completion); writer->WriteEnum("virtual_floor_style", model->virtual_floor_style, Enum_VirtualFloorStyle); + writer->WriteBoolean("transparent_screenshot", model->transparent_screenshot); } static void ReadInterface(IIniReader* reader) diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 790982c544..8274ec4fbb 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -46,6 +46,7 @@ struct GeneralConfiguration bool render_weather_gloom; bool disable_lightning_effect; bool show_guest_purchases; + bool transparent_screenshot; // Localisation int32_t language; diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 0a4bdd176a..6cdaf49e18 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -275,6 +275,12 @@ void screenshot_giant() dpi.zoom_level = 0; dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height); + if (gConfigGeneral.transparent_screenshot) + { + std::memset(dpi.bits, PALETTE_INDEX_0, dpi.width * dpi.height); + viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND; + } + auto drawingEngine = std::make_unique(GetContext()->GetUiContext()); dpi.DrawingEngine = drawingEngine.get(); diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index d6e2388c42..fa2a3c6ce8 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3962,6 +3962,9 @@ enum STR_SIMULATE_RIDE_TIP = 6325, STR_CANT_SIMULATE = 6326, + STR_TRANSPARENT_SCREENSHOT = 6327, + STR_TRANSPARENT_SCREENSHOT_TIP = 6328, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; From e2d7b2cf03b41008deeac0a67afa54ac715a1ac5 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Thu, 30 May 2019 17:21:43 +0200 Subject: [PATCH 450/506] Use new setting in screenshot command too --- src/openrct2/interface/Screenshot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 6cdaf49e18..960752787c 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -605,7 +605,7 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption CheatsSet(CheatType::RemoveLitter); } - if (options->transparent) + if (options->transparent || gConfigGeneral.transparent_screenshot) { viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND; } From b3ed5b0cc11815edf480f31daadf8a265fccb111 Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Sun, 9 Jun 2019 00:44:33 +0200 Subject: [PATCH 451/506] Make giant screenshots transparent by default --- src/openrct2/config/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 66db158fb4..626b907e76 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -208,7 +208,7 @@ namespace Config model->show_guest_purchases = reader->GetBoolean("show_guest_purchases", false); model->show_real_names_of_guests = reader->GetBoolean("show_real_names_of_guests", true); model->allow_early_completion = reader->GetBoolean("allow_early_completion", false); - model->transparent_screenshot = reader->GetBoolean("transparent_screenshot", false); + model->transparent_screenshot = reader->GetBoolean("transparent_screenshot", true); } } From 7478e13e61905fdc00da57c1e372acd72f4ccc5b Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 9 Jun 2019 11:35:42 +0200 Subject: [PATCH 452/506] Add suffix constant to avoid shifting too many bits (#9389) Since WIDX_SCENERY_BUILD_CLUSTER_BUTTON is 31, add suffix ULL to avoid shifting 1 (which is an int and 4 bytes on most systems) 31 bits which is technically undefined behaviour. This is already done in the shift at line 463. Detected by the help of cppcheck. --- src/openrct2-ui/windows/Scenery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 04a2a66e35..3a1db09df6 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -970,7 +970,7 @@ void window_scenery_invalidate(rct_window* w) if (gWindowSceneryEyedropperEnabled) w->pressed_widgets |= (1 << WIDX_SCENERY_EYEDROPPER_BUTTON); if (gWindowSceneryClusterEnabled == 1) - w->pressed_widgets |= (1 << WIDX_SCENERY_BUILD_CLUSTER_BUTTON); + w->pressed_widgets |= (1ULL << WIDX_SCENERY_BUILD_CLUSTER_BUTTON); window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_EMPTY; window_scenery_widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WWT_EMPTY; From 6f0298deb3db0f98faddc67b6ebd6ee04b261076 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 9 Jun 2019 10:55:41 +0100 Subject: [PATCH 453/506] Refactor ride measurement storage --- src/openrct2-ui/windows/Ride.cpp | 16 +- src/openrct2/actions/RideCreateAction.hpp | 2 +- src/openrct2/actions/RideDemolishAction.hpp | 7 +- src/openrct2/actions/RideSetStatus.hpp | 2 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/rct1/RCT1.h | 6 +- src/openrct2/rct1/S4Importer.cpp | 32 ++- src/openrct2/rct12/RCT12.h | 19 ++ src/openrct2/rct2/RCT2.h | 2 +- src/openrct2/rct2/S6Exporter.cpp | 58 ++++- src/openrct2/rct2/S6Exporter.h | 2 + src/openrct2/rct2/S6Importer.cpp | 35 ++- src/openrct2/ride/Ride.cpp | 233 +++++++------------- src/openrct2/ride/Ride.h | 48 ++-- src/openrct2/ride/TrackDesign.cpp | 1 + src/openrct2/ride/Vehicle.cpp | 61 +++-- src/openrct2/ride/Vehicle.h | 8 +- src/openrct2/scenario/Scenario.h | 2 +- test/testpaint/TestPaint.cpp | 4 +- 19 files changed, 287 insertions(+), 253 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 79dbf87ed9..115827caa5 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -5880,7 +5880,6 @@ static void window_ride_graphs_mousedown(rct_window* w, rct_widgetindex widgetIn static void window_ride_graphs_update(rct_window* w) { rct_widget* widget; - rct_ride_measurement* measurement; int32_t x; w->frame_no++; @@ -5896,7 +5895,8 @@ static void window_ride_graphs_update(rct_window* w) auto ride = get_ride(w->number); if (ride != nullptr) { - measurement = ride_get_measurement(ride, nullptr); + RideMeasurement* measurement{}; + std::tie(measurement, std::ignore) = ride_get_measurement(ride); x = measurement == nullptr ? 0 : measurement->current_item - (((widget->right - widget->left) / 4) * 3); } } @@ -5911,8 +5911,6 @@ static void window_ride_graphs_update(rct_window* w) */ static void window_ride_graphs_scrollgetheight(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) { - rct_ride_measurement* measurement; - window_event_invalidate_call(w); // Set minimum size @@ -5922,7 +5920,8 @@ static void window_ride_graphs_scrollgetheight(rct_window* w, int32_t scrollInde auto ride = get_ride(w->number); if (ride != nullptr) { - measurement = ride_get_measurement(ride, nullptr); + RideMeasurement* measurement{}; + std::tie(measurement, std::ignore) = ride_get_measurement(ride); if (measurement != nullptr) { *width = std::max(*width, measurement->num_items); @@ -5950,8 +5949,7 @@ static void window_ride_graphs_tooltip(rct_window* w, rct_widgetindex widgetInde auto ride = get_ride(w->number); if (ride != nullptr) { - rct_string_id message; - auto measurement = ride_get_measurement(ride, &message); + auto [measurement, message] = ride_get_measurement(ride); if (measurement != nullptr && (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING)) { set_format_arg(4, uint16_t, measurement->vehicle_index + 1); @@ -6053,11 +6051,11 @@ static void window_ride_graphs_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi auto widget = &window_ride_graphs_widgets[WIDX_GRAPH]; auto stringId = STR_NONE; - rct_ride_measurement* measurement{}; + RideMeasurement* measurement{}; auto ride = get_ride(w->number); if (ride != nullptr) { - measurement = ride_get_measurement(ride, &stringId); + std::tie(measurement, stringId) = ride_get_measurement(ride); } if (measurement == nullptr) { diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 8919268d04..2c0e195428 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -186,7 +186,7 @@ public: ride->lift_hill_speed = RideLiftData[ride->type].minimum_speed; - ride->measurement_index = 255; + ride->measurement = {}; ride->excitement = (ride_rating)-1; ride->cur_num_customers = 0; ride->num_customers_timeout = 0; diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 73562abf3b..1d8410f50c 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -229,10 +229,6 @@ private: } } - user_string_free(ride->name); - ride->type = RIDE_TYPE_NULL; - gParkValue = GetContext()->GetGameState()->GetPark().CalculateParkValue(); - auto res = std::make_unique(); res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; res->Cost = refundPrice; @@ -246,6 +242,9 @@ private: res->Position = { x, y, z }; } + ride->Delete(); + gParkValue = GetContext()->GetGameState()->GetPark().CalculateParkValue(); + // Close windows related to the demolished ride if (!(GetFlags() & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED)) { diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index bcf3245ba1..b3dc025048 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -212,7 +212,7 @@ public: ride->status = _status; ride->current_issues = 0; ride->last_issue_time = 0; - ride_get_measurement(ride, nullptr); + ride_get_measurement(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; window_invalidate_by_number(WC_RIDE, _rideIndex); break; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index cdb314d5c9..90ed7a0a8a 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 "37" +#define NETWORK_STREAM_VERSION "38" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index 587da297f9..372eeef042 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -428,8 +428,8 @@ struct rct1_peep : RCT12SpriteBase uint8_t pad_C4; union { - uint8_t staff_id; // 0xC5 - ride_id_t guest_heading_to_ride_id; // 0xC5 + uint8_t staff_id; // 0xC5 + uint8_t guest_heading_to_ride_id; // 0xC5 }; union { @@ -681,7 +681,7 @@ struct rct1_s4 uint32_t unk_1CADCA; uint16_t unk_1CADCE; uint8_t unk_1CADD0[116]; - rct_ride_measurement ride_measurements[8]; + RCT12RideMeasurement ride_measurements[8]; uint32_t next_guest_index; uint16_t game_counter_5; uint8_t patrol_areas[(RCT1_MAX_STAFF + RCT12_STAFF_TYPE_COUNT) * RCT12_PATROL_AREA_SIZE]; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 277ac94919..094da3a572 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -952,7 +952,6 @@ private: dst->sheltered_eighths = src->num_inversions >> 5; dst->boat_hire_return_direction = src->boat_hire_return_direction; dst->boat_hire_return_position = src->boat_hire_return_position; - dst->measurement_index = src->data_logging_index; dst->chairlift_bullwheel_rotation = src->chairlift_bullwheel_rotation; for (int i = 0; i < 2; i++) { @@ -1108,23 +1107,32 @@ private: void ImportRideMeasurements() { - for (int32_t i = 0; i < MAX_RIDE_MEASUREMENTS; i++) + for (const auto& src : _s4.ride_measurements) { - rct_ride_measurement* dst = get_ride_measurement(i); - rct_ride_measurement* src = &_s4.ride_measurements[i]; - ImportRideMeasurement(dst, src); + if (src.ride_index != RCT12_RIDE_ID_NULL) + { + auto ride = get_ride(src.ride_index); + ride->measurement = std::make_unique(); + ride->measurement->ride = ride; + ImportRideMeasurement(*ride->measurement, src); + } } } - void ImportRideMeasurement(rct_ride_measurement* dst, rct_ride_measurement* src) + void ImportRideMeasurement(RideMeasurement& dst, const RCT12RideMeasurement& src) { - *dst = *src; - for (int32_t i = 0; i < RIDE_MEASUREMENT_MAX_ITEMS; i++) + dst.flags = src.flags; + dst.last_use_tick = src.last_use_tick; + dst.num_items = src.num_items; + dst.current_item = src.current_item; + dst.vehicle_index = src.vehicle_index; + dst.current_station = src.current_station; + for (size_t i = 0; i < std::size(src.velocity); i++) { - dst->velocity[i] /= 2; - dst->altitude[i] /= 2; - dst->vertical[i] /= 2; - dst->lateral[i] /= 2; + dst.velocity[i] = src.velocity[i] / 2; + dst.altitude[i] = src.altitude[i] / 2; + dst.vertical[i] = src.vertical[i] / 2; + dst.lateral[i] = src.lateral[i] / 2; } } diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index d355722fe8..e93b7f2622 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -39,6 +39,9 @@ #define RCT12_PEEP_MAX_THOUGHTS 5 +#define RCT12_RIDE_ID_NULL 255 +#define RCT12_RIDE_MEASUREMENT_MAX_ITEMS 4800 + constexpr uint16_t const RCT12_MAX_INVERSIONS = 31; constexpr uint16_t const RCT12_MAX_GOLF_HOLES = 31; constexpr uint16_t const RCT12_MAX_HELICES = 31; @@ -502,4 +505,20 @@ struct RCT12PeepThought }; assert_struct_size(RCT12PeepThought, 4); +struct RCT12RideMeasurement +{ + uint8_t ride_index; // 0x0000 + uint8_t flags; // 0x0001 + uint32_t last_use_tick; // 0x0002 + uint16_t num_items; // 0x0006 + uint16_t current_item; // 0x0008 + uint8_t vehicle_index; // 0x000A + uint8_t current_station; // 0x000B + int8_t vertical[RCT12_RIDE_MEASUREMENT_MAX_ITEMS]; // 0x000C + int8_t lateral[RCT12_RIDE_MEASUREMENT_MAX_ITEMS]; // 0x12CC + uint8_t velocity[RCT12_RIDE_MEASUREMENT_MAX_ITEMS]; // 0x258C + uint8_t altitude[RCT12_RIDE_MEASUREMENT_MAX_ITEMS]; // 0x384C +}; +assert_struct_size(RCT12RideMeasurement, 0x4B0C); + #pragma pack(pop) diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index a499a5cc70..5456f6bfea 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -310,7 +310,7 @@ struct RCT2SpriteVehicle : RCT12SpriteBase int32_t remaining_distance; // 0x24 int32_t velocity; // 0x28 int32_t acceleration; // 0x2C - ride_id_t ride; // 0x30 + uint8_t ride; // 0x30 uint8_t vehicle_type; // 0x31 rct_vehicle_colour colours; // 0x32 union diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 6c3b21e48c..a9e4a79cd2 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -360,7 +360,7 @@ void S6Exporter::Export() // pad_0138B582 _s6.ride_ratings_calc_data = gRideRatingsCalcData; - std::memcpy(_s6.ride_measurements, gRideMeasurements, sizeof(_s6.ride_measurements)); + ExportRideMeasurements(); _s6.next_guest_index = gNextGuestNumber; _s6.grass_and_scenery_tilepos = gGrassSceneryTileLoopPosition; std::memcpy(_s6.patrol_areas, gStaffPatrolAreas, sizeof(_s6.patrol_areas)); @@ -538,8 +538,6 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) dst->boat_hire_return_direction = src->boat_hire_return_direction; dst->boat_hire_return_position = src->boat_hire_return_position; - dst->measurement_index = src->measurement_index; - dst->special_track_elements = src->special_track_elements; // pad_0D6[2]; @@ -686,6 +684,60 @@ void S6Exporter::ExportRide(rct2_ride* dst, const Ride* src) // pad_208[0x58]; } +void S6Exporter::ExportRideMeasurements() +{ + // Get all the ride measurements + std::vector rideMeasurements; + for (ride_id_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++) + { + auto ride = get_ride(i); + if (ride != nullptr && ride->measurement != nullptr) + { + rideMeasurements.push_back(ride->measurement.get()); + } + } + + // If there are more than S6 can hold, trim it by LRU + if (rideMeasurements.size() > RCT12_RIDE_MEASUREMENT_MAX_ITEMS) + { + // Sort in order of last recently used + std::sort(rideMeasurements.begin(), rideMeasurements.end(), [](const RideMeasurement* a, const RideMeasurement* b) { + return a->last_use_tick > b->last_use_tick; + }); + rideMeasurements.resize(RCT12_RIDE_MEASUREMENT_MAX_ITEMS); + } + + // Convert ride measurements to S6 format + uint8_t i{}; + for (auto src : rideMeasurements) + { + auto& dst = _s6.ride_measurements[i]; + ExportRideMeasurement(_s6.ride_measurements[i], *src); + + auto rideId = src->ride->id; + dst.ride_index = rideId; + _s6.rides[rideId].measurement_index = i; + i++; + } +} + +void S6Exporter::ExportRideMeasurement(RCT12RideMeasurement& dst, const RideMeasurement& src) +{ + dst.flags = src.flags; + dst.last_use_tick = src.last_use_tick; + dst.num_items = src.num_items; + dst.current_item = src.current_item; + dst.vehicle_index = src.vehicle_index; + dst.current_station = src.current_station; + for (size_t i = 0; i < std::size(src.velocity); i++) + { + dst.velocity[i] = src.velocity[i]; + dst.altitude[i] = src.altitude[i]; + dst.vertical[i] = src.vertical[i]; + dst.lateral[i] = src.lateral[i]; + } +} + void S6Exporter::ExportResearchedRideTypes() { std::fill(std::begin(_s6.researched_ride_types), std::end(_s6.researched_ride_types), false); diff --git a/src/openrct2/rct2/S6Exporter.h b/src/openrct2/rct2/S6Exporter.h index 418065311c..68396e86c6 100644 --- a/src/openrct2/rct2/S6Exporter.h +++ b/src/openrct2/rct2/S6Exporter.h @@ -57,4 +57,6 @@ private: void ExportResearchList(); void ExportMarketingCampaigns(); void ExportPeepSpawns(); + void ExportRideMeasurements(); + void ExportRideMeasurement(RCT12RideMeasurement& dst, const RideMeasurement& src); }; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index fd72503273..f7cddfe5d3 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -396,7 +396,7 @@ public: // pad_0138B582 gRideRatingsCalcData = _s6.ride_ratings_calc_data; - std::memcpy(gRideMeasurements, _s6.ride_measurements, sizeof(_s6.ride_measurements)); + ImportRideMeasurements(); gNextGuestNumber = _s6.next_guest_index; gGrassSceneryTileLoopPosition = _s6.grass_and_scenery_tilepos; std::memcpy(gStaffPatrolAreas, _s6.patrol_areas, sizeof(_s6.patrol_areas)); @@ -586,8 +586,6 @@ public: dst->boat_hire_return_direction = src->boat_hire_return_direction; dst->boat_hire_return_position = src->boat_hire_return_position; - dst->measurement_index = src->measurement_index; - dst->special_track_elements = src->special_track_elements; // pad_0D6[2]; @@ -750,6 +748,37 @@ public: // pad_208[0x58]; } + void ImportRideMeasurements() + { + for (const auto& src : _s6.ride_measurements) + { + if (src.ride_index != RCT12_RIDE_ID_NULL) + { + auto ride = get_ride(src.ride_index); + ride->measurement = std::make_unique(); + ride->measurement->ride = ride; + ImportRideMeasurement(*ride->measurement, src); + } + } + } + + void ImportRideMeasurement(RideMeasurement& dst, const RCT12RideMeasurement& src) + { + dst.flags = src.flags; + dst.last_use_tick = src.last_use_tick; + dst.num_items = src.num_items; + dst.current_item = src.current_item; + dst.vehicle_index = src.vehicle_index; + dst.current_station = src.current_station; + for (size_t i = 0; i < std::size(src.velocity); i++) + { + dst.velocity[i] = src.velocity[i]; + dst.altitude[i] = src.altitude[i]; + dst.vertical[i] = src.vertical[i]; + dst.lateral[i] = src.lateral[i]; + } + } + void ImportResearchedRideTypes() { set_every_ride_type_not_invented(); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9bff7d7a3c..b064f6621e 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -152,8 +152,6 @@ static constexpr const int32_t RideInspectionInterval[] = { Ride gRideList[MAX_RIDES]; -rct_ride_measurement gRideMeasurements[MAX_RIDE_MEASUREMENTS]; - uint16_t gRideCount; bool gGotoStartPlacementMode = false; @@ -256,11 +254,6 @@ void get_ride_entry_name(char* name, int32_t index) name[8] = '\0'; } -rct_ride_measurement* get_ride_measurement(int32_t index) -{ - return &gRideMeasurements[index]; -} - rct_ride_entry* Ride::GetRideEntry() const { rct_ride_entry* rideEntry = get_ride_entry(subtype); @@ -955,12 +948,6 @@ void ride_init_all() ride->id = i; ride->type = RIDE_TYPE_NULL; } - - for (int32_t i = 0; i < MAX_RIDE_MEASUREMENTS; i++) - { - rct_ride_measurement* ride_measurement = get_ride_measurement(i); - ride_measurement->ride_index = RIDE_ID_NULL; - } } /** @@ -1093,7 +1080,7 @@ static void ride_remove_vehicles(Ride* ride) */ void ride_clear_for_construction(Ride* ride) { - ride_measurement_clear(ride); + ride->measurement = {}; ride->lifecycle_flags &= ~(RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; @@ -2071,7 +2058,7 @@ void Ride::UpdateAll() { if (gS6Info.editor_step <= EDITOR_STEP_INVENTIONS_LIST_SET_UP) FOR_ALL_RIDES (i, ride) - ride->type = RIDE_TYPE_NULL; + ride->Delete(); return; } @@ -2963,39 +2950,18 @@ static void ride_music_update(Ride* ride) #pragma region Measurement functions -/** - * - * rct2: 0x006B642B - */ -void ride_measurement_clear(Ride* ride) -{ - rct_ride_measurement* measurement; - - if (ride->measurement_index == 255) - return; - - measurement = get_ride_measurement(ride->measurement_index); - measurement->ride_index = RIDE_ID_NULL; - ride->measurement_index = 255; -} - /** * * rct2: 0x006B64F2 */ -static void ride_measurement_update(rct_ride_measurement* measurement) +static void ride_measurement_update(RideMeasurement* measurement) { - uint16_t spriteIndex; - Ride* ride; - rct_vehicle* vehicle; - int32_t velocity, altitude, verticalG, lateralG; - - ride = get_ride(measurement->ride_index); - spriteIndex = ride->vehicles[measurement->vehicle_index]; + auto ride = measurement->ride; + auto spriteIndex = ride->vehicles[measurement->vehicle_index]; if (spriteIndex == SPRITE_INDEX_NULL) return; - vehicle = GET_VEHICLE(spriteIndex); + auto vehicle = GET_VEHICLE(spriteIndex); if (measurement->flags & RIDE_MEASUREMENT_FLAG_UNLOADING) { @@ -3020,27 +2986,27 @@ static void ride_measurement_update(rct_ride_measurement* measurement) if (vehicle->velocity == 0) return; - if (measurement->current_item >= RIDE_MEASUREMENT_MAX_ITEMS) + if (measurement->current_item >= RideMeasurement::MAX_ITEMS) return; if (measurement->flags & RIDE_MEASUREMENT_FLAG_G_FORCES) { - vehicle_get_g_forces(vehicle, &verticalG, &lateralG); - verticalG = std::clamp(verticalG / 8, -127, 127); - lateralG = std::clamp(lateralG / 8, -127, 127); + auto gForces = vehicle_get_g_forces(vehicle); + gForces.VerticalG = std::clamp(gForces.VerticalG / 8, -127, 127); + gForces.LateralG = std::clamp(gForces.LateralG / 8, -127, 127); if (gScenarioTicks & 1) { - verticalG = (verticalG + measurement->vertical[measurement->current_item]) / 2; - lateralG = (lateralG + measurement->lateral[measurement->current_item]) / 2; + gForces.VerticalG = (gForces.VerticalG + measurement->vertical[measurement->current_item]) / 2; + gForces.LateralG = (gForces.LateralG + measurement->lateral[measurement->current_item]) / 2; } - measurement->vertical[measurement->current_item] = verticalG & 0xFF; - measurement->lateral[measurement->current_item] = lateralG & 0xFF; + measurement->vertical[measurement->current_item] = gForces.VerticalG & 0xFF; + measurement->lateral[measurement->current_item] = gForces.LateralG & 0xFF; } - velocity = std::min(std::abs((vehicle->velocity * 5) >> 16), 255); - altitude = std::min(vehicle->z / 8, 255); + auto velocity = std::min(std::abs((vehicle->velocity * 5) >> 16), 255); + auto altitude = std::min(vehicle->z / 8, 255); if (gScenarioTicks & 1) { @@ -3068,136 +3034,106 @@ void ride_measurements_update() return; // For each ride measurement - for (int32_t i = 0; i < MAX_RIDE_MEASUREMENTS; i++) + ride_id_t i{}; + Ride* ride{}; + FOR_ALL_RIDES (i, ride) { - rct_ride_measurement* measurement = get_ride_measurement(i); - if (measurement->ride_index == RIDE_ID_NULL) - continue; - - Ride* ride = get_ride(measurement->ride_index); - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) || ride->status == RIDE_STATUS_SIMULATING) - continue; - - if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) + auto measurement = ride->measurement.get(); + if (measurement != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) && ride->status != RIDE_STATUS_SIMULATING) { - ride_measurement_update(measurement); - } - else - { - // For each vehicle - for (int32_t j = 0; j < ride->num_vehicles; j++) + if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) { - uint16_t vehicleSpriteIdx = ride->vehicles[j]; - if (vehicleSpriteIdx == SPRITE_INDEX_NULL) - continue; - - rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx); - if (vehicle->status == VEHICLE_STATUS_DEPARTING || vehicle->status == VEHICLE_STATUS_TRAVELLING_CABLE_LIFT) + ride_measurement_update(measurement); + } + else + { + // For each vehicle + for (int32_t j = 0; j < ride->num_vehicles; j++) { - measurement->vehicle_index = j; - measurement->current_station = vehicle->current_station; - measurement->flags |= RIDE_MEASUREMENT_FLAG_RUNNING; - measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; - ride_measurement_update(measurement); - break; + uint16_t vehicleSpriteIdx = ride->vehicles[j]; + if (vehicleSpriteIdx != SPRITE_INDEX_NULL) + { + auto vehicle = GET_VEHICLE(vehicleSpriteIdx); + if (vehicle->status == VEHICLE_STATUS_DEPARTING + || vehicle->status == VEHICLE_STATUS_TRAVELLING_CABLE_LIFT) + { + measurement->vehicle_index = j; + measurement->current_station = vehicle->current_station; + measurement->flags |= RIDE_MEASUREMENT_FLAG_RUNNING; + measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; + ride_measurement_update(measurement); + break; + } + } } } } } } -static rct_ride_measurement* ride_get_existing_measurement(ride_id_t rideIndex) -{ - for (int32_t i = 0; i < MAX_RIDE_MEASUREMENTS; i++) - { - rct_ride_measurement* measurement = get_ride_measurement(i); - if (measurement->ride_index == rideIndex) - return measurement; - } - - return nullptr; -} - -static int32_t ride_get_free_measurement() -{ - for (int32_t i = 0; i < MAX_RIDE_MEASUREMENTS; i++) - { - rct_ride_measurement* measurement = get_ride_measurement(i); - if (measurement->ride_index == RIDE_ID_NULL) - return i; - } - - return -1; -} - /** - * - * rct2: 0x006B66D9 + * If there are more than the threshold of allowed ride measurements, free the non-LRU one. */ -rct_ride_measurement* ride_get_measurement(Ride* ride, rct_string_id* message) +static void ride_free_old_measurements() +{ + size_t numRideMeasurements; + do + { + ride_id_t i{}; + Ride* ride{}; + Ride* lruRide{}; + numRideMeasurements = 0; + FOR_ALL_RIDES (i, ride) + { + if (ride->measurement != nullptr) + { + if (lruRide == nullptr || ride->measurement->last_use_tick > lruRide->measurement->last_use_tick) + { + lruRide = ride; + } + numRideMeasurements++; + } + } + if (numRideMeasurements > MAX_RIDE_MEASUREMENTS && lruRide != nullptr) + { + lruRide->measurement = {}; + numRideMeasurements--; + } + } while (numRideMeasurements > MAX_RIDE_MEASUREMENTS); +} + +std::pair ride_get_measurement(Ride* ride) { // Check if ride type supports data logging if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_DATA_LOGGING)) { - if (message != nullptr) - *message = STR_DATA_LOGGING_NOT_AVAILABLE_FOR_THIS_TYPE_OF_RIDE; - return nullptr; + return { nullptr, STR_DATA_LOGGING_NOT_AVAILABLE_FOR_THIS_TYPE_OF_RIDE }; } // Check if a measurement already exists for this ride - rct_ride_measurement* measurement = ride_get_existing_measurement(ride->id); + auto& measurement = ride->measurement; if (measurement == nullptr) { - // Find a free measurement - int32_t i = ride_get_free_measurement(); - if (i == -1) - { - // Use last recently used measurement for some other ride - int32_t lruIndex = 0; - uint32_t lruTicks = 0xFFFFFFFF; - for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) - { - measurement = get_ride_measurement(i); - - if (measurement->last_use_tick <= lruTicks) - { - lruTicks = measurement->last_use_tick; - lruIndex = i; - } - } - - i = lruIndex; - measurement = get_ride_measurement(i); - get_ride(measurement->ride_index)->measurement_index = 255; - } - else - { - measurement = get_ride_measurement(i); - } - - measurement->ride_index = ride->id; - ride->measurement_index = i; - measurement->flags = 0; + measurement = std::make_unique(); + measurement->ride = ride; if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) + { measurement->flags |= RIDE_MEASUREMENT_FLAG_G_FORCES; - measurement->num_items = 0; - measurement->current_item = 0; + } + ride_free_old_measurements(); + assert(ride->measurement != nullptr); } measurement->last_use_tick = gScenarioTicks; if (measurement->flags & 1) { - if (message != nullptr) - *message = STR_EMPTY; - return measurement; + return { measurement.get(), STR_EMPTY }; } else { set_format_arg(0, rct_string_id, RideComponentNames[RideNameConvention[ride->type].vehicle].singular); set_format_arg(2, rct_string_id, RideComponentNames[RideNameConvention[ride->type].station].singular); - if (message != nullptr) - *message = STR_DATA_LOGGING_WILL_START_WHEN_NEXT_LEAVES; - return nullptr; + return { measurement.get(), STR_DATA_LOGGING_WILL_START_WHEN_NEXT_LEAVES }; } } @@ -6652,7 +6588,7 @@ bool ride_are_all_possible_entrances_and_exits_built(Ride* ride) */ void invalidate_test_results(Ride* ride) { - ride_measurement_clear(ride); + ride->measurement = {}; ride->excitement = RIDE_RATING_UNDEFINED; ride->lifecycle_flags &= ~RIDE_LIFECYCLE_TESTED; ride->lifecycle_flags &= ~RIDE_LIFECYCLE_TEST_IN_PROGRESS; @@ -7440,6 +7376,7 @@ rct_vehicle* ride_get_broken_vehicle(Ride* ride) void Ride::Delete() { user_string_free(name); + measurement = {}; type = RIDE_TYPE_NULL; } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 8b115a0470..484d873b78 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -21,6 +21,7 @@ interface IObjectManager; class StationObject; struct Peep; +struct Ride; struct Staff; #define MAX_RIDE_TYPES_PER_RIDE_ENTRY 3 @@ -35,7 +36,6 @@ struct Staff; #define CUSTOMER_HISTORY_SIZE 10 #define MAX_CARS_PER_TRAIN 255 #define MAX_STATIONS 4 -#define RIDE_MEASUREMENT_MAX_ITEMS 4800 #define MAX_RIDES 255 #define RIDE_ID_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 @@ -160,6 +160,23 @@ struct RideStation static constexpr uint8_t NO_TRAIN = std::numeric_limits::max(); }; +struct RideMeasurement +{ + static constexpr size_t MAX_ITEMS = 4800; + + Ride* ride{}; + uint8_t flags{}; + uint32_t last_use_tick{}; + uint16_t num_items{}; + uint16_t current_item{}; + uint8_t vehicle_index{}; + uint8_t current_station{}; + int8_t vertical[MAX_ITEMS]{}; + int8_t lateral[MAX_ITEMS]{}; + uint8_t velocity[MAX_ITEMS]{}; + uint8_t altitude[MAX_ITEMS]{}; +}; + /** * Ride structure. * @@ -212,7 +229,6 @@ struct Ride uint8_t boat_hire_return_direction; LocationXY8 boat_hire_return_position; - uint8_t measurement_index; // bits 0 through 4 are the number of helix sections // bit 5: spinning tunnel, water splash, or rapids // bit 6: log reverser, waterfall @@ -352,6 +368,8 @@ struct Ride uint16_t holes; uint8_t sheltered_eighths; + std::unique_ptr measurement; + private: void Update(); void UpdateChairlift(); @@ -403,26 +421,6 @@ public: #pragma pack(push, 1) -/** - * Ride measurement structure. - * size: 0x04B0C - */ -struct rct_ride_measurement -{ - ride_id_t ride_index; // 0x0000 - uint8_t flags; // 0x0001 - uint32_t last_use_tick; // 0x0002 - uint16_t num_items; // 0x0006 - uint16_t current_item; // 0x0008 - uint8_t vehicle_index; // 0x000A - uint8_t current_station; // 0x000B - int8_t vertical[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x000C - int8_t lateral[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x12CC - uint8_t velocity[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x258C - uint8_t altitude[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x384C -}; -assert_struct_size(rct_ride_measurement, 0x4b0c); - struct track_begin_end { int32_t begin_x; @@ -982,7 +980,7 @@ extern const rct_ride_properties RideProperties[RIDE_TYPE_COUNT]; Ride* get_ride(int32_t index); rct_ride_entry* get_ride_entry(int32_t index); void get_ride_entry_name(char* name, int32_t index); -rct_ride_measurement* get_ride_measurement(int32_t index); +RideMeasurement* get_ride_measurement(int32_t index); /** * Helper macro loop for enumerating through all the non null rides. @@ -998,7 +996,6 @@ extern const uint8_t gRideClassifications[MAX_RIDES]; extern Ride gRideList[MAX_RIDES]; extern const rct_string_id ColourSchemeNames[4]; -extern rct_ride_measurement gRideMeasurements[MAX_RIDE_MEASUREMENTS]; extern uint16_t gRideCount; extern money32 _currentTrackPrice; @@ -1070,9 +1067,8 @@ int32_t ride_get_unused_preset_vehicle_colour(uint8_t ride_sub_type); void ride_set_vehicle_colours_to_random_preset(Ride* ride, uint8_t preset_index); uint8_t* get_ride_entry_indices_for_ride_type(uint8_t rideType); void reset_type_to_ride_entry_index_map(IObjectManager& objectManager); -void ride_measurement_clear(Ride* ride); void ride_measurements_update(); -rct_ride_measurement* ride_get_measurement(Ride* ride, rct_string_id* message); +std::pair ride_get_measurement(Ride* ride); void ride_breakdown_add_news_item(Ride* ride); Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection); int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, bool isApplying); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 7d99cfc255..860f3e02e8 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1798,6 +1798,7 @@ static bool track_design_place_preview(rct_track_td6* td6, money32* cost, Ride** _currentTrackPieceDirection = backup_rotation; user_string_free(ride->name); ride->type = RIDE_TYPE_NULL; + ride->measurement = {}; byte_9D8150 = false; return false; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index ca66f928ab..c35250da88 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1557,32 +1557,27 @@ static void vehicle_update_measurements(rct_vehicle* vehicle) if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) { - int32_t vertical_g, lateral_g; - vehicle_get_g_forces(vehicle, &vertical_g, &lateral_g); + auto gForces = vehicle_get_g_forces(vehicle); + gForces.VerticalG += ride->previous_vertical_g; + gForces.LateralG += ride->previous_lateral_g; + gForces.VerticalG /= 2; + gForces.LateralG /= 2; - vertical_g += ride->previous_vertical_g; - lateral_g += ride->previous_lateral_g; - vertical_g >>= 1; - lateral_g >>= 1; - - ride->previous_vertical_g = vertical_g; - ride->previous_lateral_g = lateral_g; - - if (vertical_g <= 0) + ride->previous_vertical_g = gForces.VerticalG; + ride->previous_lateral_g = gForces.LateralG; + if (gForces.VerticalG <= 0) { ride->total_air_time++; } - if (vertical_g > ride->max_positive_vertical_g) - ride->max_positive_vertical_g = vertical_g; + if (gForces.VerticalG > ride->max_positive_vertical_g) + ride->max_positive_vertical_g = gForces.VerticalG; - if (vertical_g < ride->max_negative_vertical_g) - ride->max_negative_vertical_g = vertical_g; + if (gForces.VerticalG < ride->max_negative_vertical_g) + ride->max_negative_vertical_g = gForces.VerticalG; - lateral_g = abs(lateral_g); - - if (lateral_g > ride->max_lateral_g) - ride->max_lateral_g = lateral_g; + gForces.LateralG = std::abs(gForces.LateralG); + ride->max_lateral_g = std::max(ride->max_lateral_g, (fixed16_2dp)gForces.LateralG); } } @@ -5706,7 +5701,7 @@ produceScream: * dx: lateralG * esi: vehicle */ -void vehicle_get_g_forces(const rct_vehicle* vehicle, int32_t* verticalG, int32_t* lateralG) +GForces vehicle_get_g_forces(const rct_vehicle* vehicle) { int32_t gForceVert = (((int64_t)0x280000) * Unk9A37E4[vehicle->vehicle_sprite_type]) >> 32; gForceVert = (((int64_t)gForceVert) * Unk9A39C4[vehicle->bank_rotation]) >> 32; @@ -6221,11 +6216,7 @@ void vehicle_get_g_forces(const rct_vehicle* vehicle, int32_t* verticalG, int32_ gForceLateral *= 10; gForceVert >>= 16; gForceLateral >>= 16; - - if (verticalG != nullptr) - *verticalG = (int16_t)(gForceVert & 0xFFFF); - if (lateralG != nullptr) - *lateralG = (int16_t)(gForceLateral & 0xFFFF); + return { (int16_t)(gForceVert & 0xFFFF), (int16_t)(gForceLateral & 0xFFFF) }; } void vehicle_set_map_toolbar(const rct_vehicle* vehicle) @@ -6531,9 +6522,7 @@ bool vehicle_update_dodgems_collision(rct_vehicle* vehicle, int16_t x, int16_t y */ static void vehicle_update_track_motion_up_stop_check(rct_vehicle* vehicle) { - rct_ride_entry_vehicle* vehicleEntry = vehicle_get_vehicle_entry(vehicle); - int32_t verticalG, lateralG; - + auto vehicleEntry = vehicle_get_vehicle_entry(vehicle); if (vehicleEntry == nullptr) { return; @@ -6545,18 +6534,18 @@ static void vehicle_update_track_motion_up_stop_check(rct_vehicle* vehicle) int32_t trackType = vehicle->track_type >> 2; if (!track_element_is_covered(trackType)) { - vehicle_get_g_forces(vehicle, &verticalG, &lateralG); - lateralG = abs(lateralG); - if (lateralG <= 150) + auto gForces = vehicle_get_g_forces(vehicle); + gForces.LateralG = std::abs(gForces.LateralG); + if (gForces.LateralG <= 150) { if (dword_9A2970[vehicle->vehicle_sprite_type] < 0) { - if (verticalG > -40) + if (gForces.VerticalG > -40) { return; } } - else if (verticalG > -80) + else if (gForces.VerticalG > -80) { return; } @@ -6574,18 +6563,18 @@ static void vehicle_update_track_motion_up_stop_check(rct_vehicle* vehicle) int32_t trackType = vehicle->track_type >> 2; if (!track_element_is_covered(trackType)) { - vehicle_get_g_forces(vehicle, &verticalG, &lateralG); + auto gForces = vehicle_get_g_forces(vehicle); if (dword_9A2970[vehicle->vehicle_sprite_type] < 0) { - if (verticalG > -45) + if (gForces.VerticalG > -45) { return; } } else { - if (verticalG > -80) + if (gForces.VerticalG > -80) { return; } diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index ce41e0b116..91bc5830e1 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -457,10 +457,16 @@ enum #define VEHICLE_SEAT_PAIR_FLAG 0x80 #define VEHICLE_SEAT_NUM_MASK 0x7F +struct GForces +{ + int32_t VerticalG{}; + int32_t LateralG{}; +}; + rct_vehicle* try_get_vehicle(uint16_t spriteIndex); void vehicle_update_all(); void vehicle_sounds_update(); -void vehicle_get_g_forces(const rct_vehicle* vehicle, int32_t* verticalG, int32_t* lateralG); +GForces vehicle_get_g_forces(const rct_vehicle* vehicle); void vehicle_set_map_toolbar(const rct_vehicle* vehicle); int32_t vehicle_is_used_in_pairs(const rct_vehicle* vehicle); int32_t vehicle_update_track_motion(rct_vehicle* vehicle, int32_t* outStation); diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index f14ba66a59..6f259956fe 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -265,7 +265,7 @@ struct rct_s6_data uint8_t pad_0138B582[2]; rct_ride_rating_calc_data ride_ratings_calc_data; uint8_t pad_0138B5D0[60]; - rct_ride_measurement ride_measurements[8]; + RCT12RideMeasurement ride_measurements[8]; uint32_t next_guest_index; uint16_t grass_and_scenery_tilepos; uint32_t patrol_areas[(RCT2_MAX_STAFF + RCT12_STAFF_TYPE_COUNT) * RCT12_PATROL_AREA_SIZE]; diff --git a/test/testpaint/TestPaint.cpp b/test/testpaint/TestPaint.cpp index a78a808f31..61e39a24c6 100644 --- a/test/testpaint/TestPaint.cpp +++ b/test/testpaint/TestPaint.cpp @@ -46,13 +46,11 @@ namespace TestPaint gPaintSession.DPI = dpi; { - Ride ride = {}; - ride.entrance_style = 0; static rct_ride_entry rideEntry = {}; rct_ride_entry_vehicle vehicleEntry{}; vehicleEntry.base_image_id = 0x70000; rideEntry.vehicles[0] = vehicleEntry; - gRideList[0] = ride; + gRideList[0] = {}; gRideEntries[0] = &rideEntry; } { From dd948f99c44033e5bc6d32954664a49cec6612bc Mon Sep 17 00:00:00 2001 From: Peter <46459699+Spongeloaf@users.noreply.github.com> Date: Sun, 9 Jun 2019 10:45:56 -0400 Subject: [PATCH 454/506] #9295 Refactor rct_vehcile->status to rct_vehicle::SetState() (#9329) Fix #9295. Refactor rct_vehicle->status to rct_vehicle::SetState() Created rct_vehicle::SetState() and refactored all assignments to rct_vehcile->status. SetState also includes a call to vehicle_invalidate_window(), so it cannot be forgotten. --- src/openrct2-ui/windows/Ride.cpp | 3 +- src/openrct2/rct1/S4Importer.cpp | 7 +- src/openrct2/rct2/S6Importer.cpp | 9 +- src/openrct2/ride/CableLift.cpp | 19 ++- src/openrct2/ride/Ride.cpp | 10 +- src/openrct2/ride/Vehicle.cpp | 227 +++++++++---------------------- src/openrct2/ride/Vehicle.h | 73 +++++----- 7 files changed, 134 insertions(+), 214 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 115827caa5..2f941ed953 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2508,7 +2508,8 @@ static void window_ride_main_update(rct_window* w) return; rct_vehicle* vehicle = &(get_sprite(vehicleSpriteIndex)->vehicle); - if (vehicle->status != 4 && vehicle->status != 22 && vehicle->status != 10 && vehicle->status != 7) + if (vehicle->status != VEHICLE_STATUS_TRAVELLING && vehicle->status != VEHICLE_STATUS_TRAVELLING_CABLE_LIFT + && vehicle->status != VEHICLE_STATUS_TRAVELLING_DODGEMS && vehicle->status != VEHICLE_STATUS_TRAVELLING_BOAT) { return; } diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 094da3a572..83781c621c 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1251,6 +1251,12 @@ private: } } + VEHICLE_STATUS statusSrc = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; + if (src->status <= static_cast(VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES)) + { + statusSrc = static_cast(src->status); + } + dst->status = statusSrc; dst->var_CD = src->var_CD; dst->track_x = src->track_x; dst->track_y = src->track_y; @@ -1259,7 +1265,6 @@ private: dst->track_type = src->track_type; dst->track_progress = src->track_progress; dst->vertical_drop_countdown = src->vertical_drop_countdown; - dst->status = src->status; dst->sub_state = src->sub_state; dst->update_flags = src->update_flags; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index f7cddfe5d3..994070cb4d 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1158,7 +1158,14 @@ public: dst->current_station = src->current_station; dst->current_time = src->current_time; dst->crash_z = src->crash_z; - dst->status = src->status; + + VEHICLE_STATUS statusSrc = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; + if (src->status <= static_cast(VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES)) + { + statusSrc = static_cast(src->status); + } + + dst->status = statusSrc; dst->sub_state = src->sub_state; for (size_t i = 0; i < std::size(src->peep); i++) { diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 0767c17f56..4b660f886e 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -84,8 +84,7 @@ rct_vehicle* cable_lift_segment_create( current->track_type = (TRACK_ELEM_CABLE_LIFT_HILL << 2) | (current->sprite_direction >> 3); current->track_progress = 164; current->update_flags = VEHICLE_UPDATE_FLAG_1; - current->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; - current->sub_state = 0; + current->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION, 0); current->num_peeps = 0; current->next_free_seat = 0; return current; @@ -113,6 +112,8 @@ void cable_lift_update(rct_vehicle* vehicle) case VEHICLE_STATUS_ARRIVING: cable_lift_update_arriving(vehicle); break; + default: + break; } } @@ -136,7 +137,7 @@ static void cable_lift_update_moving_to_end_of_station(rct_vehicle* vehicle) vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS; + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_PASSENGERS, vehicle->sub_state); } /** @@ -170,8 +171,7 @@ static void cable_lift_update_waiting_to_depart(rct_vehicle* vehicle) vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 0); } /** @@ -185,8 +185,8 @@ static void cable_lift_update_departing(rct_vehicle* vehicle) return; rct_vehicle* passengerVehicle = GET_VEHICLE(vehicle->cable_lift_target); - vehicle->status = VEHICLE_STATUS_TRAVELLING; - passengerVehicle->status = VEHICLE_STATUS_TRAVELLING_CABLE_LIFT; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING, vehicle->sub_state); + passengerVehicle->SetState(VEHICLE_STATUS_TRAVELLING_CABLE_LIFT, passengerVehicle->sub_state); } /** @@ -207,8 +207,7 @@ static void cable_lift_update_travelling(rct_vehicle* vehicle) vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING, 0); } /** @@ -219,7 +218,7 @@ static void cable_lift_update_arriving(rct_vehicle* vehicle) { vehicle->sub_state++; if (vehicle->sub_state >= 64) - vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; + vehicle->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION, vehicle->sub_state); } static bool sub_6DF01A_loop(rct_vehicle* vehicle) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index b064f6621e..1c44c27303 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4547,8 +4547,7 @@ static rct_vehicle* vehicle_create_car( vehicle->track_type = tileElement->AsTrack()->GetTrackType() << 2; vehicle->track_progress = 0; - vehicle->status = 0; - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION); vehicle->update_flags = 0; LocationXY16 chosenLoc; @@ -4653,8 +4652,7 @@ static rct_vehicle* vehicle_create_car( vehicle->update_flags |= VEHICLE_UPDATE_FLAG_USE_INVERTED_SPRITES; } } - vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION); } // loc_6DDD5E: @@ -4960,10 +4958,10 @@ void loc_6DDF9C(Ride* ride, TileElement* tileElement) while (true) { car->update_flags &= ~VEHICLE_UPDATE_FLAG_1; - car->status = VEHICLE_STATUS_TRAVELLING; + car->SetState(VEHICLE_STATUS_TRAVELLING, car->sub_state); if ((car->track_type >> 2) == TRACK_ELEM_END_STATION) { - car->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; + car->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION, car->sub_state); } uint16_t spriteIndex = car->next_vehicle_on_train; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index c35250da88..ed93fb17a4 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2022,6 +2022,8 @@ static void vehicle_update(rct_vehicle* vehicle) break; case VEHICLE_STATUS_DOING_CIRCUS_SHOW: vehicle_update_doing_circus_show(vehicle); + default: + break; } vehicle_update_sound(vehicle); @@ -2075,9 +2077,7 @@ static void vehicle_update_moving_to_end_of_station(rct_vehicle* vehicle) vehicle->current_station = 0; vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_PASSENGERS); break; default: { @@ -2112,9 +2112,7 @@ static void vehicle_update_moving_to_end_of_station(rct_vehicle* vehicle) if (ride->mode == RIDE_MODE_RACE && vehicle->sub_state >= 40) { - vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_PASSENGERS); break; } } @@ -2132,9 +2130,7 @@ static void vehicle_update_moving_to_end_of_station(rct_vehicle* vehicle) vehicle->current_station = station; vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_PASSENGERS); break; } } @@ -2175,9 +2171,7 @@ static void train_ready_to_depart(rct_vehicle* vehicle, uint8_t num_peeps_on_tra if (vehicle->peep[peep] != SPRITE_INDEX_NULL) { ride->stations[vehicle->current_station].TrainAtStation = RideStation::NO_TRAIN; - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); return; } @@ -2193,9 +2187,7 @@ static void train_ready_to_depart(rct_vehicle* vehicle, uint8_t num_peeps_on_tra return; ride->stations[vehicle->current_station].TrainAtStation = RideStation::NO_TRAIN; - vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_PASSENGERS); } static int ride_get_train_index_from_vehicle(Ride* ride, uint16_t spriteIndex) @@ -2416,8 +2408,6 @@ static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle) return; vehicle->velocity = 0; - vehicle->status = VEHICLE_STATUS_WAITING_TO_DEPART; - vehicle->sub_state = 0; vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT; if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS) @@ -2425,7 +2415,7 @@ static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle) vehicle->update_flags |= VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT; } - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_WAITING_TO_DEPART); } /** @@ -2465,9 +2455,7 @@ static void vehicle_update_dodgems_mode(rct_vehicle* vehicle) vehicle->Invalidate(); vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); } /** @@ -2510,9 +2498,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) { if (!ride_get_exit_location(ride, vehicle->current_station).isNull()) { - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); return; } } @@ -2528,9 +2514,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) { if (!ride_get_exit_location(ride, vehicle->current_station).isNull()) { - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); return; } break; @@ -2559,8 +2543,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) } } - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_DEPARTING); if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT) { @@ -2574,7 +2557,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) { if (track.element->AsTrack()->HasCableLift()) { - vehicle->status = VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT; + vehicle->SetState(VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT, vehicle->sub_state); } } } @@ -2582,45 +2565,38 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) switch (ride->mode) { case RIDE_MODE_BUMPERCAR: - vehicle->status = VEHICLE_STATUS_TRAVELLING_DODGEMS; - vehicle_invalidate_window(vehicle); // Bumper mode uses sub_state / var_CE to tell how long // the vehicle has been ridden. - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING_DODGEMS); vehicle->var_CE = 0; vehicle_update_dodgems_mode(vehicle); break; case RIDE_MODE_SWING: - vehicle->status = VEHICLE_STATUS_SWINGING; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_SWINGING); vehicle->var_CE = 0; vehicle->current_time = -1; vehicle_update_swinging(vehicle); break; case RIDE_MODE_ROTATION: - vehicle->status = VEHICLE_STATUS_ROTATING; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_ROTATING); vehicle->var_CE = 0; vehicle->current_time = -1; vehicle_update_rotating(vehicle); break; case RIDE_MODE_FILM_AVENGING_AVIATORS: + vehicle->SetState(VEHICLE_STATUS_SIMULATOR_OPERATING); + vehicle->current_time = -1; + vehicle_update_simulator_operating(vehicle); + break; case RIDE_MODE_FILM_THRILL_RIDERS: - vehicle->status = VEHICLE_STATUS_SIMULATOR_OPERATING; - vehicle->sub_state = 0; - if (ride->mode == RIDE_MODE_FILM_THRILL_RIDERS) - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_SIMULATOR_OPERATING, 1); vehicle->current_time = -1; vehicle_update_simulator_operating(vehicle); break; case RIDE_MODE_BEGINNERS: case RIDE_MODE_INTENSE: case RIDE_MODE_BERSERK: - vehicle->status = VEHICLE_STATUS_TOP_SPIN_OPERATING; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_TOP_SPIN_OPERATING, vehicle->sub_state); switch (ride->mode) { @@ -2641,9 +2617,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) break; case RIDE_MODE_FORWARD_ROTATION: case RIDE_MODE_BACKWARD_ROTATION: - vehicle->status = VEHICLE_STATUS_FERRIS_WHEEL_ROTATING; - vehicle->sub_state = vehicle->vehicle_sprite_type; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_FERRIS_WHEEL_ROTATING, vehicle->vehicle_sprite_type); vehicle->var_CE = 0; vehicle->ferris_wheel_var_0 = 8; vehicle->ferris_wheel_var_1 = 8; @@ -2652,8 +2626,7 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) case RIDE_MODE_3D_FILM_MOUSE_TAILS: case RIDE_MODE_3D_FILM_STORM_CHASERS: case RIDE_MODE_3D_FILM_SPACE_RAIDERS: - vehicle->status = VEHICLE_STATUS_SHOWING_FILM; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_SHOWING_FILM, vehicle->sub_state); switch (ride->mode) { case RIDE_MODE_3D_FILM_MOUSE_TAILS: @@ -2670,39 +2643,30 @@ static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) vehicle_update_showing_film(vehicle); break; case RIDE_MODE_CIRCUS_SHOW: - vehicle->status = VEHICLE_STATUS_DOING_CIRCUS_SHOW; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DOING_CIRCUS_SHOW); vehicle->current_time = -1; vehicle_update_doing_circus_show(vehicle); break; case RIDE_MODE_SPACE_RINGS: - vehicle->status = VEHICLE_STATUS_SPACE_RINGS_OPERATING; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_SPACE_RINGS_OPERATING); vehicle->vehicle_sprite_type = 0; vehicle->current_time = -1; vehicle_update_space_rings_operating(vehicle); break; case RIDE_MODE_HAUNTED_HOUSE: - vehicle->status = VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING); vehicle->vehicle_sprite_type = 0; vehicle->current_time = -1; vehicle_update_haunted_house_operating(vehicle); break; case RIDE_MODE_CROOKED_HOUSE: - vehicle->status = VEHICLE_STATUS_CROOKED_HOUSE_OPERATING; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_CROOKED_HOUSE_OPERATING); vehicle->vehicle_sprite_type = 0; vehicle->current_time = -1; vehicle_update_crooked_house_operating(vehicle); break; default: - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(vehicle->status); vehicle->var_CE = 0; break; } @@ -3164,9 +3128,7 @@ static void vehicle_update_travelling_boat_hire_setup(rct_vehicle* vehicle) vehicle->boat_location = location; vehicle->var_35 = 0; - vehicle->status = VEHICLE_STATUS_TRAVELLING_BOAT; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING_BOAT); vehicle->remaining_distance += 27924; vehicle_update_travelling_boat(vehicle); @@ -3461,12 +3423,8 @@ static void vehicle_finish_departing(rct_vehicle* vehicle) ride->stations[vehicle->current_station].Depart |= waitingTime; } - - vehicle->status = VEHICLE_STATUS_TRAVELLING; - vehicle_invalidate_window(vehicle); vehicle->lost_time_out = 0; - - vehicle->sub_state = 1; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING, 1); if (vehicle->velocity < 0) vehicle->sub_state = 0; } @@ -3539,8 +3497,7 @@ static void vehicle_update_collision_setup(rct_vehicle* vehicle) return; } - vehicle->status = VEHICLE_STATUS_CRASHED; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_CRASHED, vehicle->sub_state); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { @@ -3619,9 +3576,7 @@ static void vehicle_update_crash_setup(rct_vehicle* vehicle) vehicle_simulate_crash(vehicle); return; } - - vehicle->status = VEHICLE_STATUS_CRASHING; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_CRASHING, vehicle->sub_state); int32_t num_peeps = vehicle_get_total_num_peeps(vehicle); if (num_peeps != 0) @@ -3733,9 +3688,7 @@ static void vehicle_update_travelling(rct_vehicle* vehicle) { if (vehicle->sub_state <= 1) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 1; + vehicle->SetState(VEHICLE_STATUS_ARRIVING, 1); vehicle->var_C0 = 0; return; } @@ -3845,12 +3798,9 @@ static void vehicle_update_travelling(rct_vehicle* vehicle) if (ride->mode == RIDE_MODE_POWERED_LAUNCH_PASSTROUGH && vehicle->velocity < 0) return; - vehicle->status = VEHICLE_STATUS_ARRIVING; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->current_station = _vehicleStationIndex; - vehicle_invalidate_window(vehicle); vehicle->var_C0 = 0; - - vehicle->sub_state = 0; if (vehicle->velocity < 0) vehicle->sub_state = 1; } @@ -3885,9 +3835,7 @@ static void vehicle_update_arriving(rct_vehicle* vehicle) vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_12; vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); return; } @@ -3993,9 +3941,7 @@ loc_6D8E36: if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION && unkF64E35 == 0) { - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } @@ -4029,26 +3975,20 @@ loc_6D8E36: { if (vehicle->num_laps < ride->num_circuits) { - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } if (vehicle->num_laps == ride->num_circuits && vehicle->update_flags & VEHICLE_UPDATE_FLAG_12) { - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } } if (ride->num_circuits != 1 && vehicle->num_laps < ride->num_circuits) { - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } @@ -4057,26 +3997,20 @@ loc_6D8E36: audio_play_sound_at_location(SOUND_RIDE_LAUNCH_2, vehicle->x, vehicle->y, vehicle->z); vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } if (ride->mode == RIDE_MODE_RACE && ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) { - vehicle->status = VEHICLE_STATUS_DEPARTING; - vehicle->sub_state = 1; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_DEPARTING, 1); return; } vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_12; vehicle->velocity = 0; vehicle->acceleration = 0; - vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_UNLOADING_PASSENGERS); } /** @@ -4126,9 +4060,7 @@ static void vehicle_update_unloading_passengers(rct_vehicle* vehicle) { vehicle_update_test_finish(vehicle); } - vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION); return; } @@ -4168,9 +4100,7 @@ static void vehicle_update_unloading_passengers(rct_vehicle* vehicle) { vehicle_update_test_finish(vehicle); } - vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; - vehicle->sub_state = 0; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION); } /** @@ -4186,7 +4116,7 @@ static void vehicle_update_waiting_for_cable_lift(rct_vehicle* vehicle) if (cableLift->status != VEHICLE_STATUS_WAITING_FOR_PASSENGERS) return; - cableLift->status = VEHICLE_STATUS_WAITING_TO_DEPART; + cableLift->SetState(VEHICLE_STATUS_WAITING_TO_DEPART, vehicle->sub_state); cableLift->cable_lift_target = vehicle->sprite_index; } @@ -4248,9 +4178,7 @@ static void vehicle_update_travelling_cable_lift(rct_vehicle* vehicle) if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_11) { - vehicle->status = VEHICLE_STATUS_TRAVELLING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 1; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING, 1); vehicle->lost_time_out = 0; return; } @@ -4302,7 +4230,7 @@ static void loc_6DA9F9(rct_vehicle* vehicle, int32_t x, int32_t y, int32_t bx, i vehicle->track_type = (trackElement->GetTrackType() << 2) | (ride->boat_hire_return_direction & 3); vehicle->track_progress = 0; - vehicle->status = VEHICLE_STATUS_TRAVELLING; + vehicle->SetState(VEHICLE_STATUS_TRAVELLING, vehicle->sub_state); unk_F64E20.x = x; unk_F64E20.y = y; } @@ -4764,9 +4692,7 @@ static void vehicle_update_swinging(rct_vehicle* vehicle) // swing has to be in slowing down phase if (vehicle->sub_state == 0) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; return; } @@ -4860,9 +4786,7 @@ static void vehicle_update_ferris_wheel_rotating(rct_vehicle* vehicle) if (subState != vehicle->vehicle_sprite_type) return; - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } @@ -4888,9 +4812,7 @@ static void vehicle_update_simulator_operating(rct_vehicle* vehicle) return; } - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } @@ -4961,9 +4883,7 @@ static void vehicle_update_rotating(rct_vehicle* vehicle) { if (vehicle->sub_state == 2) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; return; } @@ -4975,9 +4895,7 @@ static void vehicle_update_rotating(rct_vehicle* vehicle) if (ride->type == RIDE_TYPE_ENTERPRISE && vehicle->sub_state == 2) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; return; } @@ -5007,9 +4925,7 @@ static void vehicle_update_space_rings_operating(rct_vehicle* vehicle) } else { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } } @@ -5037,9 +4953,7 @@ static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle) if (vehicle->current_time + 1 > 1500) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; return; } @@ -5082,9 +4996,7 @@ static void vehicle_update_crooked_house_operating(rct_vehicle* vehicle) // Originally used an array of size 1 at 0x009A0AC4 and passed the sub state into it. if ((uint16_t)(vehicle->current_time + 1) > 600) { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; return; } @@ -5120,9 +5032,7 @@ static void vehicle_update_top_spin_operating(rct_vehicle* vehicle) return; } - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } @@ -5145,9 +5055,7 @@ static void vehicle_update_showing_film(rct_vehicle* vehicle) } else { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } } @@ -5168,9 +5076,7 @@ static void vehicle_update_doing_circus_show(rct_vehicle* vehicle) } else { - vehicle->status = VEHICLE_STATUS_ARRIVING; - vehicle_invalidate_window(vehicle); - vehicle->sub_state = 0; + vehicle->SetState(VEHICLE_STATUS_ARRIVING); vehicle->var_C0 = 0; } } @@ -5289,9 +5195,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) vehicle_simulate_crash(vehicle); return; } - - vehicle->status = VEHICLE_STATUS_CRASHED; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_CRASHED, vehicle->sub_state); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { @@ -5349,9 +5253,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) vehicle_simulate_crash(vehicle); return; } - - vehicle->status = VEHICLE_STATUS_CRASHED; - vehicle_invalidate_window(vehicle); + vehicle->SetState(VEHICLE_STATUS_CRASHED, vehicle->sub_state); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { @@ -10038,6 +9940,13 @@ const rct_vehicle* rct_vehicle::GetCar(size_t carIndex) const return car; } +void rct_vehicle::SetState(VEHICLE_STATUS vehicleStatus, uint8_t subState) +{ + status = vehicleStatus; + sub_state = subState; + vehicle_invalidate_window(this); +} + bool rct_vehicle::IsGhost() const { auto r = get_ride(ride); diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 91bc5830e1..9b886774cf 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -111,6 +111,41 @@ enum VEHICLE_TYPE : uint8_t VEHICLE_TYPE_TAIL = 1, }; +enum VEHICLE_STATUS +{ + VEHICLE_STATUS_MOVING_TO_END_OF_STATION, + VEHICLE_STATUS_WAITING_FOR_PASSENGERS, + VEHICLE_STATUS_WAITING_TO_DEPART, + VEHICLE_STATUS_DEPARTING, + VEHICLE_STATUS_TRAVELLING, + VEHICLE_STATUS_ARRIVING, + VEHICLE_STATUS_UNLOADING_PASSENGERS, + VEHICLE_STATUS_TRAVELLING_BOAT, + VEHICLE_STATUS_CRASHING, + VEHICLE_STATUS_CRASHED, + VEHICLE_STATUS_TRAVELLING_DODGEMS, + VEHICLE_STATUS_SWINGING, + VEHICLE_STATUS_ROTATING, + VEHICLE_STATUS_FERRIS_WHEEL_ROTATING, + VEHICLE_STATUS_SIMULATOR_OPERATING, + VEHICLE_STATUS_SHOWING_FILM, + VEHICLE_STATUS_SPACE_RINGS_OPERATING, + VEHICLE_STATUS_TOP_SPIN_OPERATING, + VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING, + VEHICLE_STATUS_DOING_CIRCUS_SHOW, + VEHICLE_STATUS_CROOKED_HOUSE_OPERATING, + VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT, + VEHICLE_STATUS_TRAVELLING_CABLE_LIFT, + VEHICLE_STATUS_STOPPING, + VEHICLE_STATUS_WAITING_FOR_PASSENGERS_17, + VEHICLE_STATUS_WAITING_TO_START, + VEHICLE_STATUS_STARTING, + VEHICLE_STATUS_OPERATING_1A, + VEHICLE_STATUS_STOPPING_1B, + VEHICLE_STATUS_UNLOADING_PASSENGERS_1C, + VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES +}; + struct rct_vehicle : rct_sprite_common { uint8_t vehicle_sprite_type; // 0x1F @@ -167,7 +202,7 @@ struct rct_vehicle : rct_sprite_common int16_t var_4E; int16_t crash_z; // 0x4E }; - uint8_t status; // 0x50 + VEHICLE_STATUS status; // 0x50 uint8_t sub_state; // 0x51 uint16_t peep[32]; // 0x52 uint8_t peep_tshirt_colours[32]; // 0x92 @@ -235,6 +270,7 @@ struct rct_vehicle : rct_sprite_common const rct_vehicle* GetHead() const; const rct_vehicle* GetCar(size_t carIndex) const; void Invalidate(); + void SetState(VEHICLE_STATUS vehicleStatus, uint8_t subState = 0); bool IsGhost() const; }; @@ -315,41 +351,6 @@ enum VEHICLE_ENTRY_ANIMATION_MULTI_DIM_COASTER }; -enum -{ - VEHICLE_STATUS_MOVING_TO_END_OF_STATION, - VEHICLE_STATUS_WAITING_FOR_PASSENGERS, - VEHICLE_STATUS_WAITING_TO_DEPART, - VEHICLE_STATUS_DEPARTING, - VEHICLE_STATUS_TRAVELLING, - VEHICLE_STATUS_ARRIVING, - VEHICLE_STATUS_UNLOADING_PASSENGERS, - VEHICLE_STATUS_TRAVELLING_BOAT, - VEHICLE_STATUS_CRASHING, - VEHICLE_STATUS_CRASHED, - VEHICLE_STATUS_TRAVELLING_DODGEMS, - VEHICLE_STATUS_SWINGING, - VEHICLE_STATUS_ROTATING, - VEHICLE_STATUS_FERRIS_WHEEL_ROTATING, - VEHICLE_STATUS_SIMULATOR_OPERATING, - VEHICLE_STATUS_SHOWING_FILM, - VEHICLE_STATUS_SPACE_RINGS_OPERATING, - VEHICLE_STATUS_TOP_SPIN_OPERATING, - VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING, - VEHICLE_STATUS_DOING_CIRCUS_SHOW, - VEHICLE_STATUS_CROOKED_HOUSE_OPERATING, - VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT, - VEHICLE_STATUS_TRAVELLING_CABLE_LIFT, - VEHICLE_STATUS_STOPPING, - VEHICLE_STATUS_WAITING_FOR_PASSENGERS_17, - VEHICLE_STATUS_WAITING_TO_START, - VEHICLE_STATUS_STARTING, - VEHICLE_STATUS_OPERATING_1A, - VEHICLE_STATUS_STOPPING_1B, - VEHICLE_STATUS_UNLOADING_PASSENGERS_1C, - VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES -}; - enum : uint32_t { VEHICLE_UPDATE_FLAG_ON_LIFT_HILL = (1 << 0), From 4fa77e1f719429a78e0d0a0ee832e8d1a99b336d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 9 Jun 2019 16:08:29 +0100 Subject: [PATCH 455/506] Fix the build --- src/openrct2/actions/RideSetStatus.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp index b3dc025048..66662bc996 100644 --- a/src/openrct2/actions/RideSetStatus.hpp +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -165,7 +165,7 @@ public: ride->race_winner = SPRITE_INDEX_NULL; ride->current_issues = 0; ride->last_issue_time = 0; - ride_get_measurement(ride, nullptr); + ride_get_measurement(ride); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; window_invalidate_by_number(WC_RIDE, _rideIndex); break; From ba040fcd6afde476882df330e6cd39189b77b9d8 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 9 Jun 2019 19:18:04 +0100 Subject: [PATCH 456/506] Fix clang format (#9393) --- src/openrct2/ride/Ride.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 1c44c27303..8bf3821c47 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -3039,7 +3039,8 @@ void ride_measurements_update() FOR_ALL_RIDES (i, ride) { auto measurement = ride->measurement.get(); - if (measurement != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) && ride->status != RIDE_STATUS_SIMULATING) + if (measurement != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) + && ride->status != RIDE_STATUS_SIMULATING) { if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) { From 712c2d9b674326f0b1b087f4ab1c4799f3e67f27 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 10 Jun 2019 04:00:22 +0000 Subject: [PATCH 457/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/cs-CZ.txt | 2 ++ data/language/en-US.txt | 1 + data/language/nl-NL.txt | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/data/language/cs-CZ.txt b/data/language/cs-CZ.txt index fbd20194fa..c03ebfa871 100644 --- a/data/language/cs-CZ.txt +++ b/data/language/cs-CZ.txt @@ -3794,6 +3794,8 @@ STR_6323 :Probíhá simulace STR_6324 :Simulovat STR_6325 :{SMALLFONT}{BLACK}Simulovat atrakci STR_6326 :Nelze simulovat {POP16}{POP16}{POP16}{STRINGID}... +STR_6327 :Průhledné pozadí pro velké screenshoty +STR_6328 :{SMALLFONT}{BLACK}Velké snímky obrazovky budou mít průhledné pozadí namísto výchozí černé barvy. ############################################################################### ## RCT2 Scenarios diff --git a/data/language/en-US.txt b/data/language/en-US.txt index cbfde7af19..29f092b8ab 100644 --- a/data/language/en-US.txt +++ b/data/language/en-US.txt @@ -239,6 +239,7 @@ STR_6206 :Gray stucco STR_6212 :Gray sandstone STR_6274 :Can't set color scheme... STR_6307 :Color scheme: {BLACK}{STRINGID} +STR_6328 :{SMALLFONT}{BLACK}With this option enabled, giant screenshots will have a transparent background instead of the default black color. ############# # Scenarios # diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index 37c67a8feb..af8b24e7ee 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -224,7 +224,7 @@ STR_0822 :Kan bestand met grafische gegevens niet openen STR_0823 :Ontbrekend of ontoegankelijk gegevensbestand STR_0824 :{BLACK}❌ STR_0825 :Gekozen naam is al in gebruik -STR_0826 :Teveel namen gedefinieerd +STR_0826 :Te veel namen gedefinieerd STR_0827 :Onvoldoende geld - {CURRENCY2DP} benodigd STR_0828 :{SMALLFONT}{BLACK}Venster sluiten STR_0829 :{SMALLFONT}{BLACK}Venstertitel - Sleep dit om het venster te verplaatsen @@ -365,7 +365,7 @@ STR_0983 :Onderzoek & Ontwikkeling STR_0984 :{WINDOW_COLOUR_2}▲{BLACK} {CURRENCY2DP} STR_0985 :{WINDOW_COLOUR_2}▼{BLACK} {CURRENCY2DP} STR_0986 :{BLACK}{CURRENCY2DP} -STR_0987 :Teveel attracties +STR_0987 :Te veel attracties STR_0988 :Kan geen nieuwe attractie aanmaken… STR_0989 :{STRINGID} STR_0990 :{SMALLFONT}{BLACK}Constructie @@ -1076,7 +1076,7 @@ STR_1695 :{SMALLFONT}{BLACK}Inkomsten en kosten STR_1696 :{SMALLFONT}{BLACK}Klantinformatie STR_1697 :Dit kan niet op wachtrijen worden geplaatst STR_1698 :Dit kan alleen op wachtrijen worden geplaatst -STR_1699 :Teveel personen in het spel +STR_1699 :Te veel personen in het spel STR_1700 :Klusjesman aannemen… STR_1701 :Monteur aannemen… STR_1702 :Bewaker aannemen… @@ -1084,7 +1084,7 @@ STR_1703 :Entertainer aannemen… STR_1704 :Kan geen nieuwe werknemer aannemen… STR_1705 :{SMALLFONT}{BLACK}Deze werknemer ontslaan STR_1706 :{SMALLFONT}{BLACK}Deze persoon naar een andere locatie verplaatsen -STR_1707 :Teveel werknemers in dit park +STR_1707 :Te veel werknemers in dit park STR_1708 :{SMALLFONT}{BLACK}Werkgebied van deze werknemer instellen STR_1709 :Werknemer ontslaan STR_1710 :Ja @@ -2234,7 +2234,7 @@ STR_2976 :{SMALLFONT}{BLACK}Met het geselecteerde kleurenschema een onderdeel STR_2977 :Naam werknemer STR_2978 :Voer een nieuwe naam in voor deze werknemer: STR_2979 :Kan de naam van deze werknemer niet veranderen… -STR_2980 :Teveel lichtkranten in dit park +STR_2980 :Te veel lichtkranten in dit park STR_2981 :{RED}Geen toegang STR_2982 :Lichtkranttekst STR_2983 :Voer een nieuwe tekst in voer deze lichtkrant: @@ -2403,7 +2403,7 @@ STR_3164 :{BLACK}{COMMA16} geselecteerd (maximum: {COMMA16}) STR_3167 :{WINDOW_COLOUR_2}Bevat {BLACK}{COMMA16} objecten STR_3169 :Data voor de volgende objecten niet gevonden: STR_3170 :Niet genoeg ruimte voor graphics. -STR_3171 :er zijn teveel objecten van dit type geselecteerd. +STR_3171 :er zijn te veel objecten van dit type geselecteerd. STR_3172 :De volgende objecten moeten eerst geselecteerd worden: STR_3173 :dit object is momenteel in gebruik. STR_3174 :een ander object is afhankelijk van dit object. @@ -2458,7 +2458,7 @@ STR_3223 :{SMALLFONT}{BLACK}Instellen welk land gekocht kan worden door het p STR_3224 :{SMALLFONT}{BLACK}Instellen voor welk land bouwrechten te koop zijn STR_3225 :{SMALLFONT}{BLACK}Een willekeurig cluster van dit object neerzetten rondom de geselecteerde plek STR_3226 :{SMALLFONT}{BLACK}Parkingang bouwen -STR_3227 :Teveel parkingangen! +STR_3227 :Te veel parkingangen! STR_3228 :{SMALLFONT}{BLACK}Geef startposities voor bezoekers aan STR_3229 :Blokremmen kunnen niet direct na het station geplaatst worden STR_3230 :Blokremmen kunnen niet direct achter elkaar gebruikt worden @@ -2574,7 +2574,7 @@ STR_3343 :Opgeslagen spel omzetten naar scenario STR_3344 :Baanontwerper STR_3345 :Baanontwerpbeheer STR_3346 :Kan baanontwerp niet opslaan -STR_3347 :Attractie is te groot, bevat teveel elementen of het decor is te ver verspreid +STR_3347 :Attractie is te groot, bevat te veel elementen of het decor is te ver verspreid STR_3348 :Hernoemen STR_3349 :Verwijderen STR_3350 :Naam baanontwerp @@ -2599,7 +2599,7 @@ STR_3370 :{BLACK}= Informatiekiosk STR_3371 :{BLACK}= Eerste hulp STR_3372 :{BLACK}= Geldautomaat STR_3373 :{BLACK}= Toilet -STR_3374 :Waarschuwing: teveel objecten geselecteerd! +STR_3374 :Waarschuwing: te veel objecten geselecteerd! STR_3375 :Niet alle objecten in deze decorgroep kunnen worden geselecteerd STR_3376 :Installeren… STR_3377 :{SMALLFONT}{BLACK}Bestand met nieuw baanontwerp installeren @@ -2764,7 +2764,7 @@ STR_5256 :Maak een nieuw thema aan om wijzigingen aan te brengen. STR_5257 :{SMALLFONT}{BLACK}Een nieuw thema aanmaken dat is gebaseerd op het huidige STR_5258 :{SMALLFONT}{BLACK}Het huidige thema verwijderen STR_5259 :{SMALLFONT}{BLACK}Het huidige thema hernoemen -STR_5260 :Enorm screenshot +STR_5260 :Reuzenscreenshot STR_5261 :Filter STR_5262 :Wacky Worlds STR_5263 :Time Twister @@ -3789,6 +3789,8 @@ STR_6323 :Simulatie STR_6324 :Simuleren STR_6325 :{SMALLFONT}{BLACK}Testrit simuleren STR_6326 :Kan {POP16}{POP16}{POP16}{STRINGID} niet in simulatiemodus zetten... +STR_6327 :Reuzenscreenshots hebben transparante achtergrond +STR_6328 :{SMALLFONT}{BLACK}Als deze optie is ingeschakeld, worden reuzenscreenshots met een transparante achtergrond genomen, in plaats van de zwarte standaardachtergrond. ############# # Scenarios # From 1993704e8f29317daab8eb84e4c0d53486a96659 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 10 Jun 2019 22:34:29 +0200 Subject: [PATCH 458/506] Add #8553 to changelog [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 8889f4e270..c6a1e6e4b5 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -37,6 +37,7 @@ - Fix: [#8480, #8535] Crash when mirroring track design. - Fix: [#8507] Incorrect change in vehicle rolling direction. - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. +- Fix: [#8553] Scenery removal tool removes fences and paths while paused. - Fix: [#8598] Taking screenshots fails with some park names. - Fix: [#8649] Setting date does not work in multiplayer. - Fix: [#8873] Potential crash when placing footpaths. From b65e2434863024a1fe383093a542672e18d99fb8 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 10 Jun 2019 22:51:13 +0200 Subject: [PATCH 459/506] Fix #9398: Observation tower vehicle is coloured incorrectly --- src/openrct2/ride/gentle/ObservationTower.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/gentle/ObservationTower.cpp b/src/openrct2/ride/gentle/ObservationTower.cpp index 14ef1225a5..694a2242ce 100644 --- a/src/openrct2/ride/gentle/ObservationTower.cpp +++ b/src/openrct2/ride/gentle/ObservationTower.cpp @@ -54,7 +54,7 @@ void vehicle_visual_observation_tower( baseImage_id = (vehicle->animation_frame * 2) + vehicleEntry->base_image_id + 8; } - image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_3(vehicle->colours.body_colour, vehicle->colours.trim_colour << 24); + image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_3(vehicle->colours.body_colour, vehicle->colours.trim_colour); if (vehicle->IsGhost()) { image_id = (image_id & 0x7FFFF) | CONSTRUCTION_MARKER; From 82fd212834ce7613d1bd6990a439b9a9020c8f32 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Jun 2019 05:10:05 +0200 Subject: [PATCH 460/506] Fix #8859: Network gCheatsEnableAllDrawableTrackPieces on initial join --- src/openrct2/network/Network.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 90ed7a0a8a..c264c5573f 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -2918,6 +2918,7 @@ bool Network::LoadMap(IStream* stream) gGamePaused = stream->ReadValue(); _guestGenerationProbability = stream->ReadValue(); _suggestedGuestMaximum = stream->ReadValue(); + gCheatsEnableAllDrawableTrackPieces = stream->ReadValue() != 0; gCheatsSandboxMode = stream->ReadValue() != 0; gCheatsDisableClearanceChecks = stream->ReadValue() != 0; gCheatsDisableSupportLimits = stream->ReadValue() != 0; @@ -2965,6 +2966,7 @@ bool Network::SaveMap(IStream* stream, const std::vectorWriteValue(gGamePaused); stream->WriteValue(_guestGenerationProbability); stream->WriteValue(_suggestedGuestMaximum); + stream->WriteValue(gCheatsEnableAllDrawableTrackPieces); stream->WriteValue(gCheatsSandboxMode); stream->WriteValue(gCheatsDisableClearanceChecks); stream->WriteValue(gCheatsDisableSupportLimits); From 92129f01d04068b1dfa5fca4df83fa9180b5d6f0 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Jun 2019 05:10:27 +0200 Subject: [PATCH 461/506] Bump up 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 c264c5573f..190a95f02a 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 "38" +#define NETWORK_STREAM_VERSION "39" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 288921132d628a79cb406502a3b0ec40fe37487e Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 11 Jun 2019 04:00:22 +0000 Subject: [PATCH 462/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/da-DK.txt | 7 +++++++ data/language/ko-KR.txt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 02e57f55d0..0e196d94e7 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3792,6 +3792,13 @@ STR_6318 :Netværks synkroniseringsfejl.{NEWLINE}Log fil: {STRING} STR_6319 :{WINDOW_COLOUR_2}Blok Bremse tilkoblet STR_6320 :{WINDOW_COLOUR_2}Uforgængelig STR_6321 :{WINDOW_COLOUR_2}Tilføjelse defekt +STR_6322 :{WINDOW_COLOUR_2}Sprite Id: {BLACK}{INT32} +STR_6323 :Simulérer +STR_6324 :Simulér +STR_6325 :{SMALLFONT}{BLACK}Simulér forlystelse/attraktion +STR_6326 :Kan ikke simulére {POP16}{POP16}{POP16}{STRINGID}... +STR_6327 :Transparent baggrund for gigantisk Skærmbillede +STR_6328 :{SMALLFONT}{BLACK}Med denne indstilling aktiveret, vil gigantisk skærmbillede have transparent baggrund i stedet for en standard sort baggrund. ############# # Scenarios # diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index f828d8c7a3..5eabb82a68 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -3782,6 +3782,8 @@ STR_6323 :가상 운행 중 STR_6324 :가상 운행 STR_6325 :{SMALLFONT}{BLACK}놀이기구 가상 운행 STR_6326 :{POP16}{POP16}{POP16}{STRINGID}의 가상 운행을 시작할 수 없습니다... +STR_6327 :초대형 스크린 샷의 배경을 투명하게 처리 +STR_6328 :{SMALLFONT}{BLACK}이 설정을 켜면, 초대형 스크린 샷을 찍을 경우 배경색이 기본 검은색 대신 투명으로 처리됩니다. ############# From 9a23234631facb506fa107a3dbfc75502f1b6f40 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Jun 2019 05:23:18 +0200 Subject: [PATCH 463/506] Fix #9388: Crash using set grass length cheat --- src/openrct2/actions/SetCheatAction.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp index 06ed56b4f3..9835ec4946 100644 --- a/src/openrct2/actions/SetCheatAction.hpp +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -356,7 +356,11 @@ private: { for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++) { - auto surfaceElement = map_get_surface_element_at(x, y)->AsSurface(); + auto tileElement = map_get_surface_element_at(x, y); + if (tileElement == nullptr) + continue; + + auto surfaceElement = tileElement->AsSurface(); if (surfaceElement != nullptr && (surfaceElement->GetOwnership() & OWNERSHIP_OWNED) && surfaceElement->GetWaterHeight() == 0 && surfaceElement->CanGrassGrow()) { From ea7374b332e660887d8f6200735809a9dcfa69a6 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Jun 2019 17:50:17 +0200 Subject: [PATCH 464/506] Bump up 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 190a95f02a..927e2a5858 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 "39" +#define NETWORK_STREAM_VERSION "40" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 3162d4dc7510bc2a9d92b4b8e54e3e656d449ff4 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 15 May 2019 21:15:23 +0100 Subject: [PATCH 465/506] 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 466/506] 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 467/506] 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 468/506] 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; From ea0483c4a9cb1777932e641a81ef62921e8bd48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 12 Jun 2019 19:43:46 +0200 Subject: [PATCH 469/506] Add libgtest-dev to Ubuntu AMD64 image (#9405) See discussion in https://github.com/OpenRCT2/OpenRCT2/pull/9404#issuecomment-501012361 https://packages.ubuntu.com/bionic/libgtest-dev --- dockerfiles/ubuntu_amd64/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfiles/ubuntu_amd64/Dockerfile b/dockerfiles/ubuntu_amd64/Dockerfile index 9e241e6aea..ab42979445 100644 --- a/dockerfiles/ubuntu_amd64/Dockerfile +++ b/dockerfiles/ubuntu_amd64/Dockerfile @@ -36,4 +36,4 @@ RUN \ RUN apt-get -y upgrade # clang and gcc already installed -RUN apt-get install --no-install-recommends -y ccache cmake libsdl2-dev libsdl2-ttf-dev pkg-config libjansson-dev libspeex-dev libspeexdsp-dev libcurl4-openssl-dev libcrypto++-dev libfontconfig1-dev libfreetype6-dev libpng-dev libzip-dev git libssl-dev ninja-build libicu-dev +RUN apt-get install --no-install-recommends -y ccache cmake libsdl2-dev libsdl2-ttf-dev pkg-config libjansson-dev libspeex-dev libspeexdsp-dev libcurl4-openssl-dev libcrypto++-dev libfontconfig1-dev libfreetype6-dev libpng-dev libzip-dev git libssl-dev ninja-build libicu-dev libgtest-dev From 082f969fabfe20559b8fd72395dab1e976fc5cb9 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 11 Jun 2019 18:40:41 +0100 Subject: [PATCH 470/506] Fix #9396. Pass the ghost flag to banner remove to prevent invalid removal. Previously this would never have happened because the old code would do a scenery ghost removal before calling anything else. I think this is a better way of handling it though and don't want to revert to the old method --- src/openrct2/actions/FootpathRemoveAction.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/FootpathRemoveAction.hpp b/src/openrct2/actions/FootpathRemoveAction.hpp index 34d8fce962..afac55edc2 100644 --- a/src/openrct2/actions/FootpathRemoveAction.hpp +++ b/src/openrct2/actions/FootpathRemoveAction.hpp @@ -157,7 +157,8 @@ private: auto bannerRemoveAction = BannerRemoveAction( { x, y, tileElement->base_height * 8, tileElement->AsBanner()->GetPosition() }); - bannerRemoveAction.SetFlags(GetFlags()); + auto bannerFlags = GetFlags() | (tileElement->IsGhost() ? static_cast(GAME_COMMAND_FLAG_GHOST) : 0); + bannerRemoveAction.SetFlags(bannerFlags); GameActions::ExecuteNested(&bannerRemoveAction); tileElement--; } From 501e4ba3f9ed9bb3305a1dfa68877dd65aeb92e6 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 12 Jun 2019 19:18:07 +0100 Subject: [PATCH 471/506] 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 aa1f25d998..cdb9d41643 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 "41" +#define NETWORK_STREAM_VERSION "42" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From e5972f8a67b8ca98b4b81e276defeb7a4c5b91f0 Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 12 Jun 2019 21:16:40 +0100 Subject: [PATCH 472/506] Fix #9401, Fix #9387. Check for tile element before deref. (#9409) This fixes two crashes that can occur when surface elements are deleted. For normal play you should never delete a surface element as the game expects there to be a surface element on all usable terrain. --- src/openrct2/paint/tile_element/Paint.Surface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 27b7cba907..f911f2663c 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -515,7 +515,8 @@ static void viewport_surface_smoothen_edge( static bool tile_is_inside_clip_view(const tile_descriptor& tile) { - Guard::ArgumentNotNull(tile.tile_element); + if (tile.tile_element == nullptr) + return false; if (tile.tile_element->base_height > gClipHeight) return false; @@ -584,7 +585,7 @@ static void viewport_surface_draw_tile_side_bottom( neighbourCornerHeight1 = MINIMUM_LAND_HEIGHT / 2; } - if (isWater) + if (isWater && neighbour.tile_element != nullptr) { uint8_t waterHeight = neighbour.tile_element->AsSurface()->GetWaterHeight(); if (waterHeight == height && !neighbourIsClippedAway) From 3933e2ffc606eae16830248ca59fae4fb59d2a91 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 12 Jun 2019 22:20:00 +0200 Subject: [PATCH 473/506] Fix #9402: Ad campaigns disappear when you save and load the game --- distribution/changelog.txt | 1 + src/openrct2/rct2/S6Exporter.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index c6a1e6e4b5..4fc17781fb 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -55,6 +55,7 @@ - Fix: [#9240] Crash when passing directory instead of save file. - Fix: [#9293] Issue with the native load/save dialog. - Fix: [#9322] Peep crashing the game trying to find a ride to look at. +- Fix: [#9402] Ad campaigns disappear when you save and load the game. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index a9e4a79cd2..1772a19fb2 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -794,7 +794,7 @@ void S6Exporter::ExportMarketingCampaigns() std::memset(_s6.campaign_ride_index, 0, sizeof(_s6.campaign_ride_index)); for (const auto& campaign : gMarketingCampaigns) { - _s6.campaign_weeks_left[campaign.Type] = campaign.WeeksLeft; + _s6.campaign_weeks_left[campaign.Type] = campaign.WeeksLeft | CAMPAIGN_ACTIVE_FLAG; if (campaign.Type == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign.Type == ADVERTISING_CAMPAIGN_RIDE) { _s6.campaign_ride_index[campaign.Type] = campaign.RideId; From 72c4baebda40c56f5147468be4e2e0721014e7c0 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 12 Jun 2019 22:31:16 +0200 Subject: [PATCH 474/506] Fix #9411: Ad campaigns end too soon --- distribution/changelog.txt | 1 + src/openrct2/actions/ParkMarketingAction.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 4fc17781fb..dfc0c60f14 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -56,6 +56,7 @@ - Fix: [#9293] Issue with the native load/save dialog. - Fix: [#9322] Peep crashing the game trying to find a ride to look at. - Fix: [#9402] Ad campaigns disappear when you save and load the game. +- Fix: [#9411] Ad campaigns end too soon. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/actions/ParkMarketingAction.hpp b/src/openrct2/actions/ParkMarketingAction.hpp index 8de0b7e87f..607d0c1249 100644 --- a/src/openrct2/actions/ParkMarketingAction.hpp +++ b/src/openrct2/actions/ParkMarketingAction.hpp @@ -71,6 +71,7 @@ public: MarketingCampaign campaign{}; campaign.Type = _type; campaign.WeeksLeft = _numWeeks; + campaign.Flags = MarketingCampaignFlags::FIRST_WEEK; if (campaign.Type == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign.Type == ADVERTISING_CAMPAIGN_RIDE) { campaign.RideId = _item; From 9effe21dd0074b834c9e061f1d408aa716409569 Mon Sep 17 00:00:00 2001 From: aw20368 Date: Thu, 13 Jun 2019 14:03:53 -0400 Subject: [PATCH 475/506] Fix #8602: Wall piece collision detection deviates from vanilla (#9414) Wall piece collision used the base height of the wall. Changed to use the clearance height. --- distribution/changelog.txt | 1 + src/openrct2/paint/tile_element/Paint.Wall.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index c6a1e6e4b5..693d3bf764 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -39,6 +39,7 @@ - Fix: [#8537] Imported RCT1 rides/shops are all numbered 1. - Fix: [#8553] Scenery removal tool removes fences and paths while paused. - Fix: [#8598] Taking screenshots fails with some park names. +- Fix: [#8602] Wall piece collision detection deviates from vanilla - Fix: [#8649] Setting date does not work in multiplayer. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8882] Submarine Ride does not count as indoors (original bug). diff --git a/src/openrct2/paint/tile_element/Paint.Wall.cpp b/src/openrct2/paint/tile_element/Paint.Wall.cpp index 652d8af0e7..f2ebe4a6df 100644 --- a/src/openrct2/paint/tile_element/Paint.Wall.cpp +++ b/src/openrct2/paint/tile_element/Paint.Wall.cpp @@ -187,7 +187,7 @@ void fence_paint(paint_session* session, uint8_t direction, int32_t height, cons imageColourFlags &= 0x0DFFFFFFF; } - paint_util_set_general_support_height(session, height, 0x20); + paint_util_set_general_support_height(session, 8 * tile_element->clearance_height, 0x20); uint32_t dword_141F710 = 0; if (gTrackDesignSaveMode || (session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) From 357273fe7d407d19ab87b382b25a97e712ba9451 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 13 Jun 2019 19:31:49 +0100 Subject: [PATCH 476/506] Refund the removal cost of banners on paths. Found a small bug in the banner removal on paths code --- src/openrct2/actions/FootpathRemoveAction.hpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/openrct2/actions/FootpathRemoveAction.hpp b/src/openrct2/actions/FootpathRemoveAction.hpp index afac55edc2..eb29c3f215 100644 --- a/src/openrct2/actions/FootpathRemoveAction.hpp +++ b/src/openrct2/actions/FootpathRemoveAction.hpp @@ -90,7 +90,11 @@ public: if (footpathElement != nullptr) { footpath_queue_chain_reset(); - RemoveBannersAtElement(_x, _y, footpathElement); + auto bannerRes = RemoveBannersAtElement(_x, _y, footpathElement); + if (bannerRes->Error == GA_ERROR::OK) + { + res->Cost += bannerRes->Cost; + } footpath_remove_edges_at(_x, _y, footpathElement); map_invalidate_tile_full(_x, _y); tile_element_remove(footpathElement); @@ -101,7 +105,7 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_FOOTPATH_FROM_HERE); } - res->Cost = GetRefundPrice(footpathElement); + res->Cost += GetRefundPrice(footpathElement); return res; } @@ -146,8 +150,9 @@ private: * * rct2: 0x006BA23E */ - void RemoveBannersAtElement(int32_t x, int32_t y, TileElement * tileElement) const + GameActionResult::Ptr RemoveBannersAtElement(int32_t x, int32_t y, TileElement * tileElement) const { + auto result = MakeResult(); while (!(tileElement++)->IsLastForTile()) { if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH) @@ -157,9 +162,15 @@ private: auto bannerRemoveAction = BannerRemoveAction( { x, y, tileElement->base_height * 8, tileElement->AsBanner()->GetPosition() }); - auto bannerFlags = GetFlags() | (tileElement->IsGhost() ? static_cast(GAME_COMMAND_FLAG_GHOST) : 0); + bool isGhost = tileElement->IsGhost(); + auto bannerFlags = GetFlags() | (isGhost ? static_cast(GAME_COMMAND_FLAG_GHOST) : 0); bannerRemoveAction.SetFlags(bannerFlags); - GameActions::ExecuteNested(&bannerRemoveAction); + auto res = GameActions::ExecuteNested(&bannerRemoveAction); + // Ghost removal is free + if (res->Error == GA_ERROR::OK && !isGhost) + { + result->Cost += res->Cost; + } tileElement--; } } From a0b77c4bffe78707e3c6a14f1ccadbdb391f9137 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 13 Jun 2019 19:33:37 +0100 Subject: [PATCH 477/506] return the value --- src/openrct2/actions/FootpathRemoveAction.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/FootpathRemoveAction.hpp b/src/openrct2/actions/FootpathRemoveAction.hpp index eb29c3f215..7f7adb7858 100644 --- a/src/openrct2/actions/FootpathRemoveAction.hpp +++ b/src/openrct2/actions/FootpathRemoveAction.hpp @@ -156,7 +156,7 @@ private: while (!(tileElement++)->IsLastForTile()) { if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH) - return; + return result; else if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER) continue; @@ -173,5 +173,6 @@ private: } tileElement--; } + return result; } }; From 2044dbcad5748d4e04271e500c859a316c7d47f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 16 Jun 2019 13:40:15 +0200 Subject: [PATCH 478/506] Fix #9324: crash trying to remove invalid footpath scenery --- distribution/changelog.txt | 1 + src/openrct2/actions/FootpathSceneryRemoveAction.hpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 73378915d7..ea6036e890 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -56,6 +56,7 @@ - Fix: [#9240] Crash when passing directory instead of save file. - Fix: [#9293] Issue with the native load/save dialog. - Fix: [#9322] Peep crashing the game trying to find a ride to look at. +- Fix: [#9324] Crash trying to remove invalid footpath scenery. - Fix: [#9402] Ad campaigns disappear when you save and load the game. - Fix: [#9411] Ad campaigns end too soon. - Fix: Guests eating popcorn are drawn as if they're eating pizza. diff --git a/src/openrct2/actions/FootpathSceneryRemoveAction.hpp b/src/openrct2/actions/FootpathSceneryRemoveAction.hpp index 9d96e1dc66..70b40ff6d9 100644 --- a/src/openrct2/actions/FootpathSceneryRemoveAction.hpp +++ b/src/openrct2/actions/FootpathSceneryRemoveAction.hpp @@ -69,17 +69,22 @@ public: } auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); - auto pathElement = tileElement->AsPath(); + if (tileElement == nullptr) + { + log_warning("Could not find path element."); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); + } + auto pathElement = tileElement->AsPath(); if (pathElement == nullptr) { - log_error("Could not find path element."); + log_warning("Could not find path element."); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS); } if (!pathElement->AdditionIsGhost() && (GetFlags() & GAME_COMMAND_FLAG_GHOST)) { - log_error("Tried to remove non ghost during ghost removal."); + log_warning("Tried to remove non ghost during ghost removal."); return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_REMOVE_THIS); } auto res = MakeResult(); From 6b7fee86bbdc83651c35b5fb2e8d70dc6ff5ad7f Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Sun, 16 Jun 2019 16:42:21 +0200 Subject: [PATCH 479/506] Don't clear the screen to black for giant screenshots When certain viewport flags were set (underground view, hide base land, hide vetical faces, clip view), the viewport would always be cleared, including for giant screenshots. --- src/openrct2/interface/Viewport.cpp | 8 +++++--- src/openrct2/paint/tile_element/Paint.TileElement.cpp | 2 +- src/openrct2/sprites.h | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 7c661bdabb..4063fe882b 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -845,12 +845,14 @@ static void viewport_fill_column(paint_session* session) static void viewport_paint_column(paint_session* session) { if (session->ViewFlags - & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_CLIP_VIEW)) + & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE + | VIEWPORT_FLAG_CLIP_VIEW) + && (~session->ViewFlags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND)) { - uint8_t colour = 10; + uint8_t colour = COLOUR_AQUAMARINE; if (session->ViewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) { - colour = 0; + colour = COLOUR_BLACK; } gfx_clear(&session->DPI, colour); } diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index baab66d438..619c421b4b 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -125,7 +125,7 @@ static void blank_tiles_paint(paint_session* session, int32_t x, int32_t y) session->SpritePosition.x = x; session->SpritePosition.y = y; session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; - sub_98196C(session, 3123, 0, 0, 32, 32, -1, 16); + sub_98196C(session, SPR_BLANK_TILE, 0, 0, 32, 32, -1, 16); } bool gShowSupportSegmentHeights = false; diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index cc108d0dc4..8c37667de7 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -39,6 +39,8 @@ enum PEEP_SPAWN_ARROW_2 = 3113, PEEP_SPAWN_ARROW_3 = 3114, + SPR_BLANK_TILE = 3123, + // This is the start of every character there are // 224 characters per font (first 32 are control codes hence why it doesn't go to 255) // 4 fonts From 7c0f04903ecb38e2744b12bbfeff18fd7781585b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 16 Jun 2019 17:43:53 +0200 Subject: [PATCH 480/506] Fix crash with truetype fonts and multi threading (#9424) --- distribution/changelog.txt | 1 + src/openrct2/drawing/TTF.cpp | 149 +++++++++++++++++++++++------------ 2 files changed, 98 insertions(+), 52 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index ea6036e890..b7a1a599b7 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -59,6 +59,7 @@ - Fix: [#9324] Crash trying to remove invalid footpath scenery. - Fix: [#9402] Ad campaigns disappear when you save and load the game. - Fix: [#9411] Ad campaigns end too soon. +- Fix: [#9424] Crash using multi threading with TrueType fonts. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index 2489d90d15..b7d2a079f0 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -9,6 +9,8 @@ #ifndef NO_TTF +# include +# include # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation" # include @@ -53,6 +55,8 @@ static int32_t _ttfGetWidthCacheCount = 0; static int32_t _ttfGetWidthCacheHitCount = 0; static int32_t _ttfGetWidthCacheMissCount = 0; +static std::mutex _mutex; + static TTF_Font* ttf_open_font(const utf8* fontPath, int32_t ptSize); static void ttf_close_font(TTF_Font* font); static uint32_t ttf_surface_cache_hash(TTF_Font* font, const utf8* text); @@ -60,63 +64,111 @@ static void ttf_surface_cache_dispose(ttf_cache_entry* entry); static void ttf_surface_cache_dispose_all(); static void ttf_getwidth_cache_dispose_all(); static bool ttf_get_size(TTF_Font* font, const utf8* text, int32_t* width, int32_t* height); +static void ttf_toggle_hinting(bool); static TTFSurface* ttf_render(TTF_Font* font, const utf8* text); +template class FontLockHelper +{ + T& _mutex; + const bool _enabled; + +public: + FontLockHelper(T& mutex) + : _mutex(mutex) + , _enabled(gConfigGeneral.multithreading) + { + if (_enabled) + _mutex.lock(); + } + ~FontLockHelper() + { + if (_enabled) + _mutex.unlock(); + } +}; + +static void ttf_toggle_hinting(bool) +{ + if (!LocalisationService_UseTrueTypeFont()) + { + return; + } + + for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) + { + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); + bool use_hinting = gConfigFonts.enable_hinting && fontDesc->hinting_threshold; + TTF_SetFontHinting(fontDesc->font, use_hinting ? 1 : 0); + } + + if (_ttfSurfaceCacheCount) + { + ttf_surface_cache_dispose_all(); + } +} + bool ttf_initialise() { - if (!_ttfInitialised) + FontLockHelper lock(_mutex); + + if (_ttfInitialised) + return true; + + if (TTF_Init() != 0) { - if (TTF_Init() != 0) + log_error("Couldn't initialise FreeType engine"); + return false; + } + + for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) + { + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); + + utf8 fontPath[MAX_PATH]; + if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) { - log_error("Couldn't initialise FreeType engine"); + log_verbose("Unable to load font '%s'", fontDesc->font_name); return false; } - for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) + fontDesc->font = ttf_open_font(fontPath, fontDesc->ptSize); + if (fontDesc->font == nullptr) { - TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); - - utf8 fontPath[MAX_PATH]; - if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) - { - log_verbose("Unable to load font '%s'", fontDesc->font_name); - return false; - } - - fontDesc->font = ttf_open_font(fontPath, fontDesc->ptSize); - if (fontDesc->font == nullptr) - { - log_verbose("Unable to load '%s'", fontPath); - return false; - } + log_verbose("Unable to load '%s'", fontPath); + return false; } - - ttf_toggle_hinting(); - _ttfInitialised = true; } + + ttf_toggle_hinting(true); + + _ttfInitialised = true; + return true; } void ttf_dispose() { - if (_ttfInitialised) + FontLockHelper lock(_mutex); + + if (!_ttfInitialised) + return; + + ttf_surface_cache_dispose_all(); + ttf_getwidth_cache_dispose_all(); + + for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) { - ttf_surface_cache_dispose_all(); - ttf_getwidth_cache_dispose_all(); - - for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); + if (fontDesc->font != nullptr) { - TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); - if (fontDesc->font != nullptr) - { - ttf_close_font(fontDesc->font); - fontDesc->font = nullptr; - } + ttf_close_font(fontDesc->font); + fontDesc->font = nullptr; } - - TTF_Quit(); - _ttfInitialised = false; } + + TTF_Quit(); + + _ttfInitialised = false; } static TTF_Font* ttf_open_font(const utf8* fontPath, int32_t ptSize) @@ -163,22 +215,8 @@ static void ttf_surface_cache_dispose_all() void ttf_toggle_hinting() { - if (!LocalisationService_UseTrueTypeFont()) - { - return; - } - - for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) - { - TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); - bool use_hinting = gConfigFonts.enable_hinting && fontDesc->hinting_threshold; - TTF_SetFontHinting(fontDesc->font, use_hinting ? 1 : 0); - } - - if (_ttfSurfaceCacheCount) - { - ttf_surface_cache_dispose_all(); - } + FontLockHelper lock(_mutex); + ttf_toggle_hinting(true); } TTFSurface* ttf_surface_cache_get_or_add(TTF_Font* font, const utf8* text) @@ -187,6 +225,9 @@ TTFSurface* ttf_surface_cache_get_or_add(TTF_Font* font, const utf8* text) uint32_t hash = ttf_surface_cache_hash(font, text); int32_t index = hash % TTF_SURFACE_CACHE_SIZE; + + FontLockHelper lock(_mutex); + for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) { entry = &_ttfSurfaceCache[index]; @@ -260,6 +301,9 @@ uint32_t ttf_getwidth_cache_get_or_add(TTF_Font* font, const utf8* text) uint32_t hash = ttf_surface_cache_hash(font, text); int32_t index = hash % TTF_GETWIDTH_CACHE_SIZE; + + FontLockHelper lock(_mutex); + for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) { entry = &_ttfGetWidthCache[index]; @@ -304,6 +348,7 @@ uint32_t ttf_getwidth_cache_get_or_add(TTF_Font* font, const utf8* text) TTFFontDescriptor* ttf_get_font_from_sprite_base(uint16_t spriteBase) { + FontLockHelper lock(_mutex); return &gCurrentTTFFontSet->size[font_get_size_from_sprite_base(spriteBase)]; } From 72f605e2063a04dc0a90cb3d0846a57624487e1b Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 17 Jun 2019 04:00:24 +0000 Subject: [PATCH 481/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/hu-HU.txt | 103 +++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index 966dfebe4d..b6cdadfe4e 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -146,6 +146,7 @@ STR_0563 :Kényelmes, egyszerű biztonsági rudas vonatokban ülve élvezheti STR_0564 :Ez a fa pályán futó hullámvasút gyors, durva, hangos és „kontrollvesztett” utazási élményt nyújt, bőséges „légi idővel” STR_0565 :Egy egyszerű, kizárólag enyhe lejtőkre és fordulókra képes fa hullámvasút, amelyen a kocsikat csak az oldalirányú súrlódásos kerekek és a gravitáció tartja a pályán STR_0566 :Különálló hullámvasút-kocsik száguldanak egy szoros, cikcakkos alaprajzú, éles kanyarokat és rövid meredek eséseket tartalmazó pályán +STR_0573 :Motoros, helikopter formájú kocsik haladnak egy acélpályán, a pedálozó utasok irányításával STR_0578 :A kocsik egy abroncsokkal körbefogott, meredek esésekkel és palástorsókkal teli pálya mentén haladnak STR_0579 :Egy enyhe minigolf-játék STR_0582 :Önvezető légpárnás járművek @@ -468,7 +469,7 @@ STR_1097 :Motoros kilövésű térközszakaszos üzemmód STR_1098 :{POP16}{STRINGID} végébe megy STR_1099 :Utasokra vár itt: {POP16}{STRINGID} STR_1100 :Várja, hogy elhagyhassa ezt: {POP16}{STRINGID} -STR_1101 :{POP16}{STRINGID} elhagyása +STR_1101 :Elhagyja ezt: {POP16}{STRINGID} STR_1102 :{VELOCITY} sebességgel halad STR_1103 :Megérkezik ide: {POP16}{STRINGID} STR_1104 :Kirakja az utasokat itt: {POP16}{STRINGID} @@ -529,7 +530,6 @@ STR_1156 :{MOVE_X}{10}{STRINGID} STR_1157 :✓{MOVE_X}{10}{STRINGID} STR_1159 :{SMALLFONT}{BLACK}Díszletek, kertek és egyéb kiegészítők lerakása STR_1160 :{SMALLFONT}{BLACK}Tavak és vizek létrehozása/módosítása -STR_1173 :{SMALLFONT}{BLACK}Utak és várósorok építése STR_1158 :Nem távolítható el... STR_1161 :Nem rakhatod ide... STR_1162 :{OUTLINE}{TOPAZ}{STRINGID} @@ -541,6 +541,7 @@ STR_1169 :(semmi) STR_1170 :{STRING} STR_1171 :{RED}Zárva STR_1172 :{YELLOW}{STRINGID} +STR_1173 :{SMALLFONT}{BLACK}Utak és várósorok építése STR_1174 :Egy hirdetőtábla útban van STR_1175 :Nem építhető lejtős úton STR_1176 :Nem építhető ide út... @@ -1151,6 +1152,7 @@ STR_1786 :{INLINE_SPRITE}{05}{20}{00}{00} Űrhajós jelmez STR_1787 :{INLINE_SPRITE}{06}{20}{00}{00} Bandita jelmez STR_1788 :{INLINE_SPRITE}{07}{20}{00}{00} Seriff jelmez STR_1789 :{INLINE_SPRITE}{08}{20}{00}{00} Kalóz jelmez +STR_1790 :{SMALLFONT}{BLACK}A választott típusú alkalmazottak által viselt egyenruha színének kiválasztása STR_1791 :{WINDOW_COLOUR_2}Egyenruha színe: STR_1792 :{STRINGID} segélykérésére válaszol STR_1793 :{STRINGID} felé tart ellenőrzésre @@ -1175,6 +1177,7 @@ STR_1812 :{SMALLFONT}{BLACK}{STRINGID} STR_1813 :Egyéb objektumok STR_1814 :Tevékenységek STR_1815 :Gondolatok +STR_1816 :{SMALLFONT}{BLACK}A vendéglistában megjelenítendő információtípus kiválasztása STR_1817 :({COMMA16}) STR_1818 :{WINDOW_COLOUR_2}Minden vendég STR_1819 :{WINDOW_COLOUR_2}Minden vendég (összegezve) @@ -1569,6 +1572,7 @@ STR_2227 :{WINDOW_COLOUR_2}Vállalati érték: {BLACK}{CURRENCY} STR_2228 :{WINDOW_COLOUR_2}Az előző havi nyereség étel/ital és{NEWLINE}szuvenír eladásokból: {BLACK}{CURRENCY} STR_2230 :Függőleges pálya STR_2229 :Emelkedő függőlegeshez +STR_2231 :Rögzítőfék eséshez STR_2232 :Kábeles felvonószakasz STR_2233 :{SMALLFONT}{BLACK}Park információk STR_2234 :Legutóbbi üzenetek @@ -1716,8 +1720,8 @@ STR_2382 :Föld STR_2383 :Víz STR_2384 :{WINDOW_COLOUR_2}A célod: STR_2385 :{BLACK}Nincs -STR_2386 :{BLACK}Legyen legalább {COMMA16} vendég a parkodban {MONTHYEAR} végére, a parkod értékelése pedig legyen legalább 600 -STR_2387 :{BLACK}Legyen legalább {POP16}{POP16}{CURRENCY} a parkod értéke {PUSH16}{PUSH16}{PUSH16}{MONTHYEAR} végére +STR_2386 :{BLACK}Legyen legalább {COMMA16} vendég a parkodban {MONTHYEAR}végére, a parkod értékelése pedig legyen legalább 600 +STR_2387 :{BLACK}Legyen legalább {POP16}{POP16}{CURRENCY} a parkod értéke {PUSH16}{PUSH16}{PUSH16}{MONTHYEAR}végére STR_2388 :{BLACK}Érezd jól magad! STR_2389 :{BLACK}A lehető legjobb {STRINGID} építése! STR_2390 :{BLACK}Építs 10 különböző, egyenként legalább 6,00 izgalmi értékű hullámvasutat a parkodban @@ -2306,6 +2310,7 @@ STR_3065 :Haladó parkok STR_3066 :Nehéz parkok STR_3067 :„Igazi” parkok STR_3068 :Egyéb parkok +STR_3069 :Felső szakasz STR_3070 :Lejtés vízszinthez STR_3071 :{WINDOW_COLOUR_2}Ugyanez az ár mindenhol a parkban STR_3072 :{SMALLFONT}{BLACK}Válaszd ki, hogy ezt az árat használják-e mindenhol a parkban @@ -2363,7 +2368,7 @@ STR_3136 :Figyelmeztetés: A terv alternatív járműtípussal lesz megépít STR_3137 :Közeli díszletek kiválasztása STR_3138 :Kiválasztás törlése STR_3139 :A kábeles felvonó nem tud üzemelni ebben a működési módban -STR_3140 :A kábeles felvonónak közvetlenül az állomás után kell kezdődnie +STR_3140 :A kábeles felvonószakasznak közvetlenül az állomás után kell kezdődnie STR_3142 :{WINDOW_COLOUR_2}Befogadóképesség: {BLACK}{STRINGID} STR_3143 :{SMALLFONT}{BLACK}Emberek megjelenítése a térképen STR_3144 :{SMALLFONT}{BLACK}Játékok és bódék megjelenítése a térképen @@ -2553,10 +2558,10 @@ STR_5138 :{SMALLFONT}{WINDOW_COLOUR_2}{STRINGID} STR_5139 :{WHITE}{STRINGID} STR_5140 :Fékhibák kikapcsolása STR_5141 :Meghibásodások kikapcsolása -STR_5142 :Normál -STR_5143 :Gyors -STR_5144 :Extra gyors -STR_5145 :Turbó +STR_5142 :Normál sebesség +STR_5143 :Gyors sebesség +STR_5144 :Extra gyors sebesség +STR_5145 :Turbó sebesség STR_5146 :Hipersebesség STR_5147 :Csalások STR_5148 :{SMALLFONT}{BLACK}A játék sebességének megváltoztatása @@ -2680,7 +2685,7 @@ STR_5313 :Mezővizsgáló STR_5314 :Mezővizsgáló STR_5315 :Fű STR_5316 :Homok -STR_5317 :Sár +STR_5317 :Föld STR_5318 :Kavics STR_5319 :Marsi STR_5320 :Sakktábla @@ -2729,7 +2734,7 @@ STR_5364 :Kevesebb mint 15 STR_5365 :{BLACK}Személyzet gyors.: STR_5366 :Normál STR_5367 :Gyors -STR_5368 :Ütközés visszaáll. +STR_5368 :Ütközés törlése STR_5369 :Park paraméterei... STR_5370 :{SMALLFONT}{BLACK}Kattints erre a gombra, hogy módosítsd{NEWLINE}a park olyan paramétereit, mint{NEWLINE}a vendégek generálása és a pénz. STR_5371 :Objektum választás @@ -2856,7 +2861,11 @@ STR_5498 :Szerver lista STR_5499 :Játékos neve: STR_5500 :Szerver hozzáadása STR_5501 :Szerver indítása -STR_5506 :A vedégeket nem érdeklik az intenzitások +STR_5502 :Többjátékos mód +STR_5503 :Add meg a gépnevet vagy IP-címet: +STR_5504 :{SMALLFONT}{BLACK}A többjátékos mód állapota +STR_5505 :Nem lehet csatlakozni a szerverhez. +STR_5506 :Vendégeket nem érdeklik az intenzitások STR_5508 :Hibás ellenőrző összegű fájlok engedélyezése STR_5509 :{SMALLFONT}{BLACK}Engedélyezi a hibás ellenőrző összeggel{NEWLINE}rendelkező pályák és mentések{NEWLINE}betöltését, mint például a próbaverzió pályái vagy a sérült mentések. STR_5511 :(ISMERETLEN) @@ -2959,6 +2968,49 @@ STR_5629 :Nehézségi szint STR_5630 :Progresszív feloldás bekapcsolása STR_5631 :Eredeti DLC parkok STR_5632 :Építsd meg a saját... +STR_5635 :{WINDOW_COLOUR_2}Elköltött pénz: {BLACK}{CURRENCY2DP} +STR_5636 :{WINDOW_COLOUR_2}Futtatott parancsok: {BLACK}{COMMA16} +STR_5637 :Ezt nem csinálhatod... +STR_5638 :Engedély megtagadva +STR_5639 :{SMALLFONT}{BLACK}Játékosok listája +STR_5640 :{SMALLFONT}{BLACK}Csoportok kezelése +STR_5641 :Alapértelmezett csoport: +STR_5642 :Csoport +STR_5643 :Új csoport +STR_5644 :Csoport törlése +STR_5645 :Chat +STR_5646 :Terraformálás +STR_5647 :Szünet be/ki +STR_5648 :Vízszint beállítása +STR_5649 :Játék létrehozása +STR_5650 :Játék eltávolítása +STR_5651 :Játék építése +STR_5652 :Játék tulajdonságai +STR_5653 :Díszletek +STR_5654 :Út +STR_5655 :Vendég +STR_5656 :Személyzet +STR_5657 :Park tulajdonságai +STR_5658 :Park finanszírozása +STR_5659 :Játékos kirúgása +STR_5660 :Csoportok módosítása +STR_5661 :Játékoscsoport beállítása +STR_5662 :Nincs adat +STR_5663 :Földterület megtisztítása +STR_5664 :Csalás +STR_5665 :Díszletcsoportok be/ki +STR_5666 :Jelszó nélküli bejelentkezés +STR_5701 :{WINDOW_COLOUR_2}Utolsó tevékenység: {BLACK}{STRINGID} +STR_5702 :{SMALLFONT}{BLACK}A játékos legutóbbi tevékenységének megkeresése +STR_5703 :A hoszt nem rúgható ki +STR_5704 :Utolsó tevékenység +STR_5705 :Nem rakható ebbe a csoportba +STR_5706 :Nem távolítható el olyan csoport, amelybe játékosok tartoznak +STR_5707 :Ez a csoport nem módosítható +STR_5708 :Nem változtatható meg az a csoport, amelybe a hoszt tartozik +STR_5709 :Cs. átnevezése +STR_5710 :Csoport neve +STR_5711 :Írj be egy új nevet a csoport számára: STR_5712 :Nem módosíthatsz olyan engedélyt, amellyel te sem rendelkezel STR_5713 :Játékos kirúgása STR_5714 :Beállítások ablak @@ -2968,7 +3020,7 @@ STR_5716 :Nem engedélyezett a többjátékos módban STR_5717 :Hálózati verzió: {STRING} STR_5718 :{SMALLFONT}{BLACK}Hálózati verzió: {STRING} STR_5719 :Napos -STR_5720 :Részlegesen felhős +STR_5720 :Részben felhős STR_5721 :Felhős STR_5722 :Esős STR_5723 :Heves esőzés @@ -2979,6 +3031,7 @@ STR_5727 :Skálázás minősége: STR_5731 :Lineáris # tooltip for tab in options window STR_5734 :{SMALLFONT}{BLACK}Megjelenítés +STR_5735 :Hálózati állapot STR_5736 :Játékos STR_5737 :Zárva, még {COMMA16} ember van a játékon STR_5738 :Zárva, még {COMMA16} ember van a játékon @@ -2989,11 +3042,18 @@ STR_5742 :Hitelesítés ... STR_5743 :Csatlakozás ... STR_5744 :Feloldás ... STR_5745 :Hálózati szinkronizációs hiba észlelve +STR_5746 :Kilépett +STR_5747 :Kilépett: {STRING} STR_5748 :Kirúgva +STR_5749 :Ki a szerverről! STR_5750 :Kapcsolat lezárva STR_5751 :Nincs adat +STR_5752 :{OUTLINE}{RED}{STRING} kilépett +STR_5753 :{OUTLINE}{RED}{STRING} kilépett ({STRING}) STR_5754 :Hibás játékos név +STR_5755 :Hibás szoftververzió (A szerver ezt használja: {STRING}) STR_5756 :Hibás jelszó +STR_5757 :A szerver megtelt STR_5758 :{OUTLINE}{GREEN}{STRING} csatlakozott a játékhoz STR_5759 :Térkép letöltése ... ({INT32} / {INT32}) KiB STR_5760 :Hongkongi dollár (HK$) @@ -3026,14 +3086,23 @@ STR_5786 :Érvénytelen csoportnév STR_5787 :{COMMA32} játékos van online STR_5788 :Alapértelmezett ellenőrzési idő: STR_5789 :Villámhatás kikapcsolása -STR_5792 :{SMALLFONT}{BLACK}Minden meghibásodott játékot megjavít +STR_5791 :{SMALLFONT}{BLACK}Az összes játék megbízhatóságát 100%-ra{NEWLINE}állítja és visszaállítja az építési idejüket „idén”-re +STR_5792: {SMALLFONT}{BLACK}Megjavítja az összes meghibásodott játékot +STR_5793: {SMALLFONT}{BLACK}Törli a játék ütközési előzményeit,{NEWLINE}így a vendégek nem fognak panaszkodni, hogy nem biztonságos +STR_5794: {SMALLFONT}{BLACK}Néhány pálya nem engedélyezi pár játék{NEWLINE}szerkesztését, melyek már a parkban vannak{NEWLINE}Ez a csalás feloldja a korlátozást +STR_5795: {SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is +STR_5796: {SMALLFONT}{BLACK}Kényszeríti a parkot, hogy kinyisson vagy bezárjon +STR_5797: {SMALLFONT}{BLACK}Letiltja az időjárás-változásokat{NEWLINE}és befagyasztja a jelenlegi időjárást +STR_5798: {SMALLFONT}{BLACK}Engedélyezi az építési tevékenységeket szünet közben +STR_5799: {SMALLFONT}{BLACK}Letiltja a játékok fékhiba miatta meghibásodásait és ütközéseit +STR_5800: {SMALLFONT}{BLACK}Megakadályozza, hogy meghibásodjanak a játékok STR_5801 :Szemetelés kikapcsolása STR_5790 :{SMALLFONT}{BLACK}Az RCT1-stílusú árazás ki- és bekapcsolása{NEWLINE}(például belépési díj egyszerre a parkba és a játékokra) STR_5795 :{SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is STR_5802 :{SMALLFONT}{BLACK}A vendégek nem szemetelnek és hánynak STR_5803 :{SMALLFONT}{BLACK}A kiválasztott térképelem forgatása STR_5804 :Hang némítása -STR_5805 :{SMALLFONT}{BLACK}Ha ki van pipálva, a szervered hozzá lesz adva a{NEWLINE}nyilvános szerverek listájához, így bárki rátalálhat +STR_5805 :{SMALLFONT}{BLACK}Ha ki van pipálva, a szervered hozzá lesz adva{NEWLINE}a nyilvános szerverek listájához, így bárki rátalálhat STR_5806 :Váltás ablakos/teljes képernyős mód között STR_5807 :{WINDOW_COLOUR_2}Játékok száma: {BLACK}{COMMA16} STR_5808 :{WINDOW_COLOUR_2}Boltok és bódék száma: {BLACK}{COMMA16} @@ -3162,6 +3231,7 @@ STR_6034 :{SMALLFONT}{BLACK}{STRING} STR_6035 :Kérlek válaszd ki az RCT1 mappádat STR_6036 :{SMALLFONT}{BLACK}Törlés STR_6037 :Kérlek válassz egy érvényes RCT1 mappát +STR_6040 :Pályabeállítások módosítása STR_6041 :{BLACK}Nem vettél fel gépészt! STR_6052 :A magasságtérkép túl nagy és le lesz vágva STR_6053 :A magasságtérkép nem normalizálható @@ -3422,7 +3492,8 @@ STR_6323 :Szimuláció folyamatban STR_6324 :Szimulálás STR_6325 :{SMALLFONT}{BLACK}Játék/épület szimulálása STR_6326 :{POP16}{POP16}{POP16}{STRINGID} nem szimulálható... - +STR_6327 :Átlátszó hátterű óriás képmentések +STR_6328 :{SMALLFONT}{BLACK}Ha ez az opció ki van jelölve, az óriás képmentések átlátszó hátterűek lesznek az alapértelmezett fekete szín helyett. ############# # Scenarios # From bbd93f93cc0da8419d62c56502bdf8d320ca35e5 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Tue, 18 Jun 2019 21:44:06 +0200 Subject: [PATCH 482/506] Increase maximum height of Hypercoaster to RCT1 limits --- distribution/changelog.txt | 1 + src/openrct2/network/Network.cpp | 2 +- src/openrct2/ride/RideGroupManager.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b7a1a599b7..e151f91139 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -16,6 +16,7 @@ - Change: [#7877] Files are now sorted in logical rather than dictionary order. - Change: [#8427] Ghost elements now show up as white on the mini-map. - Change: [#8688] Move common actions from debug menu into cheats menu. +- Change: [#9428] Increase maximum height of the Hypercoaster to RCT1 limits. - Fix: [#2294] Clients crashing the server with invalid object selection. - Fix: [#4568, #5896] Incorrect fences removed when building a tracked ride through - Fix: [#5103] OpenGL: ride track preview not rendered. diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index cdb9d41643..6e5e854a8f 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 "42" +#define NETWORK_STREAM_VERSION "43" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/ride/RideGroupManager.cpp b/src/openrct2/ride/RideGroupManager.cpp index f6ad697d83..76ca9255b0 100644 --- a/src/openrct2/ride/RideGroupManager.cpp +++ b/src/openrct2/ride/RideGroupManager.cpp @@ -36,7 +36,7 @@ static constexpr const RideGroup ride_group_corkscrew_rc = { static constexpr const RideGroup ride_group_hypercoaster = { /*.RideType =*/RIDE_TYPE_CORKSCREW_ROLLER_COASTER, - /*.MaximumHeight =*/45, + /*.MaximumHeight =*/55, /*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL) | (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_SLOPE) | (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_SLOPE_CURVE_STEEP) | (1ULL << TRACK_S_BEND) | (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_CURVE) From 0a4fa68138da6d70eacfd3e9e69fcaf20b345cd6 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 19 Jun 2019 03:18:58 +0200 Subject: [PATCH 483/506] Fix money effect having random position in multiplayer --- src/openrct2/world/MoneyEffect.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/openrct2/world/MoneyEffect.cpp b/src/openrct2/world/MoneyEffect.cpp index 16680d802d..1b57ecc48b 100644 --- a/src/openrct2/world/MoneyEffect.cpp +++ b/src/openrct2/world/MoneyEffect.cpp @@ -12,6 +12,7 @@ #include "../interface/Viewport.h" #include "../interface/Window.h" #include "../localisation/Localisation.h" +#include "../network/network.h" #include "Map.h" #include "Sprite.h" @@ -80,6 +81,14 @@ void rct_money_effect::Create(money32 value) if (mapPosition.x == LOCATION_NULL) { + // If game actions return no valid location of the action we can not use the screen + // coordinates as every client will have different ones. + if (network_get_mode() != NETWORK_MODE_NONE) + { + log_warning("Attempted to create money effect without a valid location in multiplayer"); + return; + } + rct_window* mainWindow = window_get_main(); if (mainWindow == nullptr) return; From df30d5d9bc5fe1713fead34b6ed9245cf45c88d3 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 19 Jun 2019 03:20:19 +0200 Subject: [PATCH 484/506] Fix MarketingCampaignFlags::FIRST_WEEK not being imported/exported with sv6 --- src/openrct2/management/Marketing.h | 1 + src/openrct2/rct2/S6Exporter.cpp | 2 ++ src/openrct2/rct2/S6Importer.cpp | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/openrct2/management/Marketing.h b/src/openrct2/management/Marketing.h index 6d4df0ebde..36c931754b 100644 --- a/src/openrct2/management/Marketing.h +++ b/src/openrct2/management/Marketing.h @@ -36,6 +36,7 @@ enum enum { + CAMPAIGN_FIRST_WEEK_FLAG = (1 << 6), CAMPAIGN_ACTIVE_FLAG = (1 << 7) }; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 1772a19fb2..e5a3d286a5 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -795,6 +795,8 @@ void S6Exporter::ExportMarketingCampaigns() for (const auto& campaign : gMarketingCampaigns) { _s6.campaign_weeks_left[campaign.Type] = campaign.WeeksLeft | CAMPAIGN_ACTIVE_FLAG; + if ((campaign.Flags & MarketingCampaignFlags::FIRST_WEEK)) + _s6.campaign_weeks_left[campaign.Type] |= CAMPAIGN_FIRST_WEEK_FLAG; if (campaign.Type == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign.Type == ADVERTISING_CAMPAIGN_RIDE) { _s6.campaign_ride_index[campaign.Type] = campaign.RideId; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 994070cb4d..2ce88cd597 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1072,7 +1072,11 @@ public: { MarketingCampaign campaign{}; campaign.Type = (uint8_t)i; - campaign.WeeksLeft = _s6.campaign_weeks_left[i] & ~CAMPAIGN_ACTIVE_FLAG; + campaign.WeeksLeft = _s6.campaign_weeks_left[i] & ~(CAMPAIGN_ACTIVE_FLAG | CAMPAIGN_FIRST_WEEK_FLAG); + if ((_s6.campaign_weeks_left[i] & CAMPAIGN_FIRST_WEEK_FLAG) != 0) + { + campaign.Flags |= MarketingCampaignFlags::FIRST_WEEK; + } if (campaign.Type == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign.Type == ADVERTISING_CAMPAIGN_RIDE) { campaign.RideId = _s6.campaign_ride_index[i]; From 881b7012ac93fa953c501cfd0a99bddfb3e621cb Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 19 Jun 2019 03:29:46 +0200 Subject: [PATCH 485/506] Bump up 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 6e5e854a8f..20d496191e 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 "43" +#define NETWORK_STREAM_VERSION "44" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From eb13c5a77693189ae2e1791e55571bfb18175b93 Mon Sep 17 00:00:00 2001 From: nhair Date: Wed, 19 Jun 2019 17:02:57 -0400 Subject: [PATCH 486/506] Fix #9245: Headless servers apply Discord Rich Presence --- distribution/changelog.txt | 1 + src/openrct2/Context.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e151f91139..db1965cd0f 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -55,6 +55,7 @@ - Fix: [#9152] Spectators can modify ride colours. - Fix: [#9202] Artefacts show when changing ride type as client or using in-game console. - Fix: [#9240] Crash when passing directory instead of save file. +- Fix: [#9245] Headless servers apply Discord Rich Presence. - Fix: [#9293] Issue with the native load/save dialog. - Fix: [#9322] Peep crashing the game trying to find a ride to look at. - Fix: [#9324] Crash trying to remove invalid footpath scenery. diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 7e1e6927b7..73f44ed6b9 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -349,7 +349,10 @@ namespace OpenRCT2 _replayManager = CreateReplayManager(); _gameStateSnapshots = CreateGameStateSnapshots(); #ifdef __ENABLE_DISCORD__ - _discordService = std::make_unique(); + if (!gOpenRCT2Headless) + { + _discordService = std::make_unique(); + } #endif try From 2a60268c05f650ebbfce06aa50729a4cb23ffdca Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 18 Jun 2019 20:33:21 +0100 Subject: [PATCH 487/506] Fix #9440. Set the tile coordinate correctly with spinner. --- src/openrct2-ui/windows/TileInspector.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 49832fcb9a..212a8013fc 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -1026,18 +1026,24 @@ static void window_tile_inspector_mousedown(rct_window* w, rct_widgetindex widge { case WIDX_SPINNER_X_INCREASE: windowTileInspectorTileX = std::min(windowTileInspectorTileX + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); + windowTileInspectorToolMapX = std::min( + windowTileInspectorToolMapX + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_X_DECREASE: windowTileInspectorTileX = std::max(windowTileInspectorTileX - 1, 0); + windowTileInspectorToolMapX = std::max(windowTileInspectorToolMapX - 32, 0); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_INCREASE: windowTileInspectorTileY = std::min(windowTileInspectorTileY + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); + windowTileInspectorToolMapY = std::min( + windowTileInspectorToolMapY + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_DECREASE: windowTileInspectorTileY = std::max(windowTileInspectorTileY - 1, 0); + windowTileInspectorToolMapY = std::max(windowTileInspectorToolMapY - 32, 0); window_tile_inspector_load_tile(w, nullptr); break; } // switch widget index From ecbff5d4f2cb81236ac29274391a03c07b0f7008 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Tue, 18 Jun 2019 20:47:30 +0100 Subject: [PATCH 488/506] Refactor to use CoordsXY --- src/openrct2-ui/windows/TileInspector.cpp | 123 +++++++++------------- 1 file changed, 52 insertions(+), 71 deletions(-) diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 212a8013fc..44dc7a9879 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -446,8 +446,7 @@ static bool windowTileInspectorTileSelected = false; static int32_t windowTileInspectorToolMouseX = 0; static int32_t windowTileInspectorToolMouseY = 0; static bool windowTileInspectorToolCtrlDown = false; -static int32_t windowTileInspectorToolMapX = 0; -static int32_t windowTileInspectorToolMapY = 0; +static CoordsXY windowTileInspectorToolMap = {}; static bool windowTileInspectorApplyToAll = false; static bool windowTileInspectorElementCopied = false; static TileElement tileInspectorCopiedElement; @@ -577,7 +576,8 @@ static TileElement* window_tile_inspector_get_selected_element(rct_window* w) openrct2_assert( windowTileInspectorSelectedIndex >= 0 && windowTileInspectorSelectedIndex < windowTileInspectorElementCount, "Selected list item out of range"); - return map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY) + windowTileInspectorSelectedIndex; + return map_get_first_element_at(windowTileInspectorToolMap.x / 32, windowTileInspectorToolMap.y / 32) + + windowTileInspectorSelectedIndex; } static void window_tile_inspector_select_element_from_list(rct_window* w, int32_t index) @@ -599,7 +599,7 @@ static void window_tile_inspector_load_tile(rct_window* w, TileElement* elementT windowTileInspectorSelectedIndex = -1; w->scrolls[0].v_top = 0; - TileElement* element = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); + TileElement* element = map_get_first_element_at(windowTileInspectorToolMap.x / 32, windowTileInspectorToolMap.y / 32); int16_t numItems = 0; do { @@ -619,24 +619,21 @@ 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"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyInsertCorrupt, elementIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, 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"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyRemove, elementIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, 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"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyRotate, elementIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::AnyRotate, elementIndex); GameActions::Execute(&modifyTile); } @@ -645,15 +642,14 @@ 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"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnySwap, first, second); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::AnySwap, first, second); GameActions::Execute(&modifyTile); } static void window_tile_inspector_sort_elements() { openrct2_assert(windowTileInspectorTileSelected, "No tile selected"); - auto modifyTile = TileModifyAction({ windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnySort); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::AnySort); GameActions::Execute(&modifyTile); } @@ -671,52 +667,44 @@ 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)); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyPaste, 0, 0, - tileInspectorCopiedElement); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::AnyPaste, 0, 0, tileInspectorCopiedElement); GameActions::Execute(&modifyTile); } static void window_tile_inspector_base_height_offset(int16_t elementIndex, int8_t heightOffset) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::AnyBaseHeightOffset, elementIndex, - heightOffset); + windowTileInspectorToolMap, TileModifyType::AnyBaseHeightOffset, elementIndex, heightOffset); GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_show_park_fences(bool showFences) { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceShowParkFences, showFences); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::SurfaceShowParkFences, showFences); GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_toggle_corner(int32_t cornerIndex) { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceToggleCorner, cornerIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::SurfaceToggleCorner, cornerIndex); GameActions::Execute(&modifyTile); } static void window_tile_inspector_surface_toggle_diagonal() { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::SurfaceToggleDiagonal); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::SurfaceToggleDiagonal); GameActions::Execute(&modifyTile); } static void window_tile_inspector_path_set_sloped(int32_t elementIndex, bool sloped) { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathSetSlope, elementIndex, sloped); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::PathSetSlope, elementIndex, sloped); GameActions::Execute(&modifyTile); } static void window_tile_inspector_path_set_broken(int32_t elementIndex, bool broken) { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathSetBroken, elementIndex, broken); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::PathSetBroken, elementIndex, broken); GameActions::Execute(&modifyTile); } @@ -724,17 +712,14 @@ static void window_tile_inspector_path_toggle_edge(int32_t elementIndex, int32_t { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); openrct2_assert(cornerIndex >= 0 && cornerIndex < 8, "cornerIndex out of range"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::PathToggleEdge, elementIndex, - cornerIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::PathToggleEdge, elementIndex, cornerIndex); GameActions::Execute(&modifyTile); } static void window_tile_inspector_entrance_make_usable(int32_t elementIndex) { Guard::ArgumentInRange(elementIndex, 0, windowTileInspectorElementCount - 1); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::EntranceMakeUsable, elementIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::EntranceMakeUsable, elementIndex); GameActions::Execute(&modifyTile); } @@ -742,40 +727,36 @@ static void window_tile_inspector_wall_set_slope(int32_t elementIndex, int32_t s { // Make sure only the correct bits are set openrct2_assert((slopeValue & 3) == slopeValue, "slopeValue doesn't match its mask"); - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::WallSetSlope, elementIndex, slopeValue); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::WallSetSlope, elementIndex, slopeValue); GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_block_height_offset(int32_t elementIndex, int8_t heightOffset) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackBaseHeightOffset, elementIndex, - heightOffset); + windowTileInspectorToolMap, TileModifyType::TrackBaseHeightOffset, elementIndex, heightOffset); GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_block_set_lift(int32_t elementIndex, bool entireTrackBlock, bool chain) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, - entireTrackBlock ? TileModifyType::TrackSetChainBlock : TileModifyType::TrackSetChain, elementIndex, chain); + windowTileInspectorToolMap, entireTrackBlock ? TileModifyType::TrackSetChainBlock : TileModifyType::TrackSetChain, + elementIndex, chain); GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_set_block_brake(int32_t elementIndex, bool blockBrake) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackSetBlockBrake, elementIndex, - blockBrake); + windowTileInspectorToolMap, TileModifyType::TrackSetBlockBrake, elementIndex, blockBrake); GameActions::Execute(&modifyTile); } static void window_tile_inspector_track_set_indestructible(int32_t elementIndex, bool isIndestructible) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::TrackSetIndestructible, elementIndex, - isIndestructible); + windowTileInspectorToolMap, TileModifyType::TrackSetIndestructible, elementIndex, isIndestructible); GameActions::Execute(&modifyTile); } @@ -784,7 +765,7 @@ static void window_tile_inspector_quarter_tile_set(int32_t elementIndex, const i // 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"); auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::ScenerySetQuarterLocation, elementIndex, + windowTileInspectorToolMap, TileModifyType::ScenerySetQuarterLocation, elementIndex, (quarterIndex - get_current_rotation()) & 3); GameActions::Execute(&modifyTile); } @@ -792,7 +773,7 @@ static void window_tile_inspector_quarter_tile_set(int32_t elementIndex, const i static void window_tile_inspector_toggle_quadrant_collosion(int32_t elementIndex, const int32_t quadrantIndex) { auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::ScenerySetQuarterCollision, elementIndex, + windowTileInspectorToolMap, TileModifyType::ScenerySetQuarterCollision, elementIndex, (quadrantIndex + 2 - get_current_rotation()) & 3); GameActions::Execute(&modifyTile); } @@ -804,15 +785,13 @@ static void window_tile_inspector_banner_toggle_block(int32_t elementIndex, int3 // Make edgeIndex abstract edgeIndex = (edgeIndex - get_current_rotation()) & 3; auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::BannerToggleBlockingEdge, elementIndex, - edgeIndex); + windowTileInspectorToolMap, TileModifyType::BannerToggleBlockingEdge, elementIndex, edgeIndex); GameActions::Execute(&modifyTile); } static void window_tile_inspector_clamp_corrupt(int32_t elementIndex) { - auto modifyTile = TileModifyAction( - { windowTileInspectorToolMapX, windowTileInspectorToolMapY }, TileModifyType::CorruptClamp, elementIndex); + auto modifyTile = TileModifyAction(windowTileInspectorToolMap, TileModifyType::CorruptClamp, elementIndex); GameActions::Execute(&modifyTile); } @@ -1026,24 +1005,24 @@ static void window_tile_inspector_mousedown(rct_window* w, rct_widgetindex widge { case WIDX_SPINNER_X_INCREASE: windowTileInspectorTileX = std::min(windowTileInspectorTileX + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); - windowTileInspectorToolMapX = std::min( - windowTileInspectorToolMapX + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); + windowTileInspectorToolMap.x = std::min( + windowTileInspectorToolMap.x + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_X_DECREASE: windowTileInspectorTileX = std::max(windowTileInspectorTileX - 1, 0); - windowTileInspectorToolMapX = std::max(windowTileInspectorToolMapX - 32, 0); + windowTileInspectorToolMap.x = std::max(windowTileInspectorToolMap.x - 32, 0); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_INCREASE: windowTileInspectorTileY = std::min(windowTileInspectorTileY + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); - windowTileInspectorToolMapY = std::min( - windowTileInspectorToolMapY + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); + windowTileInspectorToolMap.y = std::min( + windowTileInspectorToolMap.y + 32, (MAXIMUM_MAP_SIZE_TECHNICAL - 1) * 32); window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_DECREASE: windowTileInspectorTileY = std::max(windowTileInspectorTileY - 1, 0); - windowTileInspectorToolMapY = std::max(windowTileInspectorToolMapY - 32, 0); + windowTileInspectorToolMap.y = std::max(windowTileInspectorToolMap.y - 32, 0); window_tile_inspector_load_tile(w, nullptr); break; } // switch widget index @@ -1266,8 +1245,8 @@ static void window_tile_inspector_tool_update(rct_window* w, rct_widgetindex wid } else if (windowTileInspectorTileSelected) { - gMapSelectPositionA.x = gMapSelectPositionB.x = windowTileInspectorTileX << 5; - gMapSelectPositionA.y = gMapSelectPositionB.y = windowTileInspectorTileY << 5; + gMapSelectPositionA.x = gMapSelectPositionB.x = windowTileInspectorToolMap.x; + gMapSelectPositionA.y = gMapSelectPositionB.y = windowTileInspectorToolMap.y; } else { @@ -1312,15 +1291,15 @@ static void window_tile_inspector_update_selected_tile(rct_window* w, int32_t x, } // Tile is already selected - if (windowTileInspectorTileSelected && mapX == windowTileInspectorToolMapX && mapY == windowTileInspectorToolMapY) + if (windowTileInspectorTileSelected && mapX == windowTileInspectorToolMap.x && mapY == windowTileInspectorToolMap.y) { return; } } windowTileInspectorTileSelected = true; - windowTileInspectorToolMapX = mapX; - windowTileInspectorToolMapY = mapY; + windowTileInspectorToolMap.x = mapX; + windowTileInspectorToolMap.y = mapY; windowTileInspectorTileX = mapX >> 5; windowTileInspectorTileY = mapY >> 5; @@ -1435,12 +1414,14 @@ static void window_tile_inspector_invalidate(rct_window* w) // X and Y spinners widget_set_enabled( w, WIDX_SPINNER_X_INCREASE, - (windowTileInspectorTileSelected && (windowTileInspectorTileX < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); - widget_set_enabled(w, WIDX_SPINNER_X_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileX > 0))); + (windowTileInspectorTileSelected && ((windowTileInspectorToolMap.x / 32) < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); + widget_set_enabled( + w, WIDX_SPINNER_X_DECREASE, (windowTileInspectorTileSelected && ((windowTileInspectorToolMap.x / 32) > 0))); widget_set_enabled( w, WIDX_SPINNER_Y_INCREASE, - (windowTileInspectorTileSelected && (windowTileInspectorTileY < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); - widget_set_enabled(w, WIDX_SPINNER_Y_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileY > 0))); + (windowTileInspectorTileSelected && ((windowTileInspectorToolMap.y / 32) < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); + widget_set_enabled( + w, WIDX_SPINNER_Y_DECREASE, (windowTileInspectorTileSelected && ((windowTileInspectorToolMap.y / 32) > 0))); // Sort buttons widget_set_enabled(w, WIDX_BUTTON_SORT, (windowTileInspectorTileSelected && windowTileInspectorElementCount > 1)); @@ -1776,8 +1757,9 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) gfx_draw_string(dpi, (char*)"Y:", COLOUR_DARK_GREEN, w->x + 74, w->y + 24); if (windowTileInspectorTileSelected) { - gfx_draw_string_right(dpi, STR_FORMAT_INTEGER, &windowTileInspectorTileX, COLOUR_DARK_GREEN, w->x + 43, w->y + 24); - gfx_draw_string_right(dpi, STR_FORMAT_INTEGER, &windowTileInspectorTileY, COLOUR_DARK_GREEN, w->x + 113, w->y + 24); + auto tileCoords = TileCoordsXY{ windowTileInspectorToolMap }; + gfx_draw_string_right(dpi, STR_FORMAT_INTEGER, &tileCoords.x, COLOUR_DARK_GREEN, w->x + 43, w->y + 24); + gfx_draw_string_right(dpi, STR_FORMAT_INTEGER, &tileCoords.y, COLOUR_DARK_GREEN, w->x + 113, w->y + 24); } else { @@ -1988,11 +1970,9 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_PARK_ENTRANCE) { - // Park entrance ID - int32_t middleX = windowTileInspectorTileX << 5; - int32_t middleY = windowTileInspectorTileY << 5; // TODO: Make this work with Left/Right park entrance parts - int16_t parkEntranceIndex = park_entrance_get_index(middleX, middleY, tileElement->base_height * 8); + int16_t parkEntranceIndex = park_entrance_get_index( + windowTileInspectorToolMap.x, windowTileInspectorToolMap.y, tileElement->base_height * 8); gfx_draw_string_left( dpi, STR_TILE_INSPECTOR_ENTRANCE_ENTRANCE_ID, &parkEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); } @@ -2177,7 +2157,8 @@ static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* if (!windowTileInspectorTileSelected) return; - const TileElement* tileElement = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); + const TileElement* tileElement = map_get_first_element_at( + windowTileInspectorToolMap.x / 32, windowTileInspectorToolMap.y / 32); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; do From 65c0b0591d8b6b884c8e570f77322d2613e60296 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 20 Jun 2019 19:27:56 +0100 Subject: [PATCH 489/506] Fix build for gcc Invalid cast to int32_t that had been left in after refactoring months ago. Latest version of gcc flags this as the cast made this a comparison between a signed and unsigned value. --- src/openrct2/world/Banner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 4ec4bd87a2..213e282a67 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -166,7 +166,7 @@ uint8_t banner_get_closest_ride_index(int32_t x, int32_t y, int32_t z) { 0, -32 }, { -32, +32 }, { +32, -32 }, { +32, +32 }, { -32, +32 }, { 0, 0 } }; - for (size_t i = 0; i < (int32_t)std::size(NeighbourCheckOrder); i++) + for (size_t i = 0; i < std::size(NeighbourCheckOrder); i++) { ride_id_t rideIndex = banner_get_ride_index_at(x + NeighbourCheckOrder[i].x, y + NeighbourCheckOrder[i].y, z); if (rideIndex != RIDE_ID_NULL) From b896f0768740889a69f3184dd3b98a93d2212dd0 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 9 Jun 2019 16:54:12 +0100 Subject: [PATCH 490/506] Add PeepPickupAction Move Guest and Staff pickup to the new game action. Rework the game action so that only one game action is required for the two game commands. Remove the final game command with a callback. --- src/openrct2-ui/windows/Guest.cpp | 35 +++- src/openrct2-ui/windows/Staff.cpp | 37 +++- src/openrct2/Game.cpp | 8 +- src/openrct2/Game.h | 26 +-- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/PeepPickupAction.hpp | 189 ++++++++++++++++++ src/openrct2/interface/Window.h | 5 - src/openrct2/network/Network.cpp | 11 +- src/openrct2/peep/Peep.cpp | 93 --------- src/openrct2/peep/Peep.h | 1 - src/openrct2/peep/Staff.cpp | 18 -- src/openrct2/peep/Staff.h | 3 - src/openrct2/windows/_legacy.cpp | 52 ----- 13 files changed, 270 insertions(+), 210 deletions(-) create mode 100644 src/openrct2/actions/PeepPickupAction.hpp diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index ea051bee58..67f9c4997b 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -692,14 +693,25 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex) window_guest_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_PICKUP: + { if (!peep_can_be_picked_up(peep)) { return; } w->picked_peep_old_x = peep->x; - game_command_callback = game_command_callback_pickup_guest; - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_PICKUP_GUEST, 0, 0); - break; + PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, {}, network_get_current_player_id() }; + pickupAction.SetCallback([peepnum = w->number](const GameAction* ga, const GameActionResult* result) { + if (result->Error != GA_ERROR::OK) + return; + rct_window* wind = window_find_by_number(WC_PEEP, peepnum); + if (wind) + { + tool_set(wind, WC_PEEP__WIDX_PICKUP, TOOL_PICKER); + } + }); + GameActions::Execute(&pickupAction); + } + break; case WIDX_RENAME: window_text_input_open( w, widgetIndex, STR_GUEST_RENAME_TITLE, STR_GUEST_RENAME_PROMPT, peep->name_string_idx, peep->id, 32); @@ -1275,8 +1287,16 @@ void window_guest_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, if (dest_x == LOCATION_NULL) return; - game_command_callback = game_command_callback_pickup_guest; - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 2, tileElement->base_height, GAME_COMMAND_PICKUP_GUEST, dest_x, dest_y); + PeepPickupAction pickupAction{ + PeepPickupType::Place, w->number, { dest_x, dest_y, tileElement->base_height }, network_get_current_player_id() + }; + pickupAction.SetCallback([](const GameAction* ga, const GameActionResult* result) { + if (result->Error != GA_ERROR::OK) + return; + tool_cancel(); + gPickupPeepImage = UINT32_MAX; + }); + GameActions::Execute(&pickupAction); } /** @@ -1288,7 +1308,10 @@ void window_guest_overview_tool_abort(rct_window* w, rct_widgetindex widgetIndex if (widgetIndex != WIDX_PICKUP) return; - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 1, 0, GAME_COMMAND_PICKUP_GUEST, w->picked_peep_old_x, 0); + PeepPickupAction pickupAction{ + PeepPickupType::Cancel, w->number, { w->picked_peep_old_x, 0, 0 }, network_get_current_player_id() + }; + GameActions::Execute(&pickupAction); } /** diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index a6e47a306c..cd11b31c85 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -462,13 +463,19 @@ void window_staff_overview_mouseup(rct_window* w, rct_widgetindex widgetIndex) break; case WIDX_PICKUP: { - // this is called in callback when hiring staff, setting nestlevel to 0 so that command is sent separately - int32_t oldNestLevel = gGameCommandNestLevel; - gGameCommandNestLevel = 0; - game_command_callback = game_command_callback_pickup_staff; w->picked_peep_old_x = peep->x; - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_PICKUP_STAFF, 0, 0); - gGameCommandNestLevel = oldNestLevel; + + PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, {}, network_get_current_player_id() }; + pickupAction.SetCallback([peepnum = w->number](const GameAction* ga, const GameActionResult* result) { + if (result->Error != GA_ERROR::OK) + return; + rct_window* wind = window_find_by_number(WC_PEEP, peepnum); + if (wind) + { + tool_set(wind, WC_STAFF__WIDX_PICKUP, TOOL_PICKER); + } + }); + GameActions::Execute(&pickupAction); } break; case WIDX_FIRE: @@ -1198,9 +1205,16 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, if (dest_x == LOCATION_NULL) return; - game_command_callback = game_command_callback_pickup_staff; - game_do_command( - w->number, GAME_COMMAND_FLAG_APPLY, 2, tileElement->base_height, GAME_COMMAND_PICKUP_STAFF, dest_x, dest_y); + PeepPickupAction pickupAction{ + PeepPickupType::Place, w->number, { dest_x, dest_y, tileElement->base_height }, network_get_current_player_id() + }; + pickupAction.SetCallback([](const GameAction* ga, const GameActionResult* result) { + if (result->Error != GA_ERROR::OK) + return; + tool_cancel(); + gPickupPeepImage = UINT32_MAX; + }); + GameActions::Execute(&pickupAction); } else if (widgetIndex == WIDX_PATROL) { @@ -1285,7 +1299,10 @@ void window_staff_overview_tool_abort(rct_window* w, rct_widgetindex widgetIndex { if (widgetIndex == WIDX_PICKUP) { - game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 1, 0, GAME_COMMAND_PICKUP_STAFF, w->picked_peep_old_x, 0); + PeepPickupAction pickupAction{ + PeepPickupType::Cancel, w->number, { w->picked_peep_old_x, 0, 0 }, network_get_current_player_id() + }; + GameActions::Execute(&pickupAction); } else if (widgetIndex == WIDX_PATROL) { diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 90f388f0f5..235a88968a 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -96,8 +96,8 @@ static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = { nullptr, nullptr, nullptr, - game_command_callback_pickup_guest, - game_command_callback_pickup_staff + nullptr, + nullptr }; // clang-format on int32_t game_command_playerid = -1; @@ -1222,8 +1222,8 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_pickup_guest, - game_command_pickup_staff, + nullptr, + nullptr, nullptr, nullptr, nullptr, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index d29f0f06b3..12e733ad51 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -85,19 +85,19 @@ enum GAME_COMMAND GAME_COMMAND_MODIFY_GROUPS, // GA GAME_COMMAND_KICK_PLAYER, // GA GAME_COMMAND_CHEAT, // GA - GAME_COMMAND_PICKUP_GUEST, - GAME_COMMAND_PICKUP_STAFF, - 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 - GAME_COMMAND_SET_COLOUR_SCHEME, // GA - GAME_COMMAND_SET_STAFF_COSTUME, // GA - GAME_COMMAND_PLACE_FOOTPATH_SCENERY, // GA - GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA - GAME_COMMAND_GUEST_SET_FLAGS, // GA - GAME_COMMAND_SET_DATE, // GA + GAME_COMMAND_PICKUP_GUEST, // GA + GAME_COMMAND_PICKUP_STAFF, // GA + 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 + GAME_COMMAND_SET_COLOUR_SCHEME, // GA + GAME_COMMAND_SET_STAFF_COSTUME, // GA + GAME_COMMAND_PLACE_FOOTPATH_SCENERY, // GA + GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA + GAME_COMMAND_GUEST_SET_FLAGS, // GA + GAME_COMMAND_SET_DATE, // GA GAME_COMMAND_COUNT, }; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 25f0601b9a..2caa6cdff5 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -43,6 +43,7 @@ #include "ParkSetParameterAction.hpp" #include "ParkSetResearchFundingAction.hpp" #include "PauseToggleAction.hpp" +#include "PeepPickupAction.hpp" #include "PlaceParkEntranceAction.hpp" #include "PlacePeepSpawnAction.hpp" #include "PlayerKickAction.hpp" @@ -110,6 +111,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/PeepPickupAction.hpp b/src/openrct2/actions/PeepPickupAction.hpp new file mode 100644 index 0000000000..68ff20dd6e --- /dev/null +++ b/src/openrct2/actions/PeepPickupAction.hpp @@ -0,0 +1,189 @@ +/***************************************************************************** + * 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 "../Input.h" +#include "../network/network.h" +#include "../world/Sprite.h" +#include "GameAction.h" + +enum class PeepPickupType : uint8_t +{ + Pickup, + Cancel, + Place, + Count +}; + +DEFINE_GAME_ACTION(PeepPickupAction, GAME_COMMAND_PICKUP_GUEST, GameActionResult) +{ +private: + uint8_t _type = static_cast(PeepPickupType::Count); + uint32_t _spriteId = SPRITE_INDEX_NULL; + CoordsXYZ _loc; + NetworkPlayerId_t _owner = { -1 }; + +public: + PeepPickupAction() = default; + PeepPickupAction(PeepPickupType type, uint32_t spriteId, CoordsXYZ loc, NetworkPlayerId_t owner) + : _type(static_cast(type)) + , _spriteId(spriteId) + , _loc(loc) + , _owner(owner) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_type) << DS_TAG(_spriteId) << DS_TAG(_loc) << DS_TAG(_owner); + } + + GameActionResult::Ptr Query() const override + { + if (_spriteId >= MAX_SPRITES || _spriteId == SPRITE_INDEX_NULL) + { + log_error("Failed to pick up peep for sprite %d", _spriteId); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); + } + + Peep* const peep = GET_PEEP(_spriteId); + if (!peep || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP) + { + log_error("Failed to pick up peep for sprite %d", _spriteId); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); + } + + auto res = MakeResult(); + + switch (static_cast(_type)) + { + case PeepPickupType::Pickup: + { + res->Position = { peep->x, peep->y, peep->z }; + if (!peep_can_be_picked_up(peep)) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_ERR_CANT_PLACE_PERSON_HERE); + } + Peep* existing = network_get_pickup_peep(_owner); + if (existing) + { + // already picking up a peep + PeepPickupAction existingPickupAction{ + PeepPickupType::Cancel, existing->sprite_index, { network_get_pickup_peep_old_x(_owner), 0, 0 }, _owner + }; + auto result = GameActions::QueryNested(&existingPickupAction); + + if (existing == peep) + { + return result; + } + } + } + break; + case PeepPickupType::Cancel: + res->Position = { peep->x, peep->y, peep->z }; + break; + case PeepPickupType::Place: + res->Position = _loc; + if (network_get_pickup_peep(_owner) != peep) + { + return MakeResult(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PERSON_HERE); + } + + if (!peep->Place({ _loc.x / 32, _loc.y / 32, _loc.z }, false)) + { + return MakeResult(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PERSON_HERE, gGameCommandErrorText); + } + break; + default: + log_error("Invalid pickup type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); + break; + } + return res; + } + + GameActionResult::Ptr Execute() const override + { + Peep* const peep = GET_PEEP(_spriteId); + if (!peep || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP) + { + log_error("Failed to pick up peep for sprite %d", _spriteId); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); + } + + auto res = MakeResult(); + + switch (static_cast(_type)) + { + case PeepPickupType::Pickup: + { + res->Position = { peep->x, peep->y, peep->z }; + + Peep* existing = network_get_pickup_peep(_owner); + if (existing) + { + // already picking up a peep + PeepPickupAction existingPickupAction{ + PeepPickupType::Cancel, existing->sprite_index, { network_get_pickup_peep_old_x(_owner), 0, 0 }, _owner + }; + auto result = GameActions::ExecuteNested(&existingPickupAction); + + if (existing == peep) + { + return result; + } + if (_owner == network_get_current_player_id()) + { + // prevent tool_cancel() + input_set_flag(INPUT_FLAG_TOOL_ACTIVE, false); + } + } + + network_set_pickup_peep(_owner, peep); + network_set_pickup_peep_old_x(_owner, peep->x); + peep->Pickup(); + } + break; + case PeepPickupType::Cancel: + { + res->Position = { peep->x, peep->y, peep->z }; + + Peep* const pickedUpPeep = network_get_pickup_peep(_owner); + if (pickedUpPeep) + { + pickedUpPeep->PickupAbort(_loc.x); + } + + network_set_pickup_peep(_owner, nullptr); + } + break; + case PeepPickupType::Place: + res->Position = _loc; + if (!peep->Place({ _loc.x / 32, _loc.y / 32, _loc.z }, true)) + { + return MakeResult(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PERSON_HERE, gGameCommandErrorText); + } + break; + default: + log_error("Invalid pickup type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PERSON_HERE); + break; + } + return res; + } +}; diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 780b42e312..7c6384dd21 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -677,11 +677,6 @@ void window_align_tabs(rct_window* w, rct_widgetindex start_tab_id, rct_widgetin void window_staff_list_init_vars(); -void game_command_callback_pickup_guest( - int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp); -void game_command_callback_pickup_staff( - int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp); - void window_event_close_call(rct_window* w); void window_event_mouse_up_call(rct_window* w, rct_widgetindex widgetIndex); void window_event_resize_call(rct_window* w); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 20d496191e..351aa3a559 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -16,6 +16,7 @@ #include "../PlatformEnvironment.h" #include "../actions/LoadOrQuitAction.hpp" #include "../actions/NetworkModifyGroupAction.hpp" +#include "../actions/PeepPickupAction.hpp" #include "../core/Guard.hpp" #include "../platform/platform.h" #include "../ui/UiContext.h" @@ -2246,11 +2247,11 @@ void Network::ServerClientDisconnected(std::unique_ptr& conne Peep* pickup_peep = network_get_pickup_peep(connection_player->Id); if (pickup_peep) { - game_command_playerid = connection_player->Id; - game_do_command( - pickup_peep->sprite_index, GAME_COMMAND_FLAG_APPLY, 1, 0, - pickup_peep->type == PEEP_TYPE_GUEST ? GAME_COMMAND_PICKUP_GUEST : GAME_COMMAND_PICKUP_STAFF, - network_get_pickup_peep_old_x(connection_player->Id), 0); + PeepPickupAction pickupAction{ PeepPickupType::Cancel, + pickup_peep->sprite_index, + { network_get_pickup_peep_old_x(connection_player->Id), 0, 0 }, + network_get_current_player_id() }; + auto res = GameActions::Execute(&pickupAction); } gNetwork.Server_Send_EVENT_PLAYER_DISCONNECTED( (char*)connection_player->Name.c_str(), connection->GetLastDisconnectReason()); diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 85c3d4284a..7caed0ca57 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -853,99 +853,6 @@ bool Peep::Place(TileCoordsXYZ location, bool apply) return true; } -bool peep_pickup_command(uint32_t peepnum, int32_t x, int32_t y, int32_t z, int32_t action, bool apply) -{ - if (peepnum >= MAX_SPRITES) - { - log_error("Failed to pick up peep for sprite %d", peepnum); - return false; - } - - Peep* const peep = GET_PEEP(peepnum); - if (!peep || peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP) - { - return false; - } - - switch (action) - { - case 0: // pickup - { - if (!peep_can_be_picked_up(peep)) - { - return false; - } - Peep* existing = network_get_pickup_peep(game_command_playerid); - if (existing) - { - // already picking up a peep - bool result = peep_pickup_command( - existing->sprite_index, network_get_pickup_peep_old_x(game_command_playerid), 0, 0, 1, apply); - if (existing == peep) - { - return result; - } - if (game_command_playerid == network_get_current_player_id()) - { - // prevent tool_cancel() - input_set_flag(INPUT_FLAG_TOOL_ACTIVE, false); - } - } - - if (apply) - { - network_set_pickup_peep(game_command_playerid, peep); - network_set_pickup_peep_old_x(game_command_playerid, peep->x); - peep->Pickup(); - } - } - break; - case 1: // cancel - if (apply) - { - // TODO: Verify if this is really needed or that we can use `peep` instead - Peep* const pickedUpPeep = network_get_pickup_peep(game_command_playerid); - if (pickedUpPeep) - { - pickedUpPeep->PickupAbort(x); - } - - network_set_pickup_peep(game_command_playerid, nullptr); - } - break; - case 2: // place - if (network_get_pickup_peep(game_command_playerid) != peep) - { - return false; - } - - if (!peep->Place({ x / 32, y / 32, z }, apply)) - { - return false; - } - break; - } - return true; -} - -void game_command_pickup_guest( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t peepnum = *eax; - int32_t x = *edi; - int32_t y = *ebp; - int32_t z = *edx; - int32_t action = *ecx; - if (peep_pickup_command(peepnum, x, y, z, action, *ebx & GAME_COMMAND_FLAG_APPLY)) - { - *ebx = 0; - } - else - { - *ebx = MONEY32_UNDEFINED; - } -} - /** * * rct2: 0x0069A535 diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 56c8336cba..5ce95b4dde 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -953,7 +953,6 @@ int32_t get_peep_face_sprite_small(Peep* peep); int32_t get_peep_face_sprite_large(Peep* peep); int32_t peep_check_easteregg_name(int32_t index, Peep* peep); int32_t peep_get_easteregg_name_id(Peep* peep); -bool peep_pickup_command(uint32_t peepnum, int32_t x, int32_t y, int32_t z, int32_t action, bool apply); void game_command_pickup_guest( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void peep_sprite_remove(Peep* peep); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index daaccae5dc..ae167fd612 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1089,24 +1089,6 @@ int32_t staff_path_finding(Staff* peep) } } -void game_command_pickup_staff( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, int32_t* ebp) -{ - int32_t peepnum = *eax; - int32_t x = *edi; - int32_t y = *ebp; - int32_t z = *edx; - int32_t action = *ecx; - if (peep_pickup_command(peepnum, x, y, z, action, *ebx & GAME_COMMAND_FLAG_APPLY)) - { - *ebx = 0; - } - else - { - *ebx = MONEY32_UNDEFINED; - } -} - colour_t staff_get_colour(uint8_t staffType) { switch (staffType) diff --git a/src/openrct2/peep/Staff.h b/src/openrct2/peep/Staff.h index 05c214797d..775ec75e1d 100644 --- a/src/openrct2/peep/Staff.h +++ b/src/openrct2/peep/Staff.h @@ -71,9 +71,6 @@ extern colour_t gStaffHandymanColour; extern colour_t gStaffMechanicColour; extern colour_t gStaffSecurityColour; -void game_command_pickup_staff( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - void staff_reset_modes(); void staff_set_name(uint16_t spriteIndex, const char* name); bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType); diff --git a/src/openrct2/windows/_legacy.cpp b/src/openrct2/windows/_legacy.cpp index 1576eee659..c4ed2920ff 100644 --- a/src/openrct2/windows/_legacy.cpp +++ b/src/openrct2/windows/_legacy.cpp @@ -29,58 +29,6 @@ bool gDisableErrorWindowSound = false; -void game_command_callback_pickup_guest( - int32_t eax, int32_t ebx, int32_t ecx, [[maybe_unused]] int32_t edx, [[maybe_unused]] int32_t esi, - [[maybe_unused]] int32_t edi, [[maybe_unused]] int32_t ebp) -{ - switch (ecx) - { - case 0: - { - int32_t peepnum = eax; - rct_window* w = window_find_by_number(WC_PEEP, peepnum); - if (w) - { - tool_set(w, WC_PEEP__WIDX_PICKUP, TOOL_PICKER); - } - } - break; - case 2: - if (ebx == 0) - { - tool_cancel(); - gPickupPeepImage = UINT32_MAX; - } - break; - } -} - -void game_command_callback_pickup_staff( - int32_t eax, int32_t ebx, int32_t ecx, [[maybe_unused]] int32_t edx, [[maybe_unused]] int32_t esi, - [[maybe_unused]] int32_t edi, [[maybe_unused]] int32_t ebp) -{ - switch (ecx) - { - case 0: - { - int32_t peepnum = eax; - rct_window* w = window_find_by_number(WC_PEEP, peepnum); - if (w) - { - tool_set(w, WC_STAFF__WIDX_PICKUP, TOOL_PICKER); - } - } - break; - case 2: - if (ebx == 0) - { - tool_cancel(); - gPickupPeepImage = UINT32_MAX; - } - break; - } -} - uint64_t _enabledRidePieces; uint8_t _rideConstructionState2; From 6bd09f6b98ed5d647544ef42c8153ce3f12a466e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 20 Jun 2019 19:58:56 +0200 Subject: [PATCH 491/506] Cancel concurrent peep pickups on placement (#29) --- src/openrct2/actions/PeepPickupAction.hpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/openrct2/actions/PeepPickupAction.hpp b/src/openrct2/actions/PeepPickupAction.hpp index 68ff20dd6e..dcabc0784b 100644 --- a/src/openrct2/actions/PeepPickupAction.hpp +++ b/src/openrct2/actions/PeepPickupAction.hpp @@ -178,6 +178,7 @@ public: { return MakeResult(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PERSON_HERE, gGameCommandErrorText); } + CancelConcurrentPickups(peep); break; default: log_error("Invalid pickup type: %u", _type); @@ -186,4 +187,26 @@ public: } return res; } + +private: + void CancelConcurrentPickups(Peep * pickedPeep) const + { + // This part is only relevant in multiplayer games. + if (network_get_mode() == NETWORK_MODE_NONE) + return; + + // Not relevant for owner, owner gets to place it normally. + NetworkPlayerId_t currentPlayerId = network_get_current_player_id(); + if (currentPlayerId == _owner) + return; + + Peep* peep = network_get_pickup_peep(network_get_current_player_id()); + if (peep != pickedPeep) + return; + + // By assigning the peep to null before calling tool_cancel we can avoid + // resetting the peep to the initial position. + network_set_pickup_peep(currentPlayerId, nullptr); + tool_cancel(); + } }; From 27e958fe2b059d7f28da63135df5d4efefdbe5eb Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 20 Jun 2019 19:23:31 +0100 Subject: [PATCH 492/506] 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 351aa3a559..5de2b63865 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -34,7 +34,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 "44" +#define NETWORK_STREAM_VERSION "45" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 2de9430bd3d5676834c0b758110f36c11dd6538b Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 20 Jun 2019 20:13:23 +0100 Subject: [PATCH 493/506] Remove incorrect code that resets picked peep The game command owner is never set for game actions so this would be incorrect --- src/openrct2/peep/Peep.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 7caed0ca57..09f09e69cb 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -846,8 +846,6 @@ bool Peep::Place(TileCoordsXYZ location, bool apply) happiness_target = std::max(happiness_target - 10, 0); UpdateCurrentActionSpriteType(); } - - network_set_pickup_peep(game_command_playerid, nullptr); } return true; From f9101a2d7ac3f12213065bcdc99091b6528f7ea7 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 24 Jun 2019 23:17:48 +0100 Subject: [PATCH 494/506] Fix #9476: Running `simulate` command on park yields `Completed: (null)` --- distribution/changelog.txt | 1 + src/openrct2/cmdline/SimulateCommands.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index db1965cd0f..2acf3cba70 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -62,6 +62,7 @@ - Fix: [#9402] Ad campaigns disappear when you save and load the game. - Fix: [#9411] Ad campaigns end too soon. - Fix: [#9424] Crash using multi threading with TrueType fonts. +- Fix: [#9476] Running `simulate` command on park yields `Completed: (null)`. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/src/openrct2/cmdline/SimulateCommands.cpp b/src/openrct2/cmdline/SimulateCommands.cpp index 76cd61de50..3848f9ccae 100644 --- a/src/openrct2/cmdline/SimulateCommands.cpp +++ b/src/openrct2/cmdline/SimulateCommands.cpp @@ -63,7 +63,7 @@ static exitcode_t HandleSimulate(CommandLineArgEnumerator* argEnumerator) { context->GetGameState()->UpdateLogic(); } - Console::WriteLine("Completed: %s", sprite_checksum()); + Console::WriteLine("Completed: %s", sprite_checksum().ToString().c_str()); } else { From a4f6d6b831180cc0b9c53471e71fdf6b3621f57c Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 25 Jun 2019 04:00:23 +0000 Subject: [PATCH 495/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/fr-FR.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/data/language/fr-FR.txt b/data/language/fr-FR.txt index 1a30b3b2f5..8c9a8d227c 100644 --- a/data/language/fr-FR.txt +++ b/data/language/fr-FR.txt @@ -3779,6 +3779,17 @@ STR_6314 :{WINDOW_COLOUR_2}Destination : {BLACK}{INT32}, {INT32} tolérance { STR_6315 :{WINDOW_COLOUR_2}Objectif recherche chemin : {BLACK}{INT32}, {INT32}, {INT32} dir. {INT32} STR_6316 :{WINDOW_COLOUR_2}Historique recherche chemin : STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6318 :Desynchronisation réseau détecté.{NEWLINE}Fichier journal : {STRING} +STR_6319 :{WINDOW_COLOUR_2}Bloc de frein fermé +STR_6320 :{WINDOW_COLOUR_2}Indestructible +STR_6321 :{WINDOW_COLOUR_2}L'ajout est cassé +STR_6322 :{WINDOW_COLOUR_2}Identifiant sprite : {BLACK}{INT32} +STR_6323 :Simulation +STR_6324 :Simuler +STR_6325 :{SMALLFONT}{BLACK}Simule l'attraction +STR_6326 :Impossible de similar {POP16}{POP16}{POP16}{STRINGID}... +STR_6327 :Fond transparent pour les captures d'écran géantes +STR_6328 :{SMALLFONT}{BLACK}Quand cette option est activée, les captures d'écran auront un fond transparent plutôt qu'un fond noir. ############# # Scenarios # From c00c8056ce7362792f6c5223740f621cf069d57a Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Tue, 25 Jun 2019 22:41:10 +0200 Subject: [PATCH 496/506] Update title sequences to v0.1.2b (#9480) --- CMakeLists.txt | 4 ++-- openrct2.proj | 4 ++-- shell.nix | 4 ++-- src/openrct2-android/app/build.gradle | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31e705baaf..06235a157b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") set(CMAKE_MACOSX_RPATH 1) -set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip") -set(TITLE_SEQUENCE_SHA1 "261a7185d8f60b90d1a390bf4e48a0c797b52e48") +set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2b/title-sequence-v0.1.2b.zip") +set(TITLE_SEQUENCE_SHA1 "19263f8ca383345959473e64da4785a60f00f420") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip") set(OBJECTS_SHA1 "0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f") diff --git a/openrct2.proj b/openrct2.proj index 03829d1ac2..d07b342143 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -68,8 +68,8 @@ 2fe3bd994b3189899d93f1d5a881e725e046fdc2 https://github.com/google/googletest/archive/$(GtestVersion).zip 058b9df80244c03f1633cb06e9f70471a29ebb8e - https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip - 261a7185d8f60b90d1a390bf4e48a0c797b52e48 + https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2b/title-sequence-v0.1.2b.zip + 19263f8ca383345959473e64da4785a60f00f420 https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip 0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f diff --git a/shell.nix b/shell.nix index 6e10ccd999..f22202962d 100644 --- a/shell.nix +++ b/shell.nix @@ -22,8 +22,8 @@ let title-sequences-src = pkgs.fetchFromGitHub { owner = "OpenRCT2"; repo = "title-sequences"; - rev = "v0.1.2a"; - sha256 = "7536dbd7c8b91554306e5823128f6bb7e94862175ef09d366d25e4bce573d155"; + rev = "v0.1.2b"; + sha256 = "a220b4c3cd3180bebb261cc59141b7fb290b433631ba9c7587a4f2c9f7dc4e4c"; }; in pkgs.stdenv.mkDerivation { diff --git a/src/openrct2-android/app/build.gradle b/src/openrct2-android/app/build.gradle index 090fb9caff..8737b080f4 100644 --- a/src/openrct2-android/app/build.gradle +++ b/src/openrct2-android/app/build.gradle @@ -90,7 +90,7 @@ android.applicationVariants.all { variant -> dest "$variant.mergeAssets.outputDir/data" } download { - src 'https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2a/title-sequence-v0.1.2a.zip' + src 'https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2b/title-sequence-v0.1.2b.zip' dest new File(buildDir, 'title-sequence.zip') } copy { From dec2d1c60b3da575545f7eb316bab969d3e3947e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 25 Jun 2019 22:58:02 +0200 Subject: [PATCH 497/506] Add `ls -l` to allow monitoring of package size on Travis (#9481) --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 92b8ca0dab..cd29b57f7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,6 +41,7 @@ matrix: - mv OpenRCT2/bin/openrct2 OpenRCT2/ && mv OpenRCT2/bin/openrct2-cli OpenRCT2/ && mv OpenRCT2/bin/libopenrct2.so OpenRCT2/ && mv OpenRCT2/share/openrct2 OpenRCT2/data && mv OpenRCT2/share/doc/openrct2 OpenRCT2/doc && mv OpenRCT2/bin/libdiscord-rpc.so OpenRCT2/ - rm -rf OpenRCT2/bin OpenRCT2/share # remove empty dirs - tar cvzf openrct2-linux.tar.gz OpenRCT2/ + - ls -lR - if [[ "z${TRAVIS_TAG}" != "z" ]] ; then export PUSH_BRANCH=master ; else export PUSH_BRANCH=$TRAVIS_BRANCH ; export FILENAME_PART=-${TRAVIS_BRANCH}-$(git rev-parse --short HEAD) ; @@ -65,6 +66,7 @@ matrix: - mv OpenRCT2/bin/openrct2 OpenRCT2/ && mv OpenRCT2/share/openrct2 OpenRCT2/data && mv OpenRCT2/share/doc/openrct2 OpenRCT2/doc - rm -rf OpenRCT2/bin OpenRCT2/share # remove empty dirs - tar cvzf openrct2-linux.tar.gz OpenRCT2/ + - ls -lR - if [[ "z${TRAVIS_TAG}" != "z" ]] ; then export PUSH_BRANCH=master ; else export PUSH_BRANCH=$TRAVIS_BRANCH ; export FILENAME_PART=-${TRAVIS_BRANCH}-$(git rev-parse --short HEAD) ; From b25c1c80887d571a69989838cc7a2513903af700 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 26 Jun 2019 04:00:35 +0000 Subject: [PATCH 498/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/da-DK.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 0e196d94e7..f5c577a61c 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -3994,7 +3994,7 @@ STR_DTLS :Området omkring en dæmning er til rådighed for dig, til at udvik STR_SCNR :Coaster Canyon STR_PARK :Coaster Canyon -STR_DTLS En stor kløft er din, til at forvandle den til en forlystelsespark +STR_DTLS :En stor kløft er din, til at forvandle den til en forlystelsespark STR_SCNR :Thunderstorm Park From c141e58ea6194b1ab88239fe726e399a1033d40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 26 Jun 2019 23:07:19 +0200 Subject: [PATCH 499/506] Switch from RelWithDebInfo to MinSizeRel + -g for Linux amd64 (#9404) In https://github.com/OpenRCT2/OpenRCT2/issues/9357 it was found that the archive to be uploaded is too big, over 32MiB quota imposed by Google App Engine. To alleviate that, switch GCC to `-Os -g` to help reduce the code size a bit. Fixes #9357 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd29b57f7e..88d63de32c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,12 +27,12 @@ env: matrix: include: - os: linux - name: Ubuntu amd64 GCC RelWithDebInfo + name: Ubuntu amd64 GCC MinSizeRel if: type != cron services: - docker env: - - OPENRCT2_CMAKE_OPTS="-G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=OpenRCT2 -DPORTABLE=ON -DCMAKE_CXX_FLAGS=\"-gz\"" TARGET=ubuntu_amd64 + - OPENRCT2_CMAKE_OPTS="-G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=OpenRCT2 -DPORTABLE=ON -DCMAKE_CXX_FLAGS=\"-g -gz\"" TARGET=ubuntu_amd64 - secure: "S3u2VCE2Vy8KNXoeh+DhnzjCmgTX0r95uEZrXDU+IKANOOCKn7Dg4OFDZE3LY/i1y2/EUDpnR5yLC38Ks795EUP/sv/OoMl4tjQ20yERjqWh+gcIRrgx7SdVabuAh3t4aBdaLD4Pfnj5avxeCt6rL7yGnj0wdbrbJSBZPsgSnuQ=" after_success: - sudo chown -R $USER build From f80695d0eba20f59f0be7f57ecd40c8c4919ec2f Mon Sep 17 00:00:00 2001 From: Jim Armstrong Date: Thu, 27 Jun 2019 11:42:18 -0400 Subject: [PATCH 500/506] Fix #9485: Staff cannot be hired in pause mode (#9489) Set ALLOW_WHILE_PAUSED flag for staff hire GA --- src/openrct2/actions/StaffHireNewAction.hpp | 2 +- src/openrct2/network/Network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/StaffHireNewAction.hpp b/src/openrct2/actions/StaffHireNewAction.hpp index bf29df5300..c4664833d6 100644 --- a/src/openrct2/actions/StaffHireNewAction.hpp +++ b/src/openrct2/actions/StaffHireNewAction.hpp @@ -76,7 +76,7 @@ public: uint16_t GetActionFlags() const override { - return GameAction::GetActionFlags(); + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; } void Serialise(DataSerialiser & stream) override diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 5de2b63865..781d69bb70 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -34,7 +34,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 "45" +#define NETWORK_STREAM_VERSION "46" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; From 77037744377c7e4b02c640df4264843e73003099 Mon Sep 17 00:00:00 2001 From: muemart Date: Thu, 27 Jun 2019 19:46:03 +0200 Subject: [PATCH 501/506] Correctly determine size of wchar arrays (#9490) --- src/openrct2/platform/Crash.cpp | 13 +++++++------ src/openrct2/platform/Platform.Win32.cpp | 4 ++-- src/openrct2/platform/Windows.cpp | 12 ++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/openrct2/platform/Crash.cpp b/src/openrct2/platform/Crash.cpp index 0ae6f68ee1..45b0dd0525 100644 --- a/src/openrct2/platform/Crash.cpp +++ b/src/openrct2/platform/Crash.cpp @@ -10,6 +10,7 @@ #include "Crash.h" #ifdef USE_BREAKPAD +# include # include # include # include @@ -99,18 +100,18 @@ static bool OnCrash( wchar_t saveFilePath[MAX_PATH]; wchar_t configFilePath[MAX_PATH]; wchar_t saveFilePathGZIP[MAX_PATH]; - swprintf_s(dumpFilePath, sizeof(dumpFilePath), L"%s\\%s.dmp", dumpPath, miniDumpId); - swprintf_s(saveFilePath, sizeof(saveFilePath), L"%s\\%s.sv6", dumpPath, miniDumpId); - swprintf_s(configFilePath, sizeof(configFilePath), L"%s\\%s.ini", dumpPath, miniDumpId); - swprintf_s(saveFilePathGZIP, sizeof(saveFilePathGZIP), L"%s\\%s.sv6.gz", dumpPath, miniDumpId); + swprintf_s(dumpFilePath, std::size(dumpFilePath), L"%s\\%s.dmp", dumpPath, miniDumpId); + swprintf_s(saveFilePath, std::size(saveFilePath), L"%s\\%s.sv6", dumpPath, miniDumpId); + swprintf_s(configFilePath, std::size(configFilePath), L"%s\\%s.ini", dumpPath, miniDumpId); + swprintf_s(saveFilePathGZIP, std::size(saveFilePathGZIP), L"%s\\%s.sv6.gz", dumpPath, miniDumpId); wchar_t dumpFilePathNew[MAX_PATH]; swprintf_s( - dumpFilePathNew, sizeof(dumpFilePathNew), L"%s\\%s(%s_%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short, + dumpFilePathNew, std::size(dumpFilePathNew), L"%s\\%s(%s_%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short, _wszArchitecture); wchar_t dumpFilePathGZIP[MAX_PATH]; - swprintf_s(dumpFilePathGZIP, sizeof(dumpFilePathGZIP), L"%s.gz", dumpFilePathNew); + swprintf_s(dumpFilePathGZIP, std::size(dumpFilePathGZIP), L"%s.gz", dumpFilePathNew); // Compress the dump { diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 448e149d7e..62ecff739c 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -179,7 +179,7 @@ namespace Platform # ifdef __USE_GETDATEFORMATEX__ wchar_t date[20]; - GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_SHORTDATE, &st, nullptr, date, sizeof(date), nullptr); + GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_SHORTDATE, &st, nullptr, date, (int)std::size(date), nullptr); std::string result = String::ToUtf8(std::wstring(date)); # else char date[20]; @@ -196,7 +196,7 @@ namespace Platform # ifdef __USE_GETDATEFORMATEX__ wchar_t time[20]; - GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &st, nullptr, time, sizeof(time)); + GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &st, nullptr, time, (int)std::size(time)); std::string result = String::ToUtf8(std::wstring(time)); # else char time[20]; diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index e3a0d6f2bc..78535d3bcf 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -413,7 +413,7 @@ uint8_t platform_get_locale_date_format() { // Retrieve short date format, eg "MM/dd/yyyy" wchar_t dateFormat[20]; - if (GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SSHORTDATE, dateFormat, sizeof(dateFormat)) == 0) + if (GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SSHORTDATE, dateFormat, (int)std::size(dateFormat)) == 0) { return DATE_FORMAT_DAY_MONTH_YEAR; } @@ -584,8 +584,8 @@ static bool windows_setup_file_association( [[maybe_unused]] int32_t printResult; - GetModuleFileNameW(nullptr, exePathW, sizeof(exePathW)); - GetModuleFileNameW(plaform_get_dll_module(), dllPathW, sizeof(dllPathW)); + GetModuleFileNameW(nullptr, exePathW, (DWORD)std::size(exePathW)); + GetModuleFileNameW(plaform_get_dll_module(), dllPathW, (DWORD)std::size(dllPathW)); wchar_t* extensionW = utf8_to_widechar(extension); wchar_t* fileTypeTextW = utf8_to_widechar(fileTypeText); @@ -737,7 +737,7 @@ bool platform_setup_uri_protocol() GetModuleFileNameW(nullptr, exePath, MAX_PATH); wchar_t buffer[512]; - swprintf_s(buffer, sizeof(buffer), L"\"%s\" handle-uri \"%%1\"", exePath); + swprintf_s(buffer, std::size(buffer), L"\"%s\" handle-uri \"%%1\"", exePath); if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, buffer, 0) == ERROR_SUCCESS) { // Not compulsory, but gives the application a nicer name @@ -745,11 +745,11 @@ bool platform_setup_uri_protocol() HKEY hMuiCacheKey; if (RegCreateKeyW(hRootKey, MUI_CACHE, &hMuiCacheKey) == ERROR_SUCCESS) { - swprintf_s(buffer, sizeof(buffer), L"%s.FriendlyAppName", exePath); + swprintf_s(buffer, std::size(buffer), L"%s.FriendlyAppName", exePath); // mingw-w64 used to define RegSetKeyValueW's signature incorrectly // You need at least mingw-w64 5.0 including this commit: // https://sourceforge.net/p/mingw-w64/mingw-w64/ci/da9341980a4b70be3563ac09b5927539e7da21f7/ - RegSetKeyValueW(hMuiCacheKey, nullptr, buffer, REG_SZ, L"OpenRCT2", sizeof(L"OpenRCT2") + 1); + RegSetKeyValueW(hMuiCacheKey, nullptr, buffer, REG_SZ, L"OpenRCT2", sizeof(L"OpenRCT2")); } log_verbose("URI protocol setup successful"); From e149722a154725460385e1a1c0af8c66c02b95d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Thu, 27 Jun 2019 22:28:07 +0200 Subject: [PATCH 502/506] Fix #9467: Crash when windows create new window when being closed (#9470) --- src/openrct2-ui/input/MouseInput.cpp | 19 +- src/openrct2-ui/interface/Theme.cpp | 5 +- src/openrct2-ui/interface/Window.cpp | 11 +- src/openrct2/interface/Window.cpp | 367 ++++++++++------------- src/openrct2/interface/Window.h | 4 +- src/openrct2/interface/Window_internal.h | 2 +- 6 files changed, 164 insertions(+), 244 deletions(-) diff --git a/src/openrct2-ui/input/MouseInput.cpp b/src/openrct2-ui/input/MouseInput.cpp index 4f4244449a..31ff8695b8 100644 --- a/src/openrct2-ui/input/MouseInput.cpp +++ b/src/openrct2-ui/input/MouseInput.cpp @@ -105,15 +105,7 @@ static void input_update_tooltip(rct_window* w, rct_widgetindex widgetIndex, int */ void game_handle_input() { - // NOTE: g_window_list may change during the event callbacks. - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto& w = *it; - window_event_periodic_update_call(w.get()); - it = itNext; - } + window_visit_each([](rct_window* w) { window_event_periodic_update_call(w); }); invalidate_all_windows_after_input(); @@ -139,14 +131,7 @@ void game_handle_input() process_mouse_tool(x, y); } - it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto& w = *it; - window_event_unknown_08_call(w.get()); - it = itNext; - } + window_visit_each([](rct_window* w) { window_event_unknown_08_call(w); }); } /** diff --git a/src/openrct2-ui/interface/Theme.cpp b/src/openrct2-ui/interface/Theme.cpp index 87c6c44a1c..9819ecd786 100644 --- a/src/openrct2-ui/interface/Theme.cpp +++ b/src/openrct2-ui/interface/Theme.cpp @@ -866,10 +866,7 @@ rct_string_id theme_desc_get_name(rct_windowclass wc) void colour_scheme_update_all() { - for (auto& w : g_window_list) - { - colour_scheme_update(w.get()); - } + window_visit_each([](rct_window* w) { colour_scheme_update(w); }); } void colour_scheme_update(rct_window* window) diff --git a/src/openrct2-ui/interface/Window.cpp b/src/openrct2-ui/interface/Window.cpp index 7b8146da4f..784069250c 100644 --- a/src/openrct2-ui/interface/Window.cpp +++ b/src/openrct2-ui/interface/Window.cpp @@ -689,10 +689,9 @@ static void window_invalidate_pressed_image_buttons(rct_window* w) */ void invalidate_all_windows_after_input() { - for (auto& w : g_window_list) - { - window_update_scroll_widgets(w.get()); - window_invalidate_pressed_image_buttons(w.get()); - window_event_resize_call(w.get()); - } + window_visit_each([](rct_window* w) { + window_update_scroll_widgets(w); + window_invalidate_pressed_image_buttons(w); + window_event_resize_call(w); + }); } diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 00d487faec..d7a90dd10d 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -34,10 +34,11 @@ #include #include +#include #include #include -std::list> g_window_list; +std::list> g_window_list; rct_window* gWindowAudioExclusive; uint16_t TextInputDescriptionArgs[4]; @@ -81,13 +82,22 @@ static int32_t window_draw_split( rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); -std::list>::iterator window_get_iterator(const rct_window* w) +std::list>::iterator window_get_iterator(const rct_window* w) { - return std::find_if(g_window_list.begin(), g_window_list.end(), [w](const std::unique_ptr& w2) -> bool { + return std::find_if(g_window_list.begin(), g_window_list.end(), [w](const std::shared_ptr& w2) -> bool { return w == w2.get(); }); } +void window_visit_each(std::function func) +{ + auto windowList = g_window_list; + for (auto& w : windowList) + { + func(w.get()); + } +} + /** * * rct2: 0x006ED7B0 @@ -95,28 +105,17 @@ std::list>::iterator window_get_iterator(const rct_w void window_dispatch_update_all() { // gTooltipNotShownTicks++; - - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - window_event_update_call((*it).get()); - it = itNext; - } + window_visit_each([&](rct_window* w) { window_event_update_call(w); }); } void window_update_all_viewports() { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - if ((*it)->viewport != nullptr && window_is_visible((*it).get())) + window_visit_each([&](rct_window* w) { + if (w->viewport != nullptr && window_is_visible(w)) { - viewport_update_position((*it).get()); + viewport_update_position(w); } - it = itNext; - } + }); } /** @@ -135,22 +134,11 @@ void window_update_all() { gWindowUpdateTicks = 0; - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = (*it).get(); - window_event_periodic_update_call(w); - it = itNext; - } + window_visit_each([](rct_window* w) { window_event_periodic_update_call(w); }); } // Border flash invalidation - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); + window_visit_each([](rct_window* w) { if (w->flags & WF_WHITE_BORDER_MASK) { w->flags -= WF_WHITE_BORDER_ONE; @@ -159,8 +147,7 @@ void window_update_all() window_invalidate(w); } } - it = itNext; - } + }); auto windowManager = OpenRCT2::GetContext()->GetUiContext()->GetWindowManager(); windowManager->UpdateMouseWheel(); @@ -252,6 +239,35 @@ void window_close(rct_window* window) } } +template static void window_close_by_condition(_TPred pred) +{ + bool listUpdated; + do + { + listUpdated = false; + + auto windowList = g_window_list; + for (auto& w : windowList) + { + if (pred(w.get())) + { + // Keep track of current amount, if a new window is created upon closing + // we need to break this current iteration and restart. + size_t previousCount = g_window_list.size(); + + window_close(w.get()); + + if (previousCount >= g_window_list.size()) + { + listUpdated = true; + break; + } + } + } + + } while (listUpdated); +} + /** * Closes all windows with the specified window class. * rct2: 0x006ECCF4 @@ -259,16 +275,7 @@ void window_close(rct_window* window) */ void window_close_by_class(rct_windowclass cls) { - std::vector closeList; - for (auto& w : g_window_list) - { - if (w->classification == cls) - closeList.push_back(w.get()); - } - for (auto& w : closeList) - { - window_close(w); - } + window_close_by_condition([&](rct_window* w) -> bool { return w->classification == cls; }); } /** @@ -279,16 +286,7 @@ void window_close_by_class(rct_windowclass cls) */ void window_close_by_number(rct_windowclass cls, rct_windownumber number) { - std::vector closeList; - for (auto& w : g_window_list) - { - if (w->classification == cls && w->number == number) - closeList.push_back(w.get()); - } - for (auto& w : closeList) - { - window_close(w); - } + window_close_by_condition([cls, number](rct_window* w) -> bool { return w->classification == cls && w->number == number; }); } /** @@ -338,17 +336,12 @@ void window_close_top() window_close_by_class(WC_DROPDOWN); if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) + { if (gS6Info.editor_step != EDITOR_STEP_LANDSCAPE_EDITOR) return; - for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) - { - auto& w = (*it); - if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - { - window_close(w.get()); - break; - } } + + window_close_by_condition([](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); }); } /** @@ -359,33 +352,16 @@ void window_close_top() void window_close_all() { window_close_by_class(WC_DROPDOWN); - - std::vector closeList; - for (auto& w : g_window_list) - { - if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - closeList.push_back(w.get()); - } - for (auto& w : closeList) - { - window_close(w); - } + window_close_by_condition([](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); }); } void window_close_all_except_class(rct_windowclass cls) { window_close_by_class(WC_DROPDOWN); - std::vector closeList; - for (auto& w : g_window_list) - { - if (w->classification != cls && !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - closeList.push_back(w.get()); - } - for (auto& w : closeList) - { - window_close(w); - } + window_close_by_condition([cls](rct_window* w) -> bool { + return w->classification != cls && !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); + }); } /** @@ -393,16 +369,7 @@ void window_close_all_except_class(rct_windowclass cls) */ void window_close_all_except_flags(uint16_t flags) { - std::vector closeList; - for (auto& w : g_window_list) - { - if (!(w->flags & flags)) - closeList.push_back(w.get()); - } - for (auto& w : closeList) - { - window_close(w); - } + window_close_by_condition([flags](rct_window* w) -> bool { return !(w->flags & flags); }); } /** @@ -482,6 +449,16 @@ void window_invalidate(rct_window* window) gfx_set_dirty_blocks(window->x, window->y, window->x + window->width, window->y + window->height); } +template static void window_invalidate_by_condition(_TPred pred) +{ + window_visit_each([pred](rct_window* w) { + if (pred(w)) + { + window_invalidate(w); + } + }); +} + /** * Invalidates all windows with the specified window class. * rct2: 0x006EC3AC @@ -489,17 +466,7 @@ void window_invalidate(rct_window* window) */ void window_invalidate_by_class(rct_windowclass cls) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); - if (w->classification == cls) - { - window_invalidate(w); - } - it = itNext; - } + window_invalidate_by_condition([cls](rct_window* w) -> bool { return w->classification == cls; }); } /** @@ -508,17 +475,8 @@ void window_invalidate_by_class(rct_windowclass cls) */ void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); - if (w->classification == cls && w->number == number) - { - window_invalidate(w); - } - it = itNext; - } + window_invalidate_by_condition( + [cls, number](rct_window* w) -> bool { return w->classification == cls && w->number == number; }); } /** @@ -526,14 +484,7 @@ void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number) */ void window_invalidate_all() { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); - window_invalidate(w); - it = itNext; - } + window_visit_each([](rct_window* w) { window_invalidate(w); }); } /** @@ -559,22 +510,27 @@ void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex) gfx_set_dirty_blocks(w->x + widget->left, w->y + widget->top, w->x + widget->right + 1, w->y + widget->bottom + 1); } +template static void widget_invalidate_by_condition(_TPred pred) +{ + window_visit_each([pred](rct_window* w) { + if (pred(w)) + { + window_invalidate(w); + } + }); +} + /** * Invalidates the specified widget of all windows that match the specified window class. */ void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); + window_visit_each([cls, widgetIndex](rct_window* w) { if (w->classification == cls) { widget_invalidate(w, widgetIndex); } - it = itNext; - } + }); } /** @@ -583,17 +539,12 @@ void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex */ void widget_invalidate_by_number(rct_windowclass cls, rct_windownumber number, rct_widgetindex widgetIndex) { - auto it = g_window_list.begin(); - while (it != g_window_list.end()) - { - auto itNext = std::next(it); - auto w = it->get(); + window_visit_each([cls, number, widgetIndex](rct_window* w) { if (w->classification == cls && w->number == number) { widget_invalidate(w, widgetIndex); } - it = itNext; - } + }); } /** @@ -754,30 +705,29 @@ rct_window* window_bring_to_front_by_number(rct_windowclass cls, rct_windownumbe */ void window_push_others_right(rct_window* window) { - for (auto& w : g_window_list) - { - if (w.get() == window) - continue; + window_visit_each([window](rct_window* w) { + if (w == window) + return; if (w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)) - continue; + return; if (w->x >= window->x + window->width) - continue; + return; if (w->x + w->width <= window->x) - continue; + return; if (w->y >= window->y + window->height) - continue; + return; if (w->y + w->height <= window->y) - continue; + return; - window_invalidate(w.get()); + window_invalidate(w); if (window->x + window->width + 13 >= context_get_width()) - continue; + return; uint16_t push_amount = window->x + window->width - w->x + 3; w->x += push_amount; - window_invalidate(w.get()); + window_invalidate(w); if (w->viewport != nullptr) w->viewport->x += push_amount; - } + }); } /** @@ -786,41 +736,36 @@ void window_push_others_right(rct_window* window) */ void window_push_others_below(rct_window* w1) { - int32_t push_amount; - // Enumerate through all other windows - for (auto& w2 : g_window_list) - { - if (w1 == w2.get()) - continue; - + window_visit_each([w1](rct_window* w2) { + if (w1 == w2) + return; // ? if (w2->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)) - continue; - + return; // Check if w2 intersects with w1 if (w2->x > (w1->x + w1->width) || w2->x + w2->width < w1->x) - continue; + return; if (w2->y > (w1->y + w1->height) || w2->y + w2->height < w1->y) - continue; + return; // Check if there is room to push it down if (w1->y + w1->height + 80 >= context_get_height()) - continue; + return; // Invalidate the window's current area - window_invalidate(w2.get()); + window_invalidate(w2); - push_amount = w1->y + w1->height - w2->y + 3; + int32_t push_amount = w1->y + w1->height - w2->y + 3; w2->y += push_amount; // Invalidate the window's new area - window_invalidate(w2.get()); + window_invalidate(w2); // Update viewport position if necessary if (w2->viewport != nullptr) w2->viewport->y += push_amount; - } + }); } /** @@ -971,11 +916,7 @@ void window_scroll_to_location(rct_window* w, int32_t x, int32_t y, int32_t z) */ static void call_event_viewport_rotate_on_all_windows() { - for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) - { - auto w = it->get(); - window_event_viewport_rotate_call(w); - } + window_visit_each([](rct_window* w) { window_event_viewport_rotate_call(w); }); } /** @@ -1655,8 +1596,7 @@ void window_bubble_list_item(rct_window* w, int32_t item_position) void window_relocate_windows(int32_t width, int32_t height) { int32_t new_location = 8; - for (auto& w : g_window_list) - { + window_visit_each([width, height, &new_location](rct_window* w) { // Work out if the window requires moving if (w->x + 10 < width) { @@ -1664,12 +1604,12 @@ void window_relocate_windows(int32_t width, int32_t height) { if (w->y - 22 < height) { - continue; + return; } } if (w->y + 10 < height) { - continue; + return; } } @@ -1688,7 +1628,7 @@ void window_relocate_windows(int32_t width, int32_t height) w->viewport->x -= x - w->x; w->viewport->y -= y - w->y; } - } + }); } /** @@ -1861,21 +1801,21 @@ static void window_snap_left(rct_window* w, int32_t proximity) auto wLeftProximity = w->x - (proximity * 2); auto wRightProximity = w->x + (proximity * 2); auto rightMost = INT32_MIN; - for (auto& w2 : g_window_list) - { - if (w2.get() == w || w2.get() == mainWindow) - continue; + + window_visit_each([&](rct_window* w2) { + if (w2 == w || w2 == mainWindow) + return; auto right = w2->x + w2->width; if (wBottom < w2->y || w->y > w2->y + w2->height) - continue; + return; if (right < wLeftProximity || right > wRightProximity) - continue; + return; rightMost = std::max(rightMost, right); - } + }); if (0 >= wLeftProximity && 0 <= wRightProximity) rightMost = std::max(rightMost, 0); @@ -1891,21 +1831,21 @@ static void window_snap_top(rct_window* w, int32_t proximity) auto wTopProximity = w->y - (proximity * 2); auto wBottomProximity = w->y + (proximity * 2); auto bottomMost = INT32_MIN; - for (auto& w2 : g_window_list) - { - if (w2.get() == w || w2.get() == mainWindow) - continue; + + window_visit_each([&](rct_window* w2) { + if (w2 == w || w2 == mainWindow) + return; auto bottom = w2->y + w2->height; if (wRight < w2->x || w->x > w2->x + w2->width) - continue; + return; if (bottom < wTopProximity || bottom > wBottomProximity) - continue; + return; bottomMost = std::max(bottomMost, bottom); - } + }); if (0 >= wTopProximity && 0 <= wBottomProximity) bottomMost = std::max(bottomMost, 0); @@ -1922,19 +1862,19 @@ static void window_snap_right(rct_window* w, int32_t proximity) auto wLeftProximity = wRight - (proximity * 2); auto wRightProximity = wRight + (proximity * 2); auto leftMost = INT32_MAX; - for (auto& w2 : g_window_list) - { - if (w2.get() == w || w2.get() == mainWindow) - continue; + + window_visit_each([&](rct_window* w2) { + if (w2 == w || w2 == mainWindow) + return; if (wBottom < w2->y || w->y > w2->y + w2->height) - continue; + return; if (w2->x < wLeftProximity || w2->x > wRightProximity) - continue; + return; leftMost = std::min(leftMost, w2->x); - } + }); auto screenWidth = context_get_width(); if (screenWidth >= wLeftProximity && screenWidth <= wRightProximity) @@ -1952,19 +1892,19 @@ static void window_snap_bottom(rct_window* w, int32_t proximity) auto wTopProximity = wBottom - (proximity * 2); auto wBottomProximity = wBottom + (proximity * 2); auto topMost = INT32_MAX; - for (auto& w2 : g_window_list) - { - if (w2.get() == w || w2.get() == mainWindow) - continue; + + window_visit_each([&](rct_window* w2) { + if (w2 == w || w2 == mainWindow) + return; if (wRight < w2->x || w->x > w2->x + w2->width) - continue; + return; if (w2->y < wTopProximity || w2->y > wBottomProximity) - continue; + return; topMost = std::min(topMost, w2->y); - } + }); auto screenHeight = context_get_height(); if (screenHeight >= wTopProximity && screenHeight <= wBottomProximity) @@ -2142,17 +2082,15 @@ void window_draw_all(rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t windowDPI.pitch = dpi->width + dpi->pitch + left - right; windowDPI.zoom_level = 0; - for (auto& w : g_window_list) - { + window_visit_each([&windowDPI, left, top, right, bottom](rct_window* w) { if (w->flags & WF_TRANSPARENT) - continue; + return; if (right <= w->x || bottom <= w->y) - continue; + return; if (left >= w->x + w->width || top >= w->y + w->height) - continue; - - window_draw(&windowDPI, w.get(), left, top, right, bottom); - } + return; + window_draw(&windowDPI, w, left, top, right, bottom); + }); } rct_viewport* window_get_previous_viewport(rct_viewport* current) @@ -2179,14 +2117,13 @@ rct_viewport* window_get_previous_viewport(rct_viewport* current) void window_reset_visibilities() { // reset window visibility status to unknown - for (auto& w : g_window_list) - { + window_visit_each([](rct_window* w) { w->visibility = VC_UNKNOWN; if (w->viewport != nullptr) { w->viewport->visibility = VC_UNKNOWN; } - } + }); } void window_init_all() diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 7c6384dd21..a9f9f96126 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -13,6 +13,7 @@ #include "../common.h" #include "../ride/RideTypes.h" +#include #include #include #include @@ -582,7 +583,8 @@ extern colour_t gCurrentWindowColours[4]; extern bool gDisableErrorWindowSound; -std::list>::iterator window_get_iterator(const rct_window* w); +std::list>::iterator window_get_iterator(const rct_window* w); +void window_visit_each(std::function func); void window_dispatch_update_all(); void window_update_all_viewports(); diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index dde8a72076..edd3c7799d 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -104,4 +104,4 @@ struct rct_window }; // rct2: 0x01420078 -extern std::list> g_window_list; +extern std::list> g_window_list; From a7f89601514a7236e54afbe87eca6972cf638447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Mon, 1 Jul 2019 22:59:31 +0200 Subject: [PATCH 503/506] Fix #9498: Only close the most recent window when using the hotkey (#9504) --- src/openrct2/interface/Window.cpp | 67 ++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index d7a90dd10d..45d806ca36 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -51,7 +51,6 @@ TextInputSession* gTextInput; uint16_t gWindowUpdateTicks; uint16_t gWindowMapFlashingFlags; - colour_t gCurrentWindowColours[4]; // converted from uint16_t values at 0x009A41EC - 0x009A4230 @@ -78,6 +77,13 @@ static constexpr const float window_scroll_locations[][2] = { }; // clang-format on +namespace WindowCloseFlags +{ + static constexpr uint32_t None = 0; + static constexpr uint32_t IterateReverse = (1 << 0); + static constexpr uint32_t CloseSingle = (1 << 1); +} // namespace WindowCloseFlags + static int32_t window_draw_split( rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); @@ -239,31 +245,53 @@ void window_close(rct_window* window) } } -template static void window_close_by_condition(_TPred pred) +template static void window_close_by_condition(_TPred pred, uint32_t flags = WindowCloseFlags::None) { bool listUpdated; do { listUpdated = false; - auto windowList = g_window_list; - for (auto& w : windowList) - { - if (pred(w.get())) + auto closeSingle = [&](std::shared_ptr window) -> bool { + if (!pred(window.get())) { - // Keep track of current amount, if a new window is created upon closing - // we need to break this current iteration and restart. - size_t previousCount = g_window_list.size(); - - window_close(w.get()); - - if (previousCount >= g_window_list.size()) - { - listUpdated = true; - break; - } + return false; } - } + + // Keep track of current amount, if a new window is created upon closing + // we need to break this current iteration and restart. + size_t previousCount = g_window_list.size(); + + window_close(window.get()); + + if ((flags & WindowCloseFlags::CloseSingle) != 0) + { + // Only close a single one. + return true; + } + + if (previousCount >= g_window_list.size()) + { + // A new window was created during the close event. + return true; + } + + // Keep closing windows. + return false; + }; + + // The closest to something like for_each_if is using find_if in order to avoid duplicate code + // to change the loop direction. + auto windowList = g_window_list; + if ((flags & WindowCloseFlags::IterateReverse) != 0) + listUpdated = std::find_if(windowList.rbegin(), windowList.rend(), closeSingle) != windowList.rend(); + else + listUpdated = std::find_if(windowList.begin(), windowList.end(), closeSingle) != windowList.end(); + + // If requested to close only a single window and a new window was created during close + // we ignore it. + if ((flags & WindowCloseFlags::CloseSingle) != 0) + break; } while (listUpdated); } @@ -341,7 +369,8 @@ void window_close_top() return; } - window_close_by_condition([](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); }); + auto pred = [](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); }; + window_close_by_condition(pred, WindowCloseFlags::CloseSingle | WindowCloseFlags::IterateReverse); } /** From 8ff0cf95464777b1285ddea4e111e396f0656d53 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 6 Jul 2019 16:50:58 +0200 Subject: [PATCH 504/506] Update objects to 1.0.11 (#9529) --- CMakeLists.txt | 4 ++-- OpenRCT2.xcodeproj/project.pbxproj | 2 +- distribution/changelog.txt | 1 + openrct2.proj | 4 ++-- shell.nix | 4 ++-- src/openrct2-android/app/build.gradle | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06235a157b..34a22049d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,8 @@ set(CMAKE_MACOSX_RPATH 1) set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2b/title-sequence-v0.1.2b.zip") set(TITLE_SEQUENCE_SHA1 "19263f8ca383345959473e64da4785a60f00f420") -set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip") -set(OBJECTS_SHA1 "0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f") +set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.11/objects.zip") +set(OBJECTS_SHA1 "8674120086929f9196560d77cada631fb478d7c0") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 8fecaa1f50..1fd8cf5444 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -3727,7 +3727,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"1.0.10\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; + shellScript = "version=\"1.0.11\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; }; C68B2D471EC790710020651C /* Download Libraries */ = { isa = PBXShellScriptBuildPhase; diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 2acf3cba70..a7d35163cb 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -63,6 +63,7 @@ - Fix: [#9411] Ad campaigns end too soon. - Fix: [#9424] Crash using multi threading with TrueType fonts. - Fix: [#9476] Running `simulate` command on park yields `Completed: (null)`. +- Fix: [#9520] Time Twister object artdec29 conversion problem. - Fix: Guests eating popcorn are drawn as if they're eating pizza. - Fix: The arbitrary ride type and vehicle dropdown lists are ordered case-sensitively. - Improved: [#6116] Expose colour scheme for track elements in the tile inspector. diff --git a/openrct2.proj b/openrct2.proj index d07b342143..c93724bcb9 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -70,8 +70,8 @@ 058b9df80244c03f1633cb06e9f70471a29ebb8e https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2b/title-sequence-v0.1.2b.zip 19263f8ca383345959473e64da4785a60f00f420 - https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip - 0e88a1a6d845eb3a56ad68ecf60a9d6a4194250f + https://github.com/OpenRCT2/objects/releases/download/v1.0.11/objects.zip + 8674120086929f9196560d77cada631fb478d7c0 diff --git a/shell.nix b/shell.nix index f22202962d..bc62e53b35 100644 --- a/shell.nix +++ b/shell.nix @@ -15,8 +15,8 @@ let objects-src = pkgs.fetchFromGitHub { owner = "OpenRCT2"; repo = "objects"; - rev = "v1.0.10"; - sha256 = "4f261964f1c01a04b7600d3d082fb4d3d9ec0d543c4eb66a819eb2ad01417aa0"; + rev = "v1.0.11"; + sha256 = "21e83bd2afad735cc0f5d13f9c99a5dee81ea0ef3a6b937c0bfaadb7f0572c34"; }; title-sequences-src = pkgs.fetchFromGitHub { diff --git a/src/openrct2-android/app/build.gradle b/src/openrct2-android/app/build.gradle index 8737b080f4..884ff052cc 100644 --- a/src/openrct2-android/app/build.gradle +++ b/src/openrct2-android/app/build.gradle @@ -98,7 +98,7 @@ android.applicationVariants.all { variant -> into "$variant.mergeAssets.outputDir/data/title" } download { - src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.10/objects.zip' + src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.11/objects.zip' dest new File(buildDir, 'objects.zip') } copy { From b973d51c73657d488f93beb0adf5d677387da296 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 6 Jul 2019 19:08:42 +0200 Subject: [PATCH 505/506] Remove fix for feature introduced after 0.2.2 [ci skip] --- distribution/changelog.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index a7d35163cb..7aef4f3128 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -61,7 +61,6 @@ - Fix: [#9324] Crash trying to remove invalid footpath scenery. - Fix: [#9402] Ad campaigns disappear when you save and load the game. - Fix: [#9411] Ad campaigns end too soon. -- Fix: [#9424] Crash using multi threading with TrueType fonts. - Fix: [#9476] Running `simulate` command on park yields `Completed: (null)`. - Fix: [#9520] Time Twister object artdec29 conversion problem. - Fix: Guests eating popcorn are drawn as if they're eating pizza. From b7b846c0d5f11dcee871e3c3d8441dcda430def5 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 8 Jul 2019 04:00:21 +0000 Subject: [PATCH 506/506] Merge Localisation/master into OpenRCT2/develop. --- data/language/ar-EG.txt | 79 ++++++++++++++++++++++++++++++++--------- data/language/hu-HU.txt | 18 +++++----- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/data/language/ar-EG.txt b/data/language/ar-EG.txt index 27bda0920c..3bdc6a3f80 100644 --- a/data/language/ar-EG.txt +++ b/data/language/ar-EG.txt @@ -552,8 +552,8 @@ STR_1167 :...لا يمكن زيادة مستوي الماء هنا STR_1168 :الإعدادات STR_1169 :(لا شئ) STR_1170 :{STRING} -STR_1171 :{RED} مغلق - - -STR_1172 :{YELLOW}{STRINGID} - - +STR_1171 :{RED} مغلق +STR_1172 :{YELLOW}{STRINGID} STR_1173 :{SMALLFONT}{BLACK} ابني ممشي وخطوط إنتظار STR_1174 :Banner sign in the way STR_1175 :Can't build this on sloped footpath @@ -1109,7 +1109,7 @@ STR_1726 :الأرض ليست للبيع! STR_1727 :حقوق الإنشاء ليست للبيع! STR_1728 :Can't buy construction rights here... STR_1729 :الأرض ليست مملوكة للحديقة! -STR_1730 :{RED}مغلقة - - +STR_1730 :{RED}مغلقة STR_1731 :{WHITE}{STRINGID} - - STR_1732 :بناء STR_1733 :الوضع @@ -2240,19 +2240,19 @@ STR_2977 :Staff member name STR_2978 :Enter new name for this member of staff: STR_2979 :Can't name staff member... STR_2980 :Too many banners in game -STR_2981 :{RED}No entry - - +STR_2981 :{RED}لا دخول STR_2982 :Banner text STR_2983 :Enter new text for this banner: STR_2984 :Can't set new text for banner... -STR_2985 :Banner -STR_2986 :{SMALLFONT}{BLACK}Change text on banner +STR_2985 :يافطة +STR_2986 :{SMALLFONT}{BLACK}غير الكلام علي اليافطة STR_2987 :{SMALLFONT}{BLACK}Set this banner as a 'no-entry' sign for guests -STR_2988 :{SMALLFONT}{BLACK}Demolish this banner +STR_2988 :{SMALLFONT}{BLACK}دمر هذه اليافطة STR_2989 :{SMALLFONT}{BLACK}حدد اللون الأساسي STR_2990 :{SMALLFONT}{BLACK}حدد لون الكتابة STR_2991 :يافطة STR_2992 :الكلام علي اليافطة -STR_2993 :أدخل كلام جديد لكتابته علي اليافطة: +STR_2993 ::أدخل كلام جديد لكتابته علي اليافطة STR_2994 :{SMALLFONT}{BLACK}تغيير االكلام علي اليافطة STR_2995 :{SMALLFONT}{BLACK}تدمير هذه اليافطة STR_2996 :{BLACK}ABC @@ -2269,7 +2269,7 @@ STR_3006 :{PALEGOLD}ABC STR_3007 :{LIGHTPINK}ABC STR_3008 :{PEARLAQUA}ABC STR_3009 :{PALESILVER}ABC -STR_3010 :غير قادر علي تحميل الملف... +STR_3010 :...غير قادر علي تحميل الملف STR_3011 :الملف يحتوي علي بيانات خاطئة STR_3012 :Dodgems beat style STR_3013 :Fairground organ style @@ -2419,7 +2419,6 @@ STR_3190 :Path Extras STR_3191 :Scenery Groups STR_3192 :Park Entrance STR_3193 :Water -STR_3194 :Scenario Description STR_3195 :Invention List STR_3196 :{WINDOW_COLOUR_2}Research Group: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Items pre-invented at start of game: @@ -2519,7 +2518,7 @@ STR_3290 :بارد ومبتل STR_3291 :دافئ STR_3292 :حار وجاف STR_3293 :بارد -STR_3294 :تغيير... +STR_3294 :...تغيير STR_3295 :{SMALLFONT}{BLACK}Change name of park STR_3296 :{SMALLFONT}{BLACK}Change name of scenario STR_3297 :{SMALLFONT}{BLACK}Change detail notes about park / scenario @@ -3587,8 +3586,8 @@ STR_6125 :نوع العنصر STR_6126 :نوع غير معروف STR_6127 :{STRING}:الملف STR_6128 :.الملف لا يمكن تحملية لأن هناك بعض العناصر المُشار إليها فيه مفقودة أو ربما تكون متضررة. قائمة بهذه العناصر معروضة في الأسفل -STR_6129 :إنسخ المحدد إلي الحافظة -STR_6130 :إنسخ القائمة كاملة إلي الحافظة +STR_6129 :إنسخ +STR_6130 :إنسخ الكل STR_6131 :مصدر العنصر STR_6132 :تجاهل حالة التطوير STR_6133 :{SMALLFONT}{BLACK}Access rides and scenery that have not yet been invented @@ -3728,12 +3727,60 @@ STR_6270 :أسطح التضاريس STR_6271 :حواف التضاريس STR_6272 :المحطات STR_6273 :الموسيقي -STR_6274 :لا يمكن تحديد مخطط اللون... +STR_6274 :...لا يمكن تحديد مخطط اللون STR_6275 :{WINDOW_COLOUR_2}نمط المحطة -STR_6276 :{RED}{STRINGID} هل علق الزوار؟ ربما يكون هذا بسبب أفعوانية غير صالحة أو وضع تشغيل غير صالح. -STR_6277 :{WINDOW_COLOUR_2}فهرسة المحطة: {BLACK}{COMMA16} +STR_6276 :{RED}{STRINGID} .هل علق الزوار؟ ربما يكون هذا بسبب أفعوانية غير صالحة أو وضع تشغيل غير صالح +STR_6277 :{WINDOW_COLOUR_2} {BLACK}{COMMA16} :فهرسة المحطة STR_6278 :عدد ملفات الحفظ التلقائي STR_6279 :{SMALLFONT}{BLACK}عدد ملفات الحفظ التلقائي التي يجب إبقائها في المرة الواحدة +STR_6280 :{SMALLFONT}{BLACK}الدردشة +STR_6281 :{SMALLFONT}{BLACK}أظهر زر منفصل لنافذة الدردشة في شريط الأدوات +STR_6282 :الدردشة +STR_6283 :الدردشة غير متوفرة حالياً. هل أنت متصل بالسرفر؟ +STR_6284 :الشبكة +STR_6285 :معلومات الشبكة +STR_6286 :يستقبل +STR_6287 :يُرسل +STR_6288 :إجمالي المُستقبل +STR_6289 :إجمالي المُرسل +STR_6290 :البرتكول الأساسي +STR_6291 :الأوامر +STR_6292 :الخريطة +STR_6293 :بايت +STR_6294 :كيلو بايت +STR_6295 :ميجا بايت +STR_6296 :جيجا بايت +STR_6297 :تيرا بايت +STR_6298 :{STRING}/ثانية +STR_6299 :حمل الكل +STR_6300 :{SMALLFONT}{BLACK}.حمل كل العناصر المفقودة إذا كانت متوفرة علي الإنترنت +STR_6301 :{SMALLFONT}{BLACK}.إنسخ أسم العنصر المُحدد إلي الحافظة +STR_6302 :{SMALLFONT}{BLACK}.إنسخ قائمة العناصر المفقودة كلها إلي الحافظة +STR_6303 :({COMMA16} / {COMMA16}): [{STRING}] يُحمل العنصر +STR_6304 :إفتح مُحدد المشهد +STR_6305 :المعالجة المتعددة +STR_6306 :{SMALLFONT}{BLACK}.اعداد إختباري لإستخدام عدة معالجات لكي ترسم المشهد، ربما يسبب عدم الإتزان +STR_6307 :{BLACK}{STRINGID} :نمط اللون +STR_6309 :إعادة الإتصال +STR_6310 :{WINDOW_COLOUR_2} {BLACK}{INT32} {INT32} {INT32} :الموقع +STR_6311 :{WINDOW_COLOUR_2} {BLACK}{INT32} {INT32} {INT32} :التالي +STR_6312 :(السطح) +STR_6313 :({INT32} الإنحدار) +STR_6314 :{WINDOW_COLOUR_2}مسافة: {BLACK}{INT32}, {INT32} تفاوت {INT32} +STR_6315 :{WINDOW_COLOUR_2}هدف مُحدد المسار: {BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6316 :{WINDOW_COLOUR_2}تاريخ مُحدد المسار: +STR_6317 :{BLACK}{INT32}، {INT32}، {INT32} مسار {INT32} +STR_6318 :{STRING} :ملف السجل {NEWLINE}.تم إكتشاف إنفصال عن الشبكة +STR_6319 :{WINDOW_COLOUR_2}مكابح البلوك مغلقة +STR_6320 :{WINDOW_COLOUR_2}غير قابل للتدمير +STR_6321 :{WINDOW_COLOUR_2}الإضافة متضررة +STR_6322 :{WINDOW_COLOUR_2} {BLACK}{INT32} :رقم النقش المتحرك +STR_6323 :يُحاكي +STR_6324 :حاكي +STR_6325 :{SMALLFONT}{BLACK}حاكي الرحلة/المزار +STR_6326 :...{POP16}{POP16}{POP16}{STRINGID} لا يمكن محاكاة +STR_6327 :خلفية شفافة للقطات الشاشة العملاقة +STR_6328 :{SMALLFONT}{BLACK}.مع هذا الإعداد، صور لقطة الشاشة العملاقة ستحصل علي خلفية شفافة بدلاً من الخلفية السوداء الإفتراضية ############# # Scenarios # diff --git a/data/language/hu-HU.txt b/data/language/hu-HU.txt index b6cdadfe4e..ee825a3272 100644 --- a/data/language/hu-HU.txt +++ b/data/language/hu-HU.txt @@ -3087,15 +3087,15 @@ STR_5787 :{COMMA32} játékos van online STR_5788 :Alapértelmezett ellenőrzési idő: STR_5789 :Villámhatás kikapcsolása STR_5791 :{SMALLFONT}{BLACK}Az összes játék megbízhatóságát 100%-ra{NEWLINE}állítja és visszaállítja az építési idejüket „idén”-re -STR_5792: {SMALLFONT}{BLACK}Megjavítja az összes meghibásodott játékot -STR_5793: {SMALLFONT}{BLACK}Törli a játék ütközési előzményeit,{NEWLINE}így a vendégek nem fognak panaszkodni, hogy nem biztonságos -STR_5794: {SMALLFONT}{BLACK}Néhány pálya nem engedélyezi pár játék{NEWLINE}szerkesztését, melyek már a parkban vannak{NEWLINE}Ez a csalás feloldja a korlátozást -STR_5795: {SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is -STR_5796: {SMALLFONT}{BLACK}Kényszeríti a parkot, hogy kinyisson vagy bezárjon -STR_5797: {SMALLFONT}{BLACK}Letiltja az időjárás-változásokat{NEWLINE}és befagyasztja a jelenlegi időjárást -STR_5798: {SMALLFONT}{BLACK}Engedélyezi az építési tevékenységeket szünet közben -STR_5799: {SMALLFONT}{BLACK}Letiltja a játékok fékhiba miatta meghibásodásait és ütközéseit -STR_5800: {SMALLFONT}{BLACK}Megakadályozza, hogy meghibásodjanak a játékok +STR_5792 :{SMALLFONT}{BLACK}Megjavítja az összes meghibásodott játékot +STR_5793 :{SMALLFONT}{BLACK}Törli a játék ütközési előzményeit,{NEWLINE}így a vendégek nem fognak panaszkodni, hogy nem biztonságos +STR_5794 :{SMALLFONT}{BLACK}Néhány pálya nem engedélyezi pár játék{NEWLINE}szerkesztését, melyek már a parkban vannak{NEWLINE}Ez a csalás feloldja a korlátozást +STR_5795 :{SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is +STR_5796 :{SMALLFONT}{BLACK}Kényszeríti a parkot, hogy kinyisson vagy bezárjon +STR_5797 :{SMALLFONT}{BLACK}Letiltja az időjárás-változásokat{NEWLINE}és befagyasztja a jelenlegi időjárást +STR_5798 :{SMALLFONT}{BLACK}Engedélyezi az építési tevékenységeket szünet közben +STR_5799 :{SMALLFONT}{BLACK}Letiltja a játékok fékhiba miatta meghibásodásait és ütközéseit +STR_5800 :{SMALLFONT}{BLACK}Megakadályozza, hogy meghibásodjanak a játékok STR_5801 :Szemetelés kikapcsolása STR_5790 :{SMALLFONT}{BLACK}Az RCT1-stílusú árazás ki- és bekapcsolása{NEWLINE}(például belépési díj egyszerre a parkba és a játékokra) STR_5795 :{SMALLFONT}{BLACK}A vendégek a park összes játékára felülnek,{NEWLINE}még az extrém magas intenzitásúakra is