From 06e0e3db510685a4794be9283d2ca462ab8f532c Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 21:45:42 -0700 Subject: [PATCH 01/45] add MACOS_BUNDLE cmake option to build self-contained app bundle --- CMakeLists.txt | 4 ++- distribution/macos/Info.plist | 8 ++--- src/openrct2-ui/CMakeLists.txt | 66 ++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e5e6a387c..2a7788ddca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,8 @@ option(DOWNLOAD_OBJECTS "Download objects during installation." ON) CMAKE_DEPENDENT_OPTION(DOWNLOAD_REPLAYS "Download replays during installation." ON "WITH_TESTS" OFF) option(MACOS_USE_DEPENDENCIES "Use OpenRCT2 dependencies instead of system libraries" ON) +CMAKE_DEPENDENT_OPTION(MACOS_BUNDLE "Build macOS application bundle (OpenRCT2.app)" OFF + "MACOS_USE_DEPENDENCIES; NOT DISABLE_GUI" OFF) # Options option(STATIC "Create a static build.") @@ -435,7 +437,7 @@ if (DOWNLOAD_REPLAYS) endif () install(TARGETS "libopenrct2" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") -if(NOT DISABLE_GUI) +if(NOT DISABLE_GUI AND NOT MACOS_BUNDLE) install(TARGETS "openrct2" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() install(TARGETS "openrct2-cli" OPTIONAL RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") diff --git a/distribution/macos/Info.plist b/distribution/macos/Info.plist index 800f356eaa..f7fd4c88c5 100644 --- a/distribution/macos/Info.plist +++ b/distribution/macos/Info.plist @@ -3,13 +3,13 @@ CFBundleExecutable - $(EXECUTABLE_NAME) + ${EXECUTABLE_NAME} CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString @@ -17,7 +17,7 @@ CFBundleSignature ORCT LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) + ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright OpenRCT2 is licensed under the GNU General Public License version 3 CFBundleAllowMixedLocalizations diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index 49b8bc55fd..054a9f91de 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -127,3 +127,69 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") get_target_property(OPENRCT2_INCLUDE_DIRS ${PROJECT_NAME} INCLUDE_DIRECTORIES) set_target_properties(${PROJECT_NAME}-headers-check PROPERTIES INCLUDE_DIRECTORIES "${OPENRCT2_INCLUDE_DIRS}") endif () + + +if(MACOS_BUNDLE) + add_dependencies(${PROJECT_NAME} openrct2-cli) + set(OUTPUT_NAME "OpenRCT2") + set(MACOS_APP_NAME "${OUTPUT_NAME}.app") + set(BUNDLE_FRAMEWORK_DIR "${MACOS_APP_NAME}/Contents/Frameworks") + set(BUNDLE_RESOURCE_DIR "${MACOS_APP_NAME}/Contents/Resources") + set(SOURCE_DATA_DIR "${ROOT_DIR}/data") + + # Add distribution sources + target_sources(${PROJECT_NAME} + PUBLIC distribution/readme.txt + PUBLIC distribution/changelog.txt + PUBLIC g2.dat + PUBLIC resources/mac/openrct2.icns + PUBLIC ${SOURCE_DATA_DIR}/language + PUBLIC ${SOURCE_DATA_DIR}/object + PUBLIC ${SOURCE_DATA_DIR}/sequence + ) + + # Specify the resources to move to the bundle + set(BUNDLE_RESOURCES + distribution/readme.txt + distribution/changelog.txt + g2.dat + resources/mac/openrct2.icns + ${SOURCE_DATA_DIR}/language + ${SOURCE_DATA_DIR}/object + ${SOURCE_DATA_DIR}/sequence + ) + + + if(${OPENRCT2_BRANCH} EQUAL master) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${OPENRCT2_VERSION_TAG}") + else() + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${OPENRCT2_VERSION_TAG} ${OPENRCT2_BRANCH}") + endif() + + set(PRODUCT_BUNDLE_IDENTIFIER "io.openrct2.OpenRCT2") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${OPENRCT2_COMMIT_SHA1_SHORT}") + set(EXECUTABLE_NAME "${OUTPUT_NAME}") + set(MACOSX_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(PRODUCT_NAME "${OUTPUT_NAME}") + + # copy data + file(COPY ${SOURCE_DATA_DIR}/language DESTINATION "${BUNDLE_RESOURCE_DIR}") + file(COPY ${SOURCE_DATA_DIR}/object DESTINATION "${BUNDLE_RESOURCE_DIR}") + file(COPY ${SOURCE_DATA_DIR}/sequence DESTINATION "${BUNDLE_RESOURCE_DIR}") + + # Create as a bundle + set_target_properties(${PROJECT_NAME} PROPERTIES + MACOSX_BUNDLE ON + OUTPUT_NAME ${OUTPUT_NAME} + MACOSX_BUNDLE_BUNDLE_NAME ${OUTPUT_NAME} + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/distribution/macos/Info.plist + RESOURCE "${BUNDLE_RESOURCES}") + + install(CODE " + include(BundleUtilities) + fixup_bundle(${CMAKE_BINARY_DIR}/${MACOS_APP_NAME} \"\" \"\") + verify_app(${CMAKE_BINARY_DIR}/${MACOS_APP_NAME}) + " BUNDLE DESTINATION ${CMAKE_BINARY_DIR} + ) + +endif () From 911ec9f97b23d078be4505169ab75efbee0229d4 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 21:45:58 -0700 Subject: [PATCH 02/45] new CI run for macOS portable app bundle --- .github/workflows/ci.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 854488efb8..4fb7b58e81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,7 +173,36 @@ jobs: uses: actions/upload-artifact@v2-preview with: name: "OpenRCT2-macOS-cmake" - path: artifacts + path: artifacts/OpenRCT2-MacOS-x64-cmake.tar.gz + macos-cmake-portable: + name: macOS (x64, portable) using CMake + runs-on: macos-latest + needs: [check-code-formatting] + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: ccache + uses: hendrikmuhs/ccache-action@v1 + with: + key: macos + - name: Build OpenRCT2 + run: | + brew install ninja + . scripts/setenv -q && build -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=on -DMACOS_BUNDLE=on + - name: Build artifacts + shell: bash + run: | + . scripts/setenv + mkdir -p artifacts + mv bin/OpenRCT2.app artifacts + echo -e "\033[0;36mCompressing OpenRCT2.app...\033[0m" + cd artifacts + zip -rq openrct2-macos-cmake-app.zip OpenRCT2.app + - name: Upload artifacts (CI) + uses: actions/upload-artifact@v2-preview + with: + name: "OpenRCT2-macOS-cmake-app" + path: artifacts/openrct2-macos-cmake-app.zip linux-portable: name: Linux (x64, portable) From 77ea64a5ef0f8a4fbf341b9e5d2a8739e5e2d354 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 22:43:32 -0700 Subject: [PATCH 03/45] function for downloading object/sequence/dependency zips --- CMakeLists.txt | 38 ++++++++++------------------ cmake/download.cmake | 37 ++++++++++++++++++++++++++++ src/openrct2-ui/CMakeLists.txt | 45 +++++++++++++++++++++------------- 3 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 cmake/download.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a7788ddca..d532e73433 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,10 +42,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") -set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2c/title-sequences.zip") +set(TITLE_SEQUENCE_VERSION "0.1.2c") +set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v${TITLE_SEQUENCE_VERSION}/title-sequences.zip") set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d") -set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip") +set(OBJECTS_VERSION "1.0.21") +set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.37/replays.zip") @@ -105,34 +107,20 @@ endif () if (APPLE AND MACOS_USE_DEPENDENCIES) # if we're building on macOS, then we need the dependencies # update dylibs + include(cmake/download.cmake) + set(MACOS_DYLIBS_VERSION "28") set(MACOS_DYLIBS_ZIPFILE "openrct2-libs-v${MACOS_DYLIBS_VERSION}-x64-macos-dylibs.zip") + set(MACOS_DYLIBS_SHA1 "29e5480376cf4ac5943f114387e32685204c8b78") set(MACOS_DYLIBS_DIR "${ROOT_DIR}/lib/macos") set(MACOS_DYLIBS_URL "https://github.com/OpenRCT2/Dependencies/releases/download/v${MACOS_DYLIBS_VERSION}/${MACOS_DYLIBS_ZIPFILE}") - if (NOT EXISTS ${MACOS_DYLIBS_DIR}) - set(DOWNLOAD_DYLIBS 1) - else () - file(READ "${MACOS_DYLIBS_DIR}/libversion" MACOS_DYLIBS_CACHED_VERSION) - if (NOT ${MACOS_DYLIBS_CACHED_VERSION} STREQUAL ${MACOS_DYLIBS_VERSION}) - message("Cached macOS dylibs out of date") - set(DOWNLOAD_DYLIBS 1) - endif () - endif () - if (DOWNLOAD_DYLIBS) - message("Downloading macOS dylibs") - file(DOWNLOAD "${MACOS_DYLIBS_URL}" "${MACOS_DYLIBS_DIR}/${MACOS_DYLIBS_ZIPFILE}") - file(ARCHIVE_EXTRACT - INPUT "${MACOS_DYLIBS_DIR}/${MACOS_DYLIBS_ZIPFILE}" - DESTINATION "${MACOS_DYLIBS_DIR}" - ) - file(WRITE - "${MACOS_DYLIBS_DIR}/libversion" - "${MACOS_DYLIBS_VERSION}" - ) - file(REMOVE "${MACOS_DYLIBS_DIR}/${MACOS_DYLIBS_ZIPFILE}") - endif () - # TODO: make the above routine a function, use it for objects, title sequences, and languages + download_openrct2_zip( + ZIP_VERSION ${MACOS_DYLIBS_VERSION} + DOWNLOAD_DIR ${MACOS_DYLIBS_DIR} + ZIP_URL ${MACOS_DYLIBS_URL} + SHA1 ${MACOS_DYLIBS_SHA1} + ) set(CMAKE_MACOSX_RPATH 1) list(APPEND CMAKE_PREFIX_PATH "${MACOS_DYLIBS_DIR}") diff --git a/cmake/download.cmake b/cmake/download.cmake new file mode 100644 index 0000000000..f4936d200a --- /dev/null +++ b/cmake/download.cmake @@ -0,0 +1,37 @@ +function(download_openrct2_zip) + set(oneValueArgs ZIP_VERSION DOWNLOAD_DIR ZIP_URL SHA1) + cmake_parse_arguments(DOWNLOAD_OPENRCT2 "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + get_filename_component(ZIP_FILE_NAME ${DOWNLOAD_OPENRCT2_ZIP_URL} NAME) + + if (NOT EXISTS ${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}) + set(DOWNLOAD_ZIP 1) + else () + if (EXISTS "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/zipversion") + file(READ "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/zipversion" DOWNLOAD_OPENRCT2_CACHED_VERSION) + if (NOT ${DOWNLOAD_OPENRCT2_CACHED_VERSION} STREQUAL ${DOWNLOAD_OPENRCT2_ZIP_VERSION}) + message("Cache ${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR} not up to date") + set(DOWNLOAD_ZIP 1) + endif () + else () + set(DOWNLOAD_ZIP 1) + endif () + endif () + if (DOWNLOAD_ZIP) + message("Downloading ${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}") + file(DOWNLOAD + "${DOWNLOAD_OPENRCT2_ZIP_URL}" "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}" + EXPECTED_HASH SHA1=${DOWNLOAD_OPENRCT2_SHA1} SHOW_PROGRESS) + file(ARCHIVE_EXTRACT + INPUT "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}" + DESTINATION "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}" + ) + file(WRITE + "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/zipversion" + "${DOWNLOAD_OPENRCT2_ZIP_VERSION}" + ) + file(REMOVE "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}") + endif () + +endfunction () diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index 054a9f91de..cc53186ba3 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -139,24 +139,18 @@ if(MACOS_BUNDLE) # Add distribution sources target_sources(${PROJECT_NAME} - PUBLIC distribution/readme.txt - PUBLIC distribution/changelog.txt - PUBLIC g2.dat - PUBLIC resources/mac/openrct2.icns - PUBLIC ${SOURCE_DATA_DIR}/language - PUBLIC ${SOURCE_DATA_DIR}/object - PUBLIC ${SOURCE_DATA_DIR}/sequence + PUBLIC ${ROOT_DIR}/distribution/readme.txt + PUBLIC ${ROOT_DIR}/distribution/changelog.txt + PUBLIC ${CMAKE_BINARY_DIR}/g2.dat + PUBLIC ${ROOT_DIR}/resources/mac/openrct2.icns ) # Specify the resources to move to the bundle set(BUNDLE_RESOURCES - distribution/readme.txt - distribution/changelog.txt - g2.dat - resources/mac/openrct2.icns - ${SOURCE_DATA_DIR}/language - ${SOURCE_DATA_DIR}/object - ${SOURCE_DATA_DIR}/sequence + ${ROOT_DIR}/distribution/readme.txt + ${ROOT_DIR}/distribution/changelog.txt + ${CMAKE_BINARY_DIR}/g2.dat + ${ROOT_DIR}/resources/mac/openrct2.icns ) @@ -174,8 +168,26 @@ if(MACOS_BUNDLE) # copy data file(COPY ${SOURCE_DATA_DIR}/language DESTINATION "${BUNDLE_RESOURCE_DIR}") - file(COPY ${SOURCE_DATA_DIR}/object DESTINATION "${BUNDLE_RESOURCE_DIR}") - file(COPY ${SOURCE_DATA_DIR}/sequence DESTINATION "${BUNDLE_RESOURCE_DIR}") + + # download objects and sequences + set(OBJECTS_DIR ${CMAKE_BINARY_DIR}/object) + set(TITLE_SEQUENCE_DIR ${CMAKE_BINARY_DIR}/sequence) + download_openrct2_zip( + ZIP_VERSION ${OBJECTS_VERSION} + DOWNLOAD_DIR ${OBJECTS_DIR} + ZIP_URL ${OBJECTS_URL} + SHA1 ${OBJECTS_SHA1} + ) + + download_openrct2_zip( + ZIP_VERSION ${TITLE_SEQUENCE_VERSION} + DOWNLOAD_DIR ${TITLE_SEQUENCE_DIR} + ZIP_URL ${TITLE_SEQUENCE_URL} + SHA1 ${TITLE_SEQUENCE_SHA1} + ) + + file(COPY ${OBJECTS_DIR} DESTINATION "${BUNDLE_RESOURCE_DIR}") + file(COPY ${TITLE_SEQUENCE_DIR} DESTINATION "${BUNDLE_RESOURCE_DIR}") # Create as a bundle set_target_properties(${PROJECT_NAME} PROPERTIES @@ -191,5 +203,4 @@ if(MACOS_BUNDLE) verify_app(${CMAKE_BINARY_DIR}/${MACOS_APP_NAME}) " BUNDLE DESTINATION ${CMAKE_BINARY_DIR} ) - endif () From dc0d77a95135ee4f9f4d0715f511884523e26fb7 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 23:24:45 -0700 Subject: [PATCH 04/45] include shaders (required for OpenGL) --- src/openrct2-ui/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index cc53186ba3..385aa29cc3 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -168,6 +168,7 @@ if(MACOS_BUNDLE) # copy data file(COPY ${SOURCE_DATA_DIR}/language DESTINATION "${BUNDLE_RESOURCE_DIR}") + file(COPY ${SOURCE_DATA_DIR}/shaders DESTINATION "${BUNDLE_RESOURCE_DIR}") # download objects and sequences set(OBJECTS_DIR ${CMAKE_BINARY_DIR}/object) From 9231c5f6114689d9d6a84ffe51015f8eda8cb50b Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 23:25:31 -0700 Subject: [PATCH 05/45] store symlinks in zip archive (for embedded libraries) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fb7b58e81..f7d296c9f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,7 +197,7 @@ jobs: mv bin/OpenRCT2.app artifacts echo -e "\033[0;36mCompressing OpenRCT2.app...\033[0m" cd artifacts - zip -rq openrct2-macos-cmake-app.zip OpenRCT2.app + zip -rqy openrct2-macos-cmake-app.zip OpenRCT2.app - name: Upload artifacts (CI) uses: actions/upload-artifact@v2-preview with: From 2b37f4586a6ab01f382c48544f5b118d2ada015e Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sat, 13 Mar 2021 23:33:10 -0700 Subject: [PATCH 06/45] separate ccache key for macOS CI runs --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7d296c9f4..b1a228567f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -184,7 +184,7 @@ jobs: - name: ccache uses: hendrikmuhs/ccache-action@v1 with: - key: macos + key: macos-app - name: Build OpenRCT2 run: | brew install ninja From 753ac907f87c312f8b8c403585fe552c17b993a0 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sun, 21 Mar 2021 16:38:31 -0600 Subject: [PATCH 07/45] Refactor macOS CMakeLists for .app bundle as default --- CMakeLists.txt | 190 ++++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d532e73433..8b6dc63c44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,9 @@ option(DOWNLOAD_TITLE_SEQUENCES "Download title sequences during installation." option(DOWNLOAD_OBJECTS "Download objects during installation." ON) CMAKE_DEPENDENT_OPTION(DOWNLOAD_REPLAYS "Download replays during installation." ON "WITH_TESTS" OFF) -option(MACOS_USE_DEPENDENCIES "Use OpenRCT2 dependencies instead of system libraries" ON) -CMAKE_DEPENDENT_OPTION(MACOS_BUNDLE "Build macOS application bundle (OpenRCT2.app)" OFF +CMAKE_DEPENDENT_OPTION(MACOS_USE_DEPENDENCIES "Use OpenRCT2 dependencies instead of system libraries" ON + "APPLE" OFF) +CMAKE_DEPENDENT_OPTION(MACOS_BUNDLE "Build macOS application bundle (OpenRCT2.app)" ON "MACOS_USE_DEPENDENCIES; NOT DISABLE_GUI" OFF) # Options @@ -104,9 +105,8 @@ if (APPIMAGE) set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") endif () -if (APPLE AND MACOS_USE_DEPENDENCIES) +if (MACOS_USE_DEPENDENCIES) # if we're building on macOS, then we need the dependencies - # update dylibs include(cmake/download.cmake) set(MACOS_DYLIBS_VERSION "28") @@ -125,17 +125,21 @@ if (APPLE AND MACOS_USE_DEPENDENCIES) set(CMAKE_MACOSX_RPATH 1) list(APPEND CMAKE_PREFIX_PATH "${MACOS_DYLIBS_DIR}") - # the RPATH to be used when installing, but only if it's not a system directory - list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) - if("${isSystemDir}" STREQUAL "-1") - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") - endif("${isSystemDir}" STREQUAL "-1") + # if we're making the OpenRCT2.app bundle, rpath will be handled by fixup_bundle + # if we're building the CLI executable, we need to do it ourselves + if (NOT MACOS_BUNDLE) + # the RPATH to be used when installing, but only if it's not a system directory + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + endif("${isSystemDir}" STREQUAL "-1") - # if the DESTDIR env var is defined, use it in the install RPATH - if(DEFINED ENV{DESTDIR}) - get_filename_component(destdirRealPath "$ENV{DESTDIR}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") - set(CMAKE_INSTALL_RPATH "${destdirRealPath}${CMAKE_INSTALL_PREFIX}/lib") - endif() + # if the DESTDIR env var is defined, use it in the install RPATH + if(DEFINED ENV{DESTDIR}) + get_filename_component(destdirRealPath "$ENV{DESTDIR}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") + set(CMAKE_INSTALL_RPATH "${destdirRealPath}${CMAKE_INSTALL_PREFIX}/lib") + endif() + endif () endif () # LIST of supported flags, use SET_CHECK_CXX_FLAGS() to apply to target. @@ -203,7 +207,7 @@ if (NOT DISABLE_DISCORD_RPC) add_definitions(-D__ENABLE_DISCORD__) include_directories(DISCORDRPC_PROCESS_INCLUDES) endif() - elseif (APPLE AND MACOS_USE_DEPENDENCIES) + elseif (MACOS_USE_DEPENDENCIES) find_package(discordrpc CONFIG REQUIRED) if(${DISCORDRPC_FOUND}) add_definitions(-D__ENABLE_DISCORD__) @@ -380,80 +384,88 @@ if (WITH_TESTS) include("${ROOT_DIR}/test/tests/CMakeLists.txt" NO_POLICY_SCOPE) endif () -# Install -# Don't recurse, grab all *.txt and *.md files -file(GLOB DOC_FILES "${ROOT_DIR}/distribution/*.txt") -list(APPEND DOC_FILES "${ROOT_DIR}/contributors.md" - "${ROOT_DIR}/licence.txt" - "${ROOT_DIR}/distribution/scripting.md" - "${ROOT_DIR}/distribution/openrct2.d.ts") +# macOS bundle "install" is handled in src/openrct2-ui/CMakeLists.txt +# This is because the openrct2 target is modified (and that is where that target is defined) +if (NOT MACOS_BUNDLE OR (MACOS_BUNDLE AND WITH_TESTS)) + # Install + # Don't recurse, grab all *.txt and *.md files + file(GLOB DOC_FILES "${ROOT_DIR}/distribution/*.txt") + list(APPEND DOC_FILES "${ROOT_DIR}/contributors.md" + "${ROOT_DIR}/licence.txt" + "${ROOT_DIR}/distribution/scripting.md" + "${ROOT_DIR}/distribution/openrct2.d.ts") -# CMake does not allow specifying a dependency chain which includes built-in -# targets, like `install`, so we have to trick it and execute dependency ourselves. -install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}\" --target g2)") -if (DOWNLOAD_TITLE_SEQUENCES) - # If openrct2.parkseq or data/sequence/ exists, assume all the title sequences are already present - install(CODE - "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/openrct2.parkseq\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/sequence/)\n\ - message(\"Using cached title sequences\")\n\ - else () \n\ - file(DOWNLOAD ${TITLE_SEQUENCE_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip EXPECTED_HASH SHA1=${TITLE_SEQUENCE_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/ \"${CMAKE_COMMAND}\" -E tar xf title-sequences.zip)\n\ - file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip)\n\ - endif ()") -endif () -if (DOWNLOAD_OBJECTS) - # If rct2.wtrcyan.json or data/object/ exists, assume all the objects are already present - install(CODE - "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/rct2/water/rct2.wtrcyan.json\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/object/)\n\ - message(\"Using cached objects\")\n\ - else () \n\ - file(DOWNLOAD ${OBJECTS_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip EXPECTED_HASH SHA1=${OBJECTS_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/ \"${CMAKE_COMMAND}\" -E tar xf objects.zip)\n\ - file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip)\n\ - endif ()") -endif () -if (DOWNLOAD_REPLAYS) - install(CODE - "if (EXISTS \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/)\n\ - message(\"Using cached replays\")\n\ - else () \n\ - file(DOWNLOAD ${REPLAYS_URL} \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip EXPECTED_HASH SHA1=${REPLAYS_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/ \"${CMAKE_COMMAND}\" -E tar xf replays.zip)\n\ - file(REMOVE \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip)\n\ - endif ()") -endif () -install(TARGETS "libopenrct2" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") -if(NOT DISABLE_GUI AND NOT MACOS_BUNDLE) - install(TARGETS "openrct2" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") -endif() -install(TARGETS "openrct2-cli" OPTIONAL RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/g2.dat" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") -install(DIRECTORY "data/" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") -install(FILES ${DOC_FILES} DESTINATION "${CMAKE_INSTALL_DOCDIR}") -install(FILES "distribution/linux/openrct2.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") -if (NOT DISABLE_GUI) - install(FILES "resources/logo/icon_x16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x24.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/24x24/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x96.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/96x96/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_flag.svg" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps" RENAME "openrct2.svg") - install(FILES "distribution/linux/openrct2.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/openrct2-savegame.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/openrct2-scenario.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/openrct2-uri.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") -endif() -install(FILES "distribution/linux/openrct2-mimeinfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages/" RENAME "openrct2.xml") -install(DIRECTORY "distribution/man/" DESTINATION "${CMAKE_INSTALL_MANDIR}/man6" FILES_MATCHING PATTERN "*.6") + # CMake does not allow specifying a dependency chain which includes built-in + # targets, like `install`, so we have to trick it and execute dependency ourselves. + install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}\" --target g2)") + if (DOWNLOAD_TITLE_SEQUENCES) + # If openrct2.parkseq or data/sequence/ exists, assume all the title sequences are already present + install(CODE + "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/openrct2.parkseq\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/sequence/)\n\ + message(\"Using cached title sequences\")\n\ + else () \n\ + file(DOWNLOAD ${TITLE_SEQUENCE_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip EXPECTED_HASH SHA1=${TITLE_SEQUENCE_SHA1} SHOW_PROGRESS)\n\ + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/ \"${CMAKE_COMMAND}\" -E tar xf title-sequences.zip)\n\ + file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip)\n\ + endif ()") + endif () + if (DOWNLOAD_OBJECTS) + # If rct2.wtrcyan.json or data/object/ exists, assume all the objects are already present + install(CODE + "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/rct2/water/rct2.wtrcyan.json\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/object/)\n\ + message(\"Using cached objects\")\n\ + else () \n\ + file(DOWNLOAD ${OBJECTS_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip EXPECTED_HASH SHA1=${OBJECTS_SHA1} SHOW_PROGRESS)\n\ + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/ \"${CMAKE_COMMAND}\" -E tar xf objects.zip)\n\ + file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip)\n\ + endif ()") + endif () + if (DOWNLOAD_REPLAYS) + install(CODE + "if (EXISTS \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/)\n\ + message(\"Using cached replays\")\n\ + else () \n\ + file(DOWNLOAD ${REPLAYS_URL} \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip EXPECTED_HASH SHA1=${REPLAYS_SHA1} SHOW_PROGRESS)\n\ + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/ \"${CMAKE_COMMAND}\" -E tar xf replays.zip)\n\ + file(REMOVE \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip)\n\ + endif ()") + endif () + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/g2.dat" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") + install(DIRECTORY "data/" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") -if (APPLE AND MACOS_USE_DEPENDENCIES) - # Note: dependencies may have the same names as system installed libraries - # (via homebrew). A local CMAKE_INSTALL_PREFIX is recommended to avoid issues - file(GLOB DYLIB_FILES "${MACOS_DYLIBS_DIR}/lib/*.dylib") - install(FILES ${DYLIB_FILES} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + # even when building WITH_TESTS, none of the below install steps are required for OpenRCT2.app + if (NOT MACOS_BUNDLE) + install(TARGETS "libopenrct2" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") + if(NOT DISABLE_GUI) + install(TARGETS "openrct2" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + endif() + install(TARGETS "openrct2-cli" OPTIONAL RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + install(FILES ${DOC_FILES} DESTINATION "${CMAKE_INSTALL_DOCDIR}") + install(FILES "distribution/linux/openrct2.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") + if (NOT DISABLE_GUI) + install(FILES "resources/logo/icon_x16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x24.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/24x24/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x96.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/96x96/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_flag.svg" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps" RENAME "openrct2.svg") + install(FILES "distribution/linux/openrct2.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/openrct2-savegame.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/openrct2-scenario.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/openrct2-uri.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + endif() + install(FILES "distribution/linux/openrct2-mimeinfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages/" RENAME "openrct2.xml") + install(DIRECTORY "distribution/man/" DESTINATION "${CMAKE_INSTALL_MANDIR}/man6" FILES_MATCHING PATTERN "*.6") + + if (MACOS_USE_DEPENDENCIES) + # Note: dependencies may have the same names as system installed libraries + # (via homebrew). A local CMAKE_INSTALL_PREFIX is recommended to avoid issues + file(GLOB DYLIB_FILES "${MACOS_DYLIBS_DIR}/lib/*.dylib") + install(FILES ${DYLIB_FILES} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() endif() From c9d1a2ed8932a42fe37cb3b385bc04e02f6bce53 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sun, 21 Mar 2021 16:42:19 -0600 Subject: [PATCH 08/45] combine both macOS cmake CI jobs --- .github/workflows/ci.yml | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1a228567f..6bea51fde6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - name: Upload artifacts (CI) uses: actions/upload-artifact@v2-preview with: - name: "OpenRCT2-macOS" + name: "OpenRCT2-macOS-xcode" path: artifacts/openrct2-macos.zip - name: Upload artifacts (openrct2.org) run: | @@ -168,42 +168,18 @@ jobs: run: . scripts/setenv -q && run-tests - name: Build artifacts shell: bash - run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-MacOS-x64-cmake.tar.gz bin/install/usr - - name: Upload artifacts (CI) - uses: actions/upload-artifact@v2-preview - with: - name: "OpenRCT2-macOS-cmake" - path: artifacts/OpenRCT2-MacOS-x64-cmake.tar.gz - macos-cmake-portable: - name: macOS (x64, portable) using CMake - runs-on: macos-latest - needs: [check-code-formatting] - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: ccache - uses: hendrikmuhs/ccache-action@v1 - with: - key: macos-app - - name: Build OpenRCT2 run: | - brew install ninja - . scripts/setenv -q && build -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=on -DMACOS_BUNDLE=on - - name: Build artifacts - shell: bash - run: | . scripts/setenv mkdir -p artifacts mv bin/OpenRCT2.app artifacts echo -e "\033[0;36mCompressing OpenRCT2.app...\033[0m" cd artifacts - zip -rqy openrct2-macos-cmake-app.zip OpenRCT2.app + zip -rqy openrct2-macos.zip OpenRCT2.app - name: Upload artifacts (CI) uses: actions/upload-artifact@v2-preview with: - name: "OpenRCT2-macOS-cmake-app" - path: artifacts/openrct2-macos-cmake-app.zip - + name: "OpenRCT2-macOS-cmake" + path: artifacts/openrct2-macos.zip linux-portable: name: Linux (x64, portable) runs-on: ubuntu-latest From d2ce68aed991e4fd079500294bd29107ba8fcbc1 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Sun, 21 Mar 2021 16:54:33 -0600 Subject: [PATCH 09/45] use openrct2-cli during macOS CI runs for run-tests --- scripts/run-tests | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/run-tests b/scripts/run-tests index a5cc969a77..1ec0677ed2 100755 --- a/scripts/run-tests +++ b/scripts/run-tests @@ -11,7 +11,11 @@ cd $basedir/bin # Scan objects first so that does not happen within a test echo -e "\033[0;36mBuilding OpenRCT2 repository indexes...\033[0m" -./openrct2 scan-objects +if [[ $(uname) == "Darwin" ]]; then + ./openrct2-cli scan-objects +else + ./openrct2 scan-objects +fi if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]]; then # Now run all the tests From d5e368a8d17bb78a790ffff1aca2855c26a15124 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Mon, 22 Mar 2021 20:49:02 -0600 Subject: [PATCH 10/45] consistently use download_openrct2_zip --- CMakeLists.txt | 56 ++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b6dc63c44..c5c4a7d6cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,8 @@ set(OBJECTS_VERSION "1.0.21") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5") -set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.37/replays.zip") +set(REPLAYS_VERSION "0.0.37") +set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") set(REPLAYS_SHA1 "C31C299539EB86DA013AEE47C9B2B2F4609F52C4") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") @@ -399,36 +400,37 @@ if (NOT MACOS_BUNDLE OR (MACOS_BUNDLE AND WITH_TESTS)) # targets, like `install`, so we have to trick it and execute dependency ourselves. install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}\" --target g2)") if (DOWNLOAD_TITLE_SEQUENCES) - # If openrct2.parkseq or data/sequence/ exists, assume all the title sequences are already present - install(CODE - "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/openrct2.parkseq\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/sequence/)\n\ - message(\"Using cached title sequences\")\n\ - else () \n\ - file(DOWNLOAD ${TITLE_SEQUENCE_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip EXPECTED_HASH SHA1=${TITLE_SEQUENCE_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/ \"${CMAKE_COMMAND}\" -E tar xf title-sequences.zip)\n\ - file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/title-sequences.zip)\n\ - endif ()") + # Checks if this version of the title sequences are already installed, updates if necessary + install(CODE " + include(${ROOT_DIR}/cmake/download.cmake) + download_openrct2_zip( + ZIP_VERSION ${TITLE_SEQUENCE_VERSION} + DOWNLOAD_DIR \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/sequence/ + ZIP_URL ${TITLE_SEQUENCE_URL} + SHA1 ${TITLE_SEQUENCE_SHA1} + )") endif () if (DOWNLOAD_OBJECTS) - # If rct2.wtrcyan.json or data/object/ exists, assume all the objects are already present - install(CODE - "if (EXISTS \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/rct2/water/rct2.wtrcyan.json\" OR EXISTS ${CMAKE_SOURCE_DIR}/data/object/)\n\ - message(\"Using cached objects\")\n\ - else () \n\ - file(DOWNLOAD ${OBJECTS_URL} \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip EXPECTED_HASH SHA1=${OBJECTS_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/ \"${CMAKE_COMMAND}\" -E tar xf objects.zip)\n\ - file(REMOVE \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/objects.zip)\n\ - endif ()") + # Checks if this version of the objects are already installed, updates if necessary + install(CODE " + include(${ROOT_DIR}/cmake/download.cmake) + download_openrct2_zip( + ZIP_VERSION ${OBJECTS_VERSION} + DOWNLOAD_DIR \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/object/ + ZIP_URL ${OBJECTS_URL} + SHA1 ${OBJECTS_SHA1} + )") endif () if (DOWNLOAD_REPLAYS) - install(CODE - "if (EXISTS \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/)\n\ - message(\"Using cached replays\")\n\ - else () \n\ - file(DOWNLOAD ${REPLAYS_URL} \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip EXPECTED_HASH SHA1=${REPLAYS_SHA1} SHOW_PROGRESS)\n\ - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/ \"${CMAKE_COMMAND}\" -E tar xf replays.zip)\n\ - file(REMOVE \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/replays.zip)\n\ - endif ()") + # Checks if this version of the replays are already installed, updates if necessary + install(CODE " + include(${ROOT_DIR}/cmake/download.cmake) + download_openrct2_zip( + ZIP_VERSION ${REPLAYS_VERSION} + DOWNLOAD_DIR \${CMAKE_CURRENT_BINARY_DIR}/testdata/replays/ + ZIP_URL ${REPLAYS_URL} + SHA1 ${REPLAYS_SHA1} + )") endif () install(FILES "${CMAKE_CURRENT_BINARY_DIR}/g2.dat" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") install(DIRECTORY "data/" DESTINATION "${CMAKE_INSTALL_DATADIR}/openrct2") From 927b213782242a8c70c8611125424167c70bc75b Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Mon, 22 Mar 2021 20:58:46 -0600 Subject: [PATCH 11/45] Add backward compatibility for older cmake versions file(ARCHIVE_EXTRACT) added in cmake 3.18 --- cmake/download.cmake | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmake/download.cmake b/cmake/download.cmake index f4936d200a..33ec3635bf 100644 --- a/cmake/download.cmake +++ b/cmake/download.cmake @@ -23,10 +23,14 @@ function(download_openrct2_zip) file(DOWNLOAD "${DOWNLOAD_OPENRCT2_ZIP_URL}" "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}" EXPECTED_HASH SHA1=${DOWNLOAD_OPENRCT2_SHA1} SHOW_PROGRESS) - file(ARCHIVE_EXTRACT - INPUT "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}" - DESTINATION "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}" - ) + if(${CMAKE_VERSION} VERSION_LESS "3.18.0") + execute_process(COMMAND ${CMAKE_COMMAND} -E chdir ${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR} ${CMAKE_COMMAND} -E tar xf ${ZIP_FILE_NAME}) + else() + file(ARCHIVE_EXTRACT + INPUT "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/${ZIP_FILE_NAME}" + DESTINATION "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}" + ) + endif() file(WRITE "${DOWNLOAD_OPENRCT2_DOWNLOAD_DIR}/zipversion" "${DOWNLOAD_OPENRCT2_ZIP_VERSION}" From e45d002562fd0a08320cf5114a4c94319d9f0bb9 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Thu, 1 Apr 2021 22:37:09 -0600 Subject: [PATCH 12/45] Remove unnecessary verify_app function fixup_bundle performs bundle verification, so this was a duplicate --- src/openrct2-ui/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index 385aa29cc3..ce14758338 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -201,7 +201,6 @@ if(MACOS_BUNDLE) install(CODE " include(BundleUtilities) fixup_bundle(${CMAKE_BINARY_DIR}/${MACOS_APP_NAME} \"\" \"\") - verify_app(${CMAKE_BINARY_DIR}/${MACOS_APP_NAME}) " BUNDLE DESTINATION ${CMAKE_BINARY_DIR} ) endif () From 943e89d5a6a8d18947e7d7a5bfc23a450d1a114a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 3 Apr 2021 22:07:11 +0200 Subject: [PATCH 13/45] Use BannerElement instead of TileElement --- src/openrct2-ui/windows/Banner.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index f0442ce136..a97a3ae8d5 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -76,7 +76,7 @@ class BannerWindow final : public Window private: Banner* _banner; CoordsXYZ _bannerViewPos; - TileElement* _tileElement = nullptr; + BannerElement* _tileElement = nullptr; void CreateViewport() { @@ -99,7 +99,7 @@ private: { if ((tileElement->GetType() == TILE_ELEMENT_TYPE_BANNER) && (tileElement->AsBanner()->GetIndex() == number)) { - _tileElement = tileElement; + _tileElement = tileElement->AsBanner(); return; } if (tileElement->IsLastForTile()) @@ -173,7 +173,7 @@ public: case WIDX_BANNER_DEMOLISH: { auto bannerRemoveAction = BannerRemoveAction( - { _banner->position.ToCoordsXY(), _tileElement->GetBaseZ(), _tileElement->AsBanner()->GetPosition() }); + { _banner->position.ToCoordsXY(), _tileElement->GetBaseZ(), _tileElement->GetPosition() }); GameActions::Execute(&bannerRemoveAction); break; } From f5ec127eaf56d64d8f05908f50f9723296b791ab Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 3 Apr 2021 22:09:24 +0200 Subject: [PATCH 14/45] Fix #14409: NPE when demolishing banner --- src/openrct2-ui/windows/Banner.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index a97a3ae8d5..4c0bc8ad23 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -172,6 +172,9 @@ public: break; case WIDX_BANNER_DEMOLISH: { + if (_banner == nullptr || _tileElement == nullptr) + break; + auto bannerRemoveAction = BannerRemoveAction( { _banner->position.ToCoordsXY(), _tileElement->GetBaseZ(), _tileElement->GetPosition() }); GameActions::Execute(&bannerRemoveAction); From 7c73e271adc8c21ced29e35aab722e8a9aedfddc Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 3 Apr 2021 22:17:57 +0200 Subject: [PATCH 15/45] Name num_sheltered_sections flags --- src/openrct2/ride/Ride.cpp | 14 ++++++++++++++ src/openrct2/ride/Ride.h | 10 ++++++++++ src/openrct2/ride/RideRatings.cpp | 6 +++--- src/openrct2/ride/Vehicle.cpp | 10 +++------- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 53b8987753..bdd9c158a1 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7347,3 +7347,17 @@ void Ride::SetMaxCarsPerTrain(uint8_t newValue) min_max_cars_per_train &= ~0x0F; min_max_cars_per_train |= newValue & 0x0F; } + +uint8_t Ride::GetNumShelteredSections() const +{ + return num_sheltered_sections & ShelteredSectionsBits::NumShelteredSectionsMask; +} + +void Ride::IncreaseNumShelteredSections() +{ + auto newNumShelteredSections = GetNumShelteredSections(); + if (newNumShelteredSections != 0x1F) + newNumShelteredSections++; + num_sheltered_sections &= ~ShelteredSectionsBits::NumShelteredSectionsMask; + num_sheltered_sections |= newNumShelteredSections; +} diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 3029c1144b..13c32587cc 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -190,6 +190,13 @@ enum class RideClassification KioskOrFacility }; +namespace ShelteredSectionsBits +{ + constexpr const uint8_t NumShelteredSectionsMask = 0b00011111; + constexpr const uint8_t RotatingWhileSheltered = 0b00100000; + constexpr const uint8_t BankingWhileSheltered = 0b01000000; +}; // namespace ShelteredSectionsBits + struct TrackDesign; enum class RideMode : uint8_t; @@ -453,6 +460,9 @@ public: uint8_t GetMaxCarsPerTrain() const; void SetMinCarsPerTrain(uint8_t newValue); void SetMaxCarsPerTrain(uint8_t newValue); + + uint8_t GetNumShelteredSections() const; + void IncreaseNumShelteredSections(); }; #pragma pack(push, 1) diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index f39a63a073..bdd1a4c124 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1326,19 +1326,19 @@ static RatingTuple ride_ratings_get_sheltered_ratings(Ride* ride) /*eax = (ride->var_11C * 30340) >> 16;*/ /*nausea += eax;*/ - if (ride->num_sheltered_sections & 0x40) + if (ride->num_sheltered_sections & ShelteredSectionsBits::BankingWhileSheltered) { excitement += 20; nausea += 15; } - if (ride->num_sheltered_sections & 0x20) + if (ride->num_sheltered_sections & ShelteredSectionsBits::RotatingWhileSheltered) { excitement += 20; nausea += 15; } - uint8_t lowerVal = ride->num_sheltered_sections & 0x1F; + uint8_t lowerVal = ride->GetNumShelteredSections(); lowerVal = std::min(lowerVal, 11); excitement += (lowerVal * 774516) >> 16; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index b6a13fbb56..a059201492 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -1909,20 +1909,16 @@ void Vehicle::UpdateMeasurements() { curRide->testing_flags |= RIDE_TESTING_SHELTERED; - uint8_t numShelteredSections = curRide->num_sheltered_sections & 0x1F; - if (numShelteredSections != 0x1F) - numShelteredSections++; - curRide->num_sheltered_sections &= ~0x1F; - curRide->num_sheltered_sections |= numShelteredSections; + curRide->IncreaseNumShelteredSections(); if (vehicle_sprite_type != 0) { - curRide->num_sheltered_sections |= (1 << 5); + curRide->num_sheltered_sections |= ShelteredSectionsBits::RotatingWhileSheltered; } if (bank_rotation != 0) { - curRide->num_sheltered_sections |= (1 << 6); + curRide->num_sheltered_sections |= ShelteredSectionsBits::BankingWhileSheltered; } } From 79302e88a53044d5c3de57c7ec11aa3f2f69aeaa Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 3 Apr 2021 22:43:57 +0200 Subject: [PATCH 16/45] Rename _tileElement to _bannerElement --- src/openrct2-ui/windows/Banner.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index 4c0bc8ad23..542f7cf879 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -76,7 +76,7 @@ class BannerWindow final : public Window private: Banner* _banner; CoordsXYZ _bannerViewPos; - BannerElement* _tileElement = nullptr; + BannerElement* _bannerElement = nullptr; void CreateViewport() { @@ -99,7 +99,7 @@ private: { if ((tileElement->GetType() == TILE_ELEMENT_TYPE_BANNER) && (tileElement->AsBanner()->GetIndex() == number)) { - _tileElement = tileElement->AsBanner(); + _bannerElement = tileElement->AsBanner(); return; } if (tileElement->IsLastForTile()) @@ -107,7 +107,7 @@ private: tileElement++; } } - _tileElement = nullptr; + _bannerElement = nullptr; } public: @@ -126,10 +126,10 @@ public: _banner = GetBanner(number); InitTileElement(); - if (_tileElement == nullptr) + if (_bannerElement == nullptr) return; - frame_no = _tileElement->GetBaseZ(); + frame_no = _bannerElement->GetBaseZ(); _bannerViewPos = CoordsXYZ{ _banner->position.ToCoordsXY().ToTileCentre(), frame_no }; CreateViewport(); } @@ -172,11 +172,11 @@ public: break; case WIDX_BANNER_DEMOLISH: { - if (_banner == nullptr || _tileElement == nullptr) + if (_banner == nullptr || _bannerElement == nullptr) break; auto bannerRemoveAction = BannerRemoveAction( - { _banner->position.ToCoordsXY(), _tileElement->GetBaseZ(), _tileElement->GetPosition() }); + { _banner->position.ToCoordsXY(), _bannerElement->GetBaseZ(), _bannerElement->GetPosition() }); GameActions::Execute(&bannerRemoveAction); break; } From 50c4f1c030a324721a22a5aaf2732a32e4ba05d6 Mon Sep 17 00:00:00 2001 From: adam-bloom Date: Mon, 5 Apr 2021 19:18:09 -0600 Subject: [PATCH 17/45] address feedback: use openrct2-cli for all CI runs --- scripts/run-tests | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/run-tests b/scripts/run-tests index 1ec0677ed2..4317a8c1fd 100755 --- a/scripts/run-tests +++ b/scripts/run-tests @@ -11,11 +11,7 @@ cd $basedir/bin # Scan objects first so that does not happen within a test echo -e "\033[0;36mBuilding OpenRCT2 repository indexes...\033[0m" -if [[ $(uname) == "Darwin" ]]; then - ./openrct2-cli scan-objects -else - ./openrct2 scan-objects -fi +./openrct2-cli scan-objects if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]]; then # Now run all the tests From a9e1f2e89cb995845ae7e48a08393a3b94e73993 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 11 Apr 2021 18:02:19 +0100 Subject: [PATCH 18/45] Remove SpriteBase::flags (#14460) * Remove SpriteBase::flags * Increment network version * update replays --- CMakeLists.txt | 4 ++-- openrct2.proj | 4 ++-- src/openrct2/GameStateSnapshots.cpp | 2 +- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct12/RCT12.h | 5 +++++ src/openrct2/rct2/S6Exporter.cpp | 3 ++- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/CableLift.cpp | 1 + src/openrct2/ride/Ride.cpp | 1 + src/openrct2/ride/Vehicle.cpp | 6 +++--- src/openrct2/ride/Vehicle.h | 1 + src/openrct2/ride/VehiclePaint.cpp | 2 +- src/openrct2/world/Sprite.cpp | 1 - src/openrct2/world/SpriteBase.h | 1 - test/tests/S6ImportExportTests.cpp | 2 +- 16 files changed, 23 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5c4a7d6cf..0a2114bd2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,9 +50,9 @@ set(OBJECTS_VERSION "1.0.21") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5") -set(REPLAYS_VERSION "0.0.37") +set(REPLAYS_VERSION "0.0.38") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") -set(REPLAYS_SHA1 "C31C299539EB86DA013AEE47C9B2B2F4609F52C4") +set(REPLAYS_SHA1 "8940FE7B3F86772214C8CF265E6CEA5A25B49FC1") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/openrct2.proj b/openrct2.proj index 365a794c31..02db22bdb3 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -48,8 +48,8 @@ 304d13a126c15bf2c86ff13b81a2f2cc1856ac8d https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip c38af45d51a6e440386180feacf76c64720b6ac5 - https://github.com/OpenRCT2/replays/releases/download/v0.0.37/replays.zip - C31C299539EB86DA013AEE47C9B2B2F4609F52C4 + https://github.com/OpenRCT2/replays/releases/download/v0.0.38/replays.zip + 8940FE7B3F86772214C8CF265E6CEA5A25B49FC1 diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp index 1c3a142530..68056cffc0 100644 --- a/src/openrct2/GameStateSnapshots.cpp +++ b/src/openrct2/GameStateSnapshots.cpp @@ -197,7 +197,6 @@ struct GameStateSnapshots final : public IGameStateSnapshots { COMPARE_FIELD(SpriteBase, Type); COMPARE_FIELD(SpriteBase, sprite_index); - COMPARE_FIELD(SpriteBase, flags); COMPARE_FIELD(SpriteBase, x); COMPARE_FIELD(SpriteBase, y); COMPARE_FIELD(SpriteBase, z); @@ -392,6 +391,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots COMPARE_FIELD(Vehicle, target_seat_rotation); COMPARE_FIELD(Vehicle, BoatLocation.x); COMPARE_FIELD(Vehicle, BoatLocation.y); + COMPARE_FIELD(Vehicle, IsCrashedVehicle); } void CompareSpriteDataLitter(const Litter& spriteBase, const Litter& spriteCmp, GameStateSpriteChange_t& changeData) const diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 2358beb336..d3cc97aba8 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -36,7 +36,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/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index f8b60a8d72..05f7b47134 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1401,7 +1401,6 @@ private: void ImportEntityCommonProperties(SpriteBase* dst, const RCT12SpriteBase* src) { - dst->flags = src->flags; dst->sprite_direction = src->sprite_direction; dst->sprite_width = src->sprite_width; dst->sprite_height_negative = src->sprite_height_negative; @@ -2877,6 +2876,7 @@ template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase dst->num_peeps = src->num_peeps; dst->next_free_seat = src->next_free_seat; + dst->IsCrashedVehicle = src->flags & RCT12_SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE; } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index fe0ff85f2f..7d25590af7 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -173,6 +173,11 @@ enum RCT12_STATION_STYLE_INVISIBLE, // Added by OpenRCT2 }; +enum +{ + RCT12_SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE = 1 << 7, +}; + #pragma pack(push, 1) struct RCT12xy8 diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 6a1301a925..c75e8d4fd6 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -1068,7 +1068,7 @@ void S6Exporter::ExportEntityCommonProperties(RCT12SpriteBase* dst, const Sprite dst->next_in_quadrant = SPRITE_INDEX_NULL; dst->sprite_height_negative = src->sprite_height_negative; dst->sprite_index = src->sprite_index; - dst->flags = src->flags; + dst->flags = 0; dst->x = src->x; dst->y = src->y; dst->z = src->z; @@ -1167,6 +1167,7 @@ template<> void S6Exporter::ExportEntity(RCT2SpriteVehicle* dst, const Vehicle* dst->colours_extended = src->colours_extended; dst->seat_rotation = src->seat_rotation; dst->target_seat_rotation = src->target_seat_rotation; + dst->flags = src->IsCrashedVehicle ? RCT12_SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE : 0; } template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Guest* src) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 2ac8390f39..db710bbe12 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1512,7 +1512,6 @@ public: dst->Type = GetEntityTypeFromRCT2Sprite(src); dst->sprite_height_negative = src->sprite_height_negative; dst->sprite_index = src->sprite_index; - dst->flags = src->flags; dst->x = src->x; dst->y = src->y; dst->z = src->z; @@ -1666,6 +1665,7 @@ template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc dst->colours_extended = src->colours_extended; dst->seat_rotation = src->seat_rotation; dst->target_seat_rotation = src->target_seat_rotation; + dst->IsCrashedVehicle = src->flags & RCT12_SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE; } template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc) diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 5d9791d242..c1dfc7d154 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -79,6 +79,7 @@ Vehicle* cable_lift_segment_create( current->num_peeps = 0; current->next_free_seat = 0; current->BoatLocation.setNull(); + current->IsCrashedVehicle = false; return current; } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index bdd9c158a1..444cd3ab86 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4270,6 +4270,7 @@ static Vehicle* vehicle_create_car( vehicle->num_peeps = 0; vehicle->next_free_seat = 0; vehicle->BoatLocation.setNull(); + vehicle->IsCrashedVehicle = false; return vehicle; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index a059201492..3b855eeaba 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3606,7 +3606,7 @@ void Vehicle::UpdateCollisionSetup() crashed_vehicle_particle_create(train->colours, { train->x, train->y, train->z }); } - train->flags |= SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE; + train->IsCrashedVehicle = true; train->var_C8 = scenario_rand(); train->var_CA = scenario_rand(); @@ -5365,7 +5365,7 @@ void Vehicle::CrashOnLand() while (numParticles-- != 0) crashed_vehicle_particle_create(colours, { x, y, z }); - flags |= SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE; + IsCrashedVehicle = true; animation_frame = 0; var_C8 = 0; sprite_width = 13; @@ -5428,7 +5428,7 @@ void Vehicle::CrashOnWater() for (int32_t i = 0; i < 10; ++i) crashed_vehicle_particle_create(colours, { x - 4, y + 8, z }); - flags |= SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE; + IsCrashedVehicle = true; animation_frame = 0; var_C8 = 0; sprite_width = 13; diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 455e759687..a21814b8b4 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -204,6 +204,7 @@ struct Vehicle : SpriteBase uint8_t seat_rotation; uint8_t target_seat_rotation; CoordsXY BoatLocation; + bool IsCrashedVehicle; constexpr bool IsHead() const { diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 9183704028..92d57a506b 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -3140,7 +3140,7 @@ template<> void PaintEntity(paint_session* session, const Vehicle* vehicle, int3 int32_t y = vehicle->y; int32_t z = vehicle->z; - if (vehicle->flags & SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE) + if (vehicle->IsCrashedVehicle) { uint32_t ebx = 22965 + vehicle->animation_frame; PaintAddImageAsParent(session, ebx, 0, 0, 1, 1, 0, z, 0, 0, z + 2); diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 7d6f5e40b7..233c015fbc 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -427,7 +427,6 @@ static void PrepareNewEntity(SpriteBase* base, const EntityType type) base->sprite_width = 0x10; base->sprite_height_negative = 0x14; base->sprite_height_positive = 0x8; - base->flags = 0; base->sprite_left = LOCATION_NULL; SpriteSpatialInsert(base, { LOCATION_NULL, 0 }); diff --git a/src/openrct2/world/SpriteBase.h b/src/openrct2/world/SpriteBase.h index a6ce07253c..d46bc7eac5 100644 --- a/src/openrct2/world/SpriteBase.h +++ b/src/openrct2/world/SpriteBase.h @@ -29,7 +29,6 @@ struct SpriteBase // Height from centre of sprite to bottom uint8_t sprite_height_negative; uint16_t sprite_index; - uint16_t flags; int16_t x; int16_t y; int16_t z; diff --git a/test/tests/S6ImportExportTests.cpp b/test/tests/S6ImportExportTests.cpp index f3ee073f7d..bb2cee2455 100644 --- a/test/tests/S6ImportExportTests.cpp +++ b/test/tests/S6ImportExportTests.cpp @@ -132,7 +132,6 @@ static void CompareSpriteDataCommon(const SpriteBase& left, const SpriteBase& ri { COMPARE_FIELD(Type); COMPARE_FIELD(sprite_index); - COMPARE_FIELD(flags); COMPARE_FIELD(x); COMPARE_FIELD(y); COMPARE_FIELD(z); @@ -336,6 +335,7 @@ static void CompareSpriteDataVehicle(const Vehicle& left, const Vehicle& right) COMPARE_FIELD(colours_extended); COMPARE_FIELD(seat_rotation); COMPARE_FIELD(target_seat_rotation); + COMPARE_FIELD(IsCrashedVehicle); } static void CompareSpriteDataLitter(const Litter& left, const Litter& right) From 86e9fe6f19d9ee2b96cf952be74c9f53556ec7c1 Mon Sep 17 00:00:00 2001 From: Jacob Caudill <54962983+jbcaud@users.noreply.github.com> Date: Mon, 12 Apr 2021 07:53:06 -0400 Subject: [PATCH 19/45] Close #13788: Refactor News to new Window framework (#14404) * Refactor News for new Window framework --- src/openrct2-ui/windows/News.cpp | 504 ++++++++++++++----------------- 1 file changed, 234 insertions(+), 270 deletions(-) diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index baf68ef572..09d78458c7 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -33,6 +33,7 @@ enum WINDOW_NEWS_WIDGET_IDX { WIDX_SCROLL }; + static rct_widget window_news_widgets[] = { WINDOW_SHIM(WINDOW_TITLE, WW, WH), MakeWidget({372, 18}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Primary, SPR_TAB_GEARS_0), // settings @@ -40,309 +41,272 @@ static rct_widget window_news_widgets[] = { { WIDGETS_END }, }; -static void window_news_mouseup(rct_window *w, rct_widgetindex widgetIndex); -static void window_news_update(rct_window *w); -static void window_news_scrollgetsize(rct_window *w, int32_t scrollIndex, int32_t *width, int32_t *height); -static void window_news_scrollmousedown(rct_window *w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords); -static void window_news_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int32_t scrollIndex); - -static rct_window_event_list window_news_events([](auto& events) +class NewsWindow final : public Window { - events.mouse_up = &window_news_mouseup; - events.update = &window_news_update; - events.get_scroll_size = &window_news_scrollgetsize; - events.scroll_mousedown = &window_news_scrollmousedown; - events.paint = &window_news_paint; - events.scroll_paint = &window_news_scrollpaint; -}); -// clang-format on - -/** - * - * rct2: 0x0066E464 - */ -rct_window* window_news_open() -{ - rct_window* window; - - // Check if window is already open - window = window_bring_to_front_by_class(WC_RECENT_NEWS); - if (window == nullptr) +private: + int32_t _pressedNewsItemIndex, _pressedButtonIndex, _suspendUpdateTicks; + static int32_t CalculateItemHeight() { - window = WindowCreateAutoPos(400, 300, &window_news_events, WC_RECENT_NEWS, 0); - window->widgets = window_news_widgets; - window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SETTINGS); - WindowInitScrollWidgets(window); - window->news.var_480 = -1; + return 4 * font_get_line_height(FontSpriteBase::SMALL) + 2; } - // sub_66E4BA: - rct_widget* widget; - - int32_t width = 0; - int32_t height = 0; - window_get_scroll_size(window, 0, &width, &height); - widget = &window_news_widgets[WIDX_SCROLL]; - window->scrolls[0].v_top = std::max(0, height - (widget->height() - 1)); - WidgetScrollUpdateThumbs(window, WIDX_SCROLL); - - return window; -} - -static int32_t window_news_get_item_height() -{ - return 4 * font_get_line_height(FontSpriteBase::SMALL) + 2; -} - -/** - * - * rct2: 0x0066D4D5 - */ -static void window_news_mouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) +public: + void OnOpen() override { - case WIDX_CLOSE: - window_close(w); - break; - case WIDX_SETTINGS: - context_open_window(WC_NOTIFICATION_OPTIONS); - break; - } -} + widgets = window_news_widgets; + enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SETTINGS); + WindowInitScrollWidgets(this); + _pressedNewsItemIndex = -1; -/** - * - * rct2: 0x0066EAB8 - */ -static void window_news_update(rct_window* w) -{ - if (w->news.var_480 == -1 || --w->news.var_484 != 0) - { - return; + int32_t w = 0, h = 0; + rct_widget* widget = &widgets[WIDX_SCROLL]; + window_get_scroll_size(this, 0, &w, &h); + scrolls[0].v_top = std::max(0, h - (widget->height() - 1)); + WidgetScrollUpdateThumbs(this, WIDX_SCROLL); } - w->Invalidate(); - OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click2, 0, w->windowPos.x + (w->width / 2)); - - size_t j = w->news.var_480; - w->news.var_480 = -1; - if (j >= gNewsItems.GetArchived().size()) - return; - - const auto& newsItem = gNewsItems.GetArchived()[j]; - if (newsItem.HasButton()) - return; - if (w->news.var_482 == 1) + void OnMouseUp(rct_widgetindex widgetIndex) override { - News::OpenSubject(newsItem.Type, newsItem.Assoc); - } - else if (w->news.var_482 > 1) - { - auto subjectLoc = News::GetSubjectLocation(newsItem.Type, newsItem.Assoc); - if (subjectLoc != std::nullopt && (w = window_get_main()) != nullptr) + switch (widgetIndex) { - window_scroll_to_location(w, *subjectLoc); - } - } -} - -/** - * - * rct2: 0x0066EA3C - */ -static void window_news_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) -{ - *height = static_cast(gNewsItems.GetArchived().size()) * window_news_get_item_height(); -} - -/** - * - * rct2: 0x0066EA5C - */ -static void window_news_scrollmousedown(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords) -{ - int32_t itemHeight = window_news_get_item_height(); - - int32_t i = 0; - int32_t buttonIndex = 0; - auto mutableScreenCoords = screenCoords; - for (const auto& newsItem : gNewsItems.GetArchived()) - { - if (mutableScreenCoords.y < itemHeight) - { - if (newsItem.HasButton() || mutableScreenCoords.y < 14 || mutableScreenCoords.y >= 38 - || mutableScreenCoords.x < 328) - { - buttonIndex = 0; + case WIDX_CLOSE: + Close(); break; - } - else if (mutableScreenCoords.x < 351 && newsItem.TypeHasSubject()) - { - buttonIndex = 1; + case WIDX_SETTINGS: + context_open_window(WC_NOTIFICATION_OPTIONS); break; - } - else if (mutableScreenCoords.x < 376 && newsItem.TypeHasLocation()) - { - buttonIndex = 2; - break; - } } - mutableScreenCoords.y -= itemHeight; - i++; } - if (buttonIndex != 0) + void OnUpdate() override { - w->news.var_480 = i; - w->news.var_482 = buttonIndex; - w->news.var_484 = 4; - w->Invalidate(); - OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, w->windowPos.x + (w->width / 2)); - } -} - -/** - * - * rct2: 0x0066E4E8 - */ -static void window_news_paint(rct_window* w, rct_drawpixelinfo* dpi) -{ - WindowDrawWidgets(w, dpi); -} - -/** - * - * rct2: 0x0066E4EE - */ -static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex) -{ - int32_t lineHeight = font_get_line_height(FontSpriteBase::SMALL); - int32_t itemHeight = window_news_get_item_height(); - - int32_t y = 0; - int32_t i = 0; - for (const auto& newsItem : gNewsItems.GetArchived()) - { - if (y >= dpi->y + dpi->height) - break; - if (y + itemHeight < dpi->y) + if (_pressedNewsItemIndex == -1 || --_suspendUpdateTicks != 0) { - y += itemHeight; - i++; - continue; + return; } - // Background - gfx_fill_rect_inset( - dpi, { -1, y, 383, y + itemHeight - 1 }, w->colours[1], (INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_GREY)); + Invalidate(); + OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click2, 0, windowPos.x + (width / 2)); - // Date text - { - auto ft = Formatter(); - ft.Add(DateDayNames[newsItem.Day - 1]); - ft.Add(DateGameMonthNames[date_get_month(newsItem.MonthYear)]); - DrawTextBasic(dpi, { 2, y }, STR_NEWS_DATE_FORMAT, ft, { COLOUR_WHITE, FontSpriteBase::SMALL }); - } - // Item text - { - auto ft = Formatter(); - ft.Add(newsItem.Text.c_str()); - DrawTextWrapped(dpi, { 2, y + lineHeight }, 325, STR_BOTTOM_TOOLBAR_NEWS_TEXT, ft, { FontSpriteBase::SMALL }); - } - // Subject button - if ((newsItem.TypeHasSubject()) && !(newsItem.HasButton())) - { - auto screenCoords = ScreenCoordsXY{ 328, y + lineHeight + 4 }; + size_t j = _pressedNewsItemIndex; + _pressedNewsItemIndex = -1; - int32_t press = 0; - if (w->news.var_480 != -1) + if (j >= gNewsItems.GetArchived().size()) + { + return; + } + + const auto& newsItem = gNewsItems.GetArchived()[j]; + if (newsItem.HasButton()) + { + return; + } + + if (_pressedButtonIndex == 1) + { + News::OpenSubject(newsItem.Type, newsItem.Assoc); + } + else if (_pressedButtonIndex > 1) + { + static rct_window* _mainWindow; + auto subjectLoc = News::GetSubjectLocation(newsItem.Type, newsItem.Assoc); + if (subjectLoc != std::nullopt && (_mainWindow = window_get_main()) != nullptr) { - News::IsValidIndex(w->news.var_480 + News::ItemHistoryStart); - if (i == w->news.var_480 && w->news.var_482 == 1) - press = INSET_RECT_FLAG_BORDER_INSET; + window_scroll_to_location(_mainWindow, *subjectLoc); } - gfx_fill_rect_inset(dpi, { screenCoords, screenCoords + ScreenCoordsXY{ 23, 23 } }, w->colours[2], press); + } + } - switch (newsItem.Type) + ScreenSize OnScrollGetSize(int32_t scrollIndex) override + { + static int32_t _scrollHeight = static_cast(gNewsItems.GetArchived().size()) * CalculateItemHeight(); + return {WW, _scrollHeight}; + } + + void OnScrollMouseDown(int32_t scrollIndex, const ScreenCoordsXY& screenCoords) override + { + int32_t itemHeight = CalculateItemHeight(); + int32_t i = 0; + int32_t buttonIndex = 0; + auto mutableScreenCoords = screenCoords; + for (const auto& newsItem : gNewsItems.GetArchived()) + { + if (mutableScreenCoords.y < itemHeight) { - case News::ItemType::Ride: - gfx_draw_sprite(dpi, ImageId(SPR_RIDE), screenCoords); - break; - case News::ItemType::Peep: - case News::ItemType::PeepOnRide: + if (newsItem.HasButton() || mutableScreenCoords.y < 14 || mutableScreenCoords.y >= 38 + || mutableScreenCoords.x < 328) { - rct_drawpixelinfo cliped_dpi; - if (!clip_drawpixelinfo(&cliped_dpi, dpi, screenCoords + ScreenCoordsXY{ 1, 1 }, 22, 22)) - { - break; - } - - auto peep = TryGetEntity(newsItem.Assoc); - if (peep == nullptr) - break; - - auto clipCoords = ScreenCoordsXY{ 10, 19 }; - - // If normal peep set sprite to normal (no food) - // If staff set sprite to staff sprite - auto spriteType = PeepSpriteType::Normal; - if (peep->Is()) - { - spriteType = peep->SpriteType; - if (peep->AssignedStaffType == StaffType::Entertainer) - { - clipCoords.y += 3; - } - } - - uint32_t image_id = GetPeepAnimation(spriteType).base_image; - image_id += 0xA0000001; - image_id |= (peep->TshirtColour << 19) | (peep->TrousersColour << 24); - - gfx_draw_sprite(&cliped_dpi, ImageId::FromUInt32(image_id), clipCoords); + buttonIndex = 0; break; } - case News::ItemType::Money: - gfx_draw_sprite(dpi, ImageId(SPR_FINANCE), screenCoords); + else if (mutableScreenCoords.x < 351 && newsItem.TypeHasSubject()) + { + buttonIndex = 1; break; - case News::ItemType::Research: - gfx_draw_sprite(dpi, ImageId(newsItem.Assoc < 0x10000 ? SPR_NEW_SCENERY : SPR_NEW_RIDE), screenCoords); - break; - case News::ItemType::Peeps: - gfx_draw_sprite(dpi, ImageId(SPR_GUESTS), screenCoords); - break; - case News::ItemType::Award: - gfx_draw_sprite(dpi, ImageId(SPR_AWARD), screenCoords); - break; - case News::ItemType::Graph: - gfx_draw_sprite(dpi, ImageId(SPR_GRAPH), screenCoords); - break; - case News::ItemType::Null: - case News::ItemType::Blank: - case News::ItemType::Count: + } + else if (mutableScreenCoords.x < 376 && newsItem.TypeHasLocation()) + { + buttonIndex = 2; break; + } } + mutableScreenCoords.y -= itemHeight; + i++; } - // Location button - if ((newsItem.TypeHasLocation()) && !(newsItem.HasButton())) + if (buttonIndex != 0) { - auto screenCoords = ScreenCoordsXY{ 352, y + lineHeight + 4 }; - - int32_t press = 0; - if (w->news.var_480 != -1) - { - News::IsValidIndex(w->news.var_480 + News::ItemHistoryStart); - if (i == w->news.var_480 && w->news.var_482 == 2) - press = 0x20; - } - gfx_fill_rect_inset(dpi, { screenCoords, screenCoords + ScreenCoordsXY{ 23, 23 } }, w->colours[2], press); - gfx_draw_sprite(dpi, ImageId(SPR_LOCATE), screenCoords); + _pressedNewsItemIndex = i; + _pressedButtonIndex = buttonIndex; + _suspendUpdateTicks = 4; + Invalidate(); + OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, windowPos.x + (width / 2)); } - - y += itemHeight; - i++; } -} + + void OnDraw(rct_drawpixelinfo& dpi) override + { + DrawWidgets(dpi); + } + + void OnScrollDraw(int32_t scrollIndex, rct_drawpixelinfo& dpi) override + { + int32_t lineHeight = font_get_line_height(FontSpriteBase::SMALL); + int32_t itemHeight = CalculateItemHeight(); + int32_t y = 0; + int32_t i = 0; + + for (const auto& newsItem : gNewsItems.GetArchived()) + { + if (y >= dpi.y + dpi.height) + break; + if (y + itemHeight < dpi.y) + { + y += itemHeight; + i++; + continue; + } + + // Background + gfx_fill_rect_inset( + &dpi, { -1, y, 383, y + itemHeight - 1 }, colours[1], (INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_GREY)); + + // Date text + { + auto ft = Formatter(); + ft.Add(DateDayNames[newsItem.Day - 1]); + ft.Add(DateGameMonthNames[date_get_month(newsItem.MonthYear)]); + DrawTextBasic(&dpi, { 2, y }, STR_NEWS_DATE_FORMAT, ft, { COLOUR_WHITE, FontSpriteBase::SMALL }); + } + // Item text + { + auto ft = Formatter(); + ft.Add(newsItem.Text.c_str()); + DrawTextWrapped(&dpi, { 2, y + lineHeight }, 325, STR_BOTTOM_TOOLBAR_NEWS_TEXT, ft, { FontSpriteBase::SMALL }); + } + // Subject button + if ((newsItem.TypeHasSubject()) && !(newsItem.HasButton())) + { + auto screenCoords = ScreenCoordsXY{ 328, y + lineHeight + 4 }; + + int32_t press = 0; + if (_pressedNewsItemIndex != -1) + { + News::IsValidIndex(_pressedNewsItemIndex + News::ItemHistoryStart); + if (i == _pressedNewsItemIndex && _pressedButtonIndex == 1) + { + press = INSET_RECT_FLAG_BORDER_INSET; + } + + } + gfx_fill_rect_inset(&dpi, { screenCoords, screenCoords + ScreenCoordsXY{ 23, 23 } }, colours[2], press); + + switch (newsItem.Type) + { + case News::ItemType::Ride: + gfx_draw_sprite(&dpi, ImageId(SPR_RIDE), screenCoords); + break; + case News::ItemType::Peep: + case News::ItemType::PeepOnRide: + { + rct_drawpixelinfo cliped_dpi; + if (!clip_drawpixelinfo(&cliped_dpi, &dpi, screenCoords + ScreenCoordsXY{ 1, 1 }, 22, 22)) + { + break; + } + + auto peep = TryGetEntity(newsItem.Assoc); + if (peep == nullptr) + { + break; + } + + auto clipCoords = ScreenCoordsXY{ 10, 19 }; + + // If normal peep set sprite to normal (no food) + // If staff set sprite to staff sprite + auto spriteType = PeepSpriteType::Normal; + if (peep->Is()) + { + spriteType = peep->SpriteType; + if (peep->AssignedStaffType == StaffType::Entertainer) + { + clipCoords.y += 3; + } + } + + uint32_t image_id = GetPeepAnimation(spriteType).base_image; + image_id += 0xA0000001; + image_id |= (peep->TshirtColour << 19) | (peep->TrousersColour << 24); + + gfx_draw_sprite(&cliped_dpi, ImageId::FromUInt32(image_id), clipCoords); + break; + } + case News::ItemType::Money: + gfx_draw_sprite(&dpi, ImageId(SPR_FINANCE), screenCoords); + break; + case News::ItemType::Research: + gfx_draw_sprite(&dpi, ImageId(newsItem.Assoc < 0x10000 ? SPR_NEW_SCENERY : SPR_NEW_RIDE), screenCoords); + break; + case News::ItemType::Peeps: + gfx_draw_sprite(&dpi, ImageId(SPR_GUESTS), screenCoords); + break; + case News::ItemType::Award: + gfx_draw_sprite(&dpi, ImageId(SPR_AWARD), screenCoords); + break; + case News::ItemType::Graph: + gfx_draw_sprite(&dpi, ImageId(SPR_GRAPH), screenCoords); + break; + case News::ItemType::Null: + case News::ItemType::Blank: + case News::ItemType::Count: + break; + } + } + + // Location button + if ((newsItem.TypeHasLocation()) && !(newsItem.HasButton())) + { + auto screenCoords = ScreenCoordsXY{ 352, y + lineHeight + 4 }; + + int32_t press = 0; + if (_pressedNewsItemIndex != -1) + { + News::IsValidIndex(_pressedNewsItemIndex + News::ItemHistoryStart); + if (i == _pressedNewsItemIndex && _pressedButtonIndex == 2) + press = 0x20; + } + gfx_fill_rect_inset(&dpi, { screenCoords, screenCoords + ScreenCoordsXY{ 23, 23 } }, colours[2], press); + gfx_draw_sprite(&dpi, ImageId(SPR_LOCATE), screenCoords); + } + + y += itemHeight; + i++; + } + } +}; + +rct_window* window_news_open() +{ + return WindowFocusOrCreate(WC_RECENT_NEWS, WW, WH, 0); +} \ No newline at end of file From 1b64fc871b86e9b5ac618743816988450b8dc245 Mon Sep 17 00:00:00 2001 From: Hampus Date: Mon, 12 Apr 2021 13:53:58 +0200 Subject: [PATCH 20/45] Close #13805: Refactor Sign window to class (#14417) * Refactor window to class: Sign Fix: Refactor window to class: Sign #13805 --- src/openrct2-ui/windows/Sign.cpp | 664 +++++++++++-------------------- 1 file changed, 238 insertions(+), 426 deletions(-) diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index b6f876b8c1..c8e81b18af 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -52,45 +52,235 @@ static rct_widget window_sign_widgets[] = { { WIDGETS_END }, }; -static void window_sign_mouseup(rct_window *w, rct_widgetindex widgetIndex); -static void window_sign_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget* widget); -static void window_sign_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex); -static void window_sign_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text); -static void window_sign_viewport_rotate(rct_window *w); -static void window_sign_invalidate(rct_window *w); -static void window_sign_paint(rct_window *w, rct_drawpixelinfo *dpi); - - -// 0x98E44C -static rct_window_event_list window_sign_events([](auto& events) -{ - events.mouse_up = &window_sign_mouseup; - events.mouse_down = &window_sign_mousedown; - events.dropdown = &window_sign_dropdown; - events.text_input = &window_sign_textinput; - events.viewport_rotate = &window_sign_viewport_rotate; - events.invalidate = &window_sign_invalidate; - events.paint = &window_sign_paint; -}); - -static void window_sign_small_mouseup(rct_window *w, rct_widgetindex widgetIndex); -static void window_sign_small_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex); -static void window_sign_small_invalidate(rct_window *w); - -// 0x9A410C -static rct_window_event_list window_sign_small_events([](auto& events) -{ - events.mouse_up = &window_sign_small_mouseup; - events.mouse_down = &window_sign_mousedown; - events.dropdown = &window_sign_small_dropdown; - events.text_input = &window_sign_textinput; - events.viewport_rotate = &window_sign_viewport_rotate; - events.invalidate = &window_sign_small_invalidate; - events.paint = &window_sign_paint; -}); // clang-format on -static void window_sign_show_text_input(rct_window* w); +class SignWindow final : public Window +{ +private: + bool _isSmall = false; + Banner* _banner = nullptr; + TileElement* _tileElement = nullptr; + + void ShowTextInput() + { + if (_banner != nullptr) + { + auto bannerText = _banner->GetText(); + window_text_input_raw_open(this, WIDX_SIGN_TEXT, STR_SIGN_TEXT_TITLE, STR_SIGN_TEXT_PROMPT, bannerText.c_str(), 32); + } + } + +public: + void OnOpen() override + { + widgets = window_sign_widgets; + enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SIGN_TEXT) | (1 << WIDX_SIGN_DEMOLISH) | (1 << WIDX_MAIN_COLOUR) + | (1 << WIDX_TEXT_COLOUR); + + WindowInitScrollWidgets(this); + } + + /* + * Initializes the window and sets it's number and if it's small + * @return true if successfull + */ + bool Initialize(rct_windownumber windowNumber, const bool isSmall) + { + number = windowNumber; + _isSmall = isSmall; + + _banner = GetBanner(number); + if (_banner == nullptr) + return false; + + auto signViewPosition = _banner->position.ToCoordsXY().ToTileCentre(); + _tileElement = banner_get_tile_element(number); + if (_tileElement == nullptr) + return false; + + int32_t viewZ = _tileElement->GetBaseZ(); + frame_no = viewZ; + + if (_isSmall) + { + list_information_type = _tileElement->AsWall()->GetPrimaryColour(); + var_492 = _tileElement->AsWall()->GetSecondaryColour(); + SceneryEntry = _tileElement->AsWall()->GetEntryIndex(); + } + else + { + list_information_type = _tileElement->AsLargeScenery()->GetPrimaryColour(); + var_492 = _tileElement->AsLargeScenery()->GetSecondaryColour(); + SceneryEntry = _tileElement->AsLargeScenery()->GetEntryIndex(); + } + + // Create viewport + rct_widget& viewportWidget = window_sign_widgets[WIDX_VIEWPORT]; + + viewport_create( + this, windowPos + ScreenCoordsXY{ viewportWidget.left + 1, viewportWidget.top + 1 }, viewportWidget.width() - 1, + viewportWidget.height() - 1, 0, { signViewPosition, viewZ }, 0, SPRITE_INDEX_NULL); + + viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; + Invalidate(); + + return true; + } + + void OnMouseUp(rct_widgetindex widgetIndex) override + { + switch (widgetIndex) + { + case WIDX_CLOSE: + Close(); + break; + case WIDX_SIGN_DEMOLISH: + { + auto bannerCoords = _banner->position.ToCoordsXY(); + + if (_isSmall) + { + CoordsXYZD wallLocation = { bannerCoords, _tileElement->GetBaseZ(), _tileElement->GetDirection() }; + auto wallRemoveAction = WallRemoveAction(wallLocation); + GameActions::Execute(&wallRemoveAction); + } + else + { + auto sceneryRemoveAction = LargeSceneryRemoveAction( + { bannerCoords, _tileElement->GetBaseZ(), _tileElement->GetDirection() }, + _tileElement->AsLargeScenery()->GetSequenceIndex()); + GameActions::Execute(&sceneryRemoveAction); + } + break; + } + case WIDX_SIGN_TEXT: + ShowTextInput(); + break; + } + } + + void OnMouseDown(rct_widgetindex widgetIndex) override + { + rct_widget* widget = &widgets[widgetIndex]; + switch (widgetIndex) + { + case WIDX_MAIN_COLOUR: + WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(list_information_type)); + break; + case WIDX_TEXT_COLOUR: + WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(var_492)); + break; + } + } + + void OnDropdown(rct_widgetindex widgetIndex, int32_t dropdownIndex) override + { + switch (widgetIndex) + { + case WIDX_MAIN_COLOUR: + { + if (dropdownIndex == -1) + return; + list_information_type = dropdownIndex; + auto signSetStyleAction = SignSetStyleAction(number, dropdownIndex, var_492, !_isSmall); + GameActions::Execute(&signSetStyleAction); + break; + } + case WIDX_TEXT_COLOUR: + { + if (dropdownIndex == -1) + return; + var_492 = dropdownIndex; + auto signSetStyleAction = SignSetStyleAction(number, list_information_type, dropdownIndex, !_isSmall); + GameActions::Execute(&signSetStyleAction); + break; + } + default: + return; + } + + Invalidate(); + } + + void OnTextInput(rct_widgetindex widgetIndex, std::string_view text) override + { + if (widgetIndex == WIDX_SIGN_TEXT && !text.empty()) + { + auto signSetNameAction = SignSetNameAction(number, std::string(text)); + GameActions::Execute(&signSetNameAction); + } + } + + void OnPrepareDraw() override + { + rct_widget* main_colour_btn = &window_sign_widgets[WIDX_MAIN_COLOUR]; + rct_widget* text_colour_btn = &window_sign_widgets[WIDX_TEXT_COLOUR]; + + if (_isSmall) + { + rct_scenery_entry* scenery_entry = get_wall_entry(SceneryEntry); + + main_colour_btn->type = WindowWidgetType::Empty; + text_colour_btn->type = WindowWidgetType::Empty; + + if (scenery_entry->wall.flags & WALL_SCENERY_HAS_PRIMARY_COLOUR) + { + main_colour_btn->type = WindowWidgetType::ColourBtn; + } + if (scenery_entry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) + { + text_colour_btn->type = WindowWidgetType::ColourBtn; + } + } + else + { + rct_scenery_entry* scenery_entry = get_large_scenery_entry(SceneryEntry); + + main_colour_btn->type = WindowWidgetType::Empty; + text_colour_btn->type = WindowWidgetType::Empty; + + if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR) + { + main_colour_btn->type = WindowWidgetType::ColourBtn; + } + if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR) + { + text_colour_btn->type = WindowWidgetType::ColourBtn; + } + } + + main_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(list_information_type) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; + text_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(var_492) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; + } + + void OnDraw(rct_drawpixelinfo& dpi) override + { + DrawWidgets(dpi); + + if (viewport != nullptr) + { + window_draw_viewport(&dpi, this); + } + } + + void OnViewportRotate() override + { + RemoveViewport(); + + auto banner = GetBanner(number); + + auto signViewPos = CoordsXYZ{ banner->position.ToCoordsXY().ToTileCentre(), frame_no }; + + // Create viewport + rct_widget* viewportWidget = &window_sign_widgets[WIDX_VIEWPORT]; + viewport_create( + this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1, + viewportWidget->height() - 1, 0, signViewPos, 0, SPRITE_INDEX_NULL); + if (viewport != nullptr) + viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; + Invalidate(); + } +}; /** * @@ -98,420 +288,42 @@ static void window_sign_show_text_input(rct_window* w); */ rct_window* window_sign_open(rct_windownumber number) { - rct_window* w; - rct_widget* viewportWidget; + auto* w = static_cast(window_bring_to_front_by_number(WC_BANNER, number)); - // Check if window is already open - w = window_bring_to_front_by_number(WC_BANNER, number); if (w != nullptr) return w; - w = WindowCreateAutoPos(WW, WH, &window_sign_events, WC_BANNER, WF_NO_SCROLLING); - w->widgets = window_sign_widgets; - w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SIGN_TEXT) | (1 << WIDX_SIGN_DEMOLISH) | (1 << WIDX_MAIN_COLOUR) - | (1 << WIDX_TEXT_COLOUR); + w = WindowCreate(WC_BANNER, WW, WH, 0); - w->number = number; - WindowInitScrollWidgets(w); - - auto banner = GetBanner(w->number); - if (banner == nullptr) + if (w == nullptr) return nullptr; - auto signViewPos = banner->position.ToCoordsXY().ToTileCentre(); - TileElement* tile_element = map_get_first_element_at(signViewPos); - if (tile_element == nullptr) + bool result = w->Initialize(number, false); + if (result != true) return nullptr; - while (1) - { - if (tile_element->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY) - { - rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry(); - if (scenery_entry != nullptr && scenery_entry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) - { - auto bannerIndex = tile_element->AsLargeScenery()->GetBannerIndex(); - - if (bannerIndex == w->number) - break; - } - } - tile_element++; - if (tile_element >= &gTileElements[std::size(gTileElements)]) - { - return nullptr; - } - } - - int32_t view_z = tile_element->GetBaseZ(); - w->frame_no = view_z; - - w->list_information_type = tile_element->AsLargeScenery()->GetPrimaryColour(); - w->var_492 = tile_element->AsLargeScenery()->GetSecondaryColour(); - w->SceneryEntry = tile_element->AsLargeScenery()->GetEntryIndex(); - - // Create viewport - viewportWidget = &window_sign_widgets[WIDX_VIEWPORT]; - viewport_create( - w, w->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1, - viewportWidget->height() - 1, 0, { signViewPos, view_z }, 0, SPRITE_INDEX_NULL); - - w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; - w->Invalidate(); - return w; } -/** - * - * rct2: 0x6B9765 - */ -static void window_sign_mouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) - { - case WIDX_CLOSE: - window_close(w); - break; - case WIDX_SIGN_DEMOLISH: - { - auto banner = GetBanner(w->number); - auto bannerCoords = banner->position.ToCoordsXY(); - auto tile_element = map_get_first_element_at(bannerCoords); - if (tile_element == nullptr) - return; - while (1) - { - if (tile_element->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY) - { - rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry(); - if (scenery_entry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) - { - auto bannerIndex = tile_element->AsLargeScenery()->GetBannerIndex(); - if (bannerIndex == w->number) - break; - } - } - tile_element++; - if (tile_element >= &gTileElements[std::size(gTileElements)]) - { - return; - } - } - - auto sceneryRemoveAction = LargeSceneryRemoveAction( - { bannerCoords, tile_element->GetBaseZ(), tile_element->GetDirection() }, - tile_element->AsLargeScenery()->GetSequenceIndex()); - GameActions::Execute(&sceneryRemoveAction); - break; - } - case WIDX_SIGN_TEXT: - window_sign_show_text_input(w); - break; - } -} - -/** - * - * rct2: 0x6B9784 - & 0x6E6164 */ -static void window_sign_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget) -{ - switch (widgetIndex) - { - case WIDX_MAIN_COLOUR: - WindowDropdownShowColour(w, widget, TRANSLUCENT(w->colours[1]), static_cast(w->list_information_type)); - break; - case WIDX_TEXT_COLOUR: - WindowDropdownShowColour(w, widget, TRANSLUCENT(w->colours[1]), static_cast(w->var_492)); - break; - } -} - -/** - * - * rct2: 0x6B979C - */ -static void window_sign_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) -{ - switch (widgetIndex) - { - case WIDX_MAIN_COLOUR: - { - if (dropdownIndex == -1) - return; - w->list_information_type = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(w->number, dropdownIndex, w->var_492, true); - GameActions::Execute(&signSetStyleAction); - break; - } - case WIDX_TEXT_COLOUR: - { - if (dropdownIndex == -1) - return; - w->var_492 = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(w->number, w->list_information_type, dropdownIndex, true); - GameActions::Execute(&signSetStyleAction); - break; - } - default: - return; - } - - w->Invalidate(); -} - -/** - * - * rct2: 0x6B9791, 0x6E6171 - */ -static void window_sign_textinput(rct_window* w, rct_widgetindex widgetIndex, char* text) -{ - if (widgetIndex == WIDX_SIGN_TEXT && text != nullptr) - { - auto signSetNameAction = SignSetNameAction(w->number, text); - GameActions::Execute(&signSetNameAction); - } -} - -/** - * - * rct2: 0x006B96F5 - */ -static void window_sign_invalidate(rct_window* w) -{ - rct_widget* main_colour_btn = &window_sign_widgets[WIDX_MAIN_COLOUR]; - rct_widget* text_colour_btn = &window_sign_widgets[WIDX_TEXT_COLOUR]; - - rct_scenery_entry* scenery_entry = get_large_scenery_entry(w->SceneryEntry); - - main_colour_btn->type = WindowWidgetType::Empty; - text_colour_btn->type = WindowWidgetType::Empty; - - if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR) - { - main_colour_btn->type = WindowWidgetType::ColourBtn; - } - if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR) - { - text_colour_btn->type = WindowWidgetType::ColourBtn; - } - - main_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(w->list_information_type) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; - text_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(w->var_492) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; -} - -/** - * - * rct2: 0x006B9754, 0x006E6134 - */ -static void window_sign_paint(rct_window* w, rct_drawpixelinfo* dpi) -{ - WindowDrawWidgets(w, dpi); - - // Draw viewport - if (w->viewport != nullptr) - { - window_draw_viewport(dpi, w); - } -} - -/** - * - * rct2: 0x6B9A6C, 0x6E6424 - */ -static void window_sign_viewport_rotate(rct_window* w) -{ - w->RemoveViewport(); - - auto banner = GetBanner(w->number); - - auto signViewPos = CoordsXYZ{ banner->position.ToCoordsXY().ToTileCentre(), w->frame_no }; - - // Create viewport - rct_widget* viewportWidget = &window_sign_widgets[WIDX_VIEWPORT]; - viewport_create( - w, w->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1, - viewportWidget->height() - 1, 0, signViewPos, 0, SPRITE_INDEX_NULL); - if (w->viewport != nullptr) - w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; - w->Invalidate(); -} - /** * * rct2: 0x6E5F52 */ rct_window* window_sign_small_open(rct_windownumber number) { - rct_window* w; - rct_widget* viewportWidget; + auto* w = static_cast(window_bring_to_front_by_number(WC_BANNER, number)); - // Check if window is already open - w = window_bring_to_front_by_number(WC_BANNER, number); if (w != nullptr) return w; - w = WindowCreateAutoPos(WW, WH, &window_sign_small_events, WC_BANNER, 0); - w->widgets = window_sign_widgets; - w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SIGN_TEXT) | (1 << WIDX_SIGN_DEMOLISH) | (1 << WIDX_MAIN_COLOUR) - | (1 << WIDX_TEXT_COLOUR); + w = WindowCreate(WC_BANNER, WW, WH, 0); - w->number = number; - WindowInitScrollWidgets(w); - w->colours[0] = COLOUR_DARK_BROWN; - w->colours[1] = COLOUR_DARK_BROWN; - w->colours[2] = COLOUR_DARK_BROWN; - - auto banner = GetBanner(w->number); - auto signViewPos = banner->position.ToCoordsXY().ToTileCentre(); - - TileElement* tile_element = map_get_first_element_at(signViewPos); - if (tile_element == nullptr) + if (w == nullptr) return nullptr; - while (1) - { - if (tile_element->GetType() == TILE_ELEMENT_TYPE_WALL) - { - rct_scenery_entry* scenery_entry = tile_element->AsWall()->GetEntry(); - if (scenery_entry->wall.scrolling_mode != SCROLLING_MODE_NONE) - { - if (tile_element->AsWall()->GetBannerIndex() == w->number) - break; - } - } - tile_element++; - } - - int32_t view_z = tile_element->GetBaseZ(); - w->frame_no = view_z; - - w->list_information_type = tile_element->AsWall()->GetPrimaryColour(); - w->var_492 = tile_element->AsWall()->GetSecondaryColour(); - w->SceneryEntry = tile_element->AsWall()->GetEntryIndex(); - - // Create viewport - viewportWidget = &window_sign_widgets[WIDX_VIEWPORT]; - viewport_create( - w, w->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1, - viewportWidget->height() - 1, 0, { signViewPos, view_z }, 0, SPRITE_INDEX_NULL); - - w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; - w->flags |= WF_NO_SCROLLING; - w->Invalidate(); + bool result = w->Initialize(number, true); + if (result != true) + return nullptr; return w; } - -/** - * - * rct2: 0x6E6145 - */ -static void window_sign_small_mouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) - { - case WIDX_CLOSE: - window_close(w); - break; - case WIDX_SIGN_DEMOLISH: - { - auto banner = GetBanner(w->number); - auto bannerCoords = banner->position.ToCoordsXY(); - auto tile_element = map_get_first_element_at(bannerCoords); - if (tile_element == nullptr) - return; - while (true) - { - if (tile_element->GetType() == TILE_ELEMENT_TYPE_WALL) - { - rct_scenery_entry* scenery_entry = tile_element->AsWall()->GetEntry(); - if (scenery_entry->wall.scrolling_mode != SCROLLING_MODE_NONE) - { - if (tile_element->AsWall()->GetBannerIndex() == w->number) - break; - } - } - tile_element++; - } - CoordsXYZD wallLocation = { bannerCoords, tile_element->GetBaseZ(), tile_element->GetDirection() }; - auto wallRemoveAction = WallRemoveAction(wallLocation); - GameActions::Execute(&wallRemoveAction); - break; - } - case WIDX_SIGN_TEXT: - window_sign_show_text_input(w); - break; - } -} - -/** - * - * rct2: 0x6E617C - */ -static void window_sign_small_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) -{ - switch (widgetIndex) - { - case WIDX_MAIN_COLOUR: - { - if (dropdownIndex == -1) - return; - w->list_information_type = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(w->number, dropdownIndex, w->var_492, false); - GameActions::Execute(&signSetStyleAction); - break; - } - case WIDX_TEXT_COLOUR: - { - if (dropdownIndex == -1) - return; - w->var_492 = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(w->number, w->list_information_type, dropdownIndex, false); - GameActions::Execute(&signSetStyleAction); - break; - } - default: - return; - } - - w->Invalidate(); -} - -/** - * - * rct2: 0x006E60D5 - */ -static void window_sign_small_invalidate(rct_window* w) -{ - rct_widget* main_colour_btn = &window_sign_widgets[WIDX_MAIN_COLOUR]; - rct_widget* text_colour_btn = &window_sign_widgets[WIDX_TEXT_COLOUR]; - - rct_scenery_entry* scenery_entry = get_wall_entry(w->SceneryEntry); - - main_colour_btn->type = WindowWidgetType::Empty; - text_colour_btn->type = WindowWidgetType::Empty; - - if (scenery_entry->wall.flags & WALL_SCENERY_HAS_PRIMARY_COLOUR) - { - main_colour_btn->type = WindowWidgetType::ColourBtn; - } - if (scenery_entry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) - { - text_colour_btn->type = WindowWidgetType::ColourBtn; - } - - main_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(w->list_information_type) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; - text_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(w->var_492) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; -} - -static void window_sign_show_text_input(rct_window* w) -{ - auto banner = GetBanner(w->number); - if (banner != nullptr) - { - auto bannerText = banner->GetText(); - window_text_input_raw_open(w, WIDX_SIGN_TEXT, STR_SIGN_TEXT_TITLE, STR_SIGN_TEXT_PROMPT, bannerText.c_str(), 32); - } -} From 3188865313485c02acb56abaf125a3380e967185 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Mon, 12 Apr 2021 12:01:15 -1000 Subject: [PATCH 21/45] Script improvements (#14452) shebang: Move parameters from set. Add newline after for consistency. curl: Add -f; Prevents output on error. Use -O where applicable; -o with the same filename as the URL is pointless. Add -S after -s: Makes curl still error despite being silent. build-symbols: Add zip fallback. get-discord-rpc: Move git clone parameters before repository for readability. Use --depth 1 to speed up cloning. install-nsis: Use ProgramData environment variable. build-appimage-docker.sh: Add -e to docker run. Run script directly. build-appimage.sh: Make if more consistent. Remove unused Travis scripts. setenv: unset instead of blanking variables. vstool.cmd: Use ProgramFiles(x86) environment variable. --- OpenRCT2.xcodeproj/project.pbxproj | 6 +- scripts/build | 3 +- scripts/build-appimage | 5 +- scripts/build-installer | 4 +- scripts/build-portable | 3 +- scripts/build-symbols | 21 ++-- scripts/check-code-formatting | 3 +- scripts/get-discord-rpc | 8 +- scripts/install-nsis | 14 +-- scripts/linux/build-appimage-docker.sh | 8 +- scripts/linux/build-appimage.sh | 7 +- scripts/linux/build.sh | 87 ---------------- scripts/linux/clean.sh | 17 ---- scripts/linux/install.sh | 132 ------------------------- scripts/run-clang-format.py | 1 + scripts/run-testpaint | 3 +- scripts/run-tests | 3 +- scripts/setenv | 10 +- scripts/stats/count-rct-globals.php | 1 + scripts/upload-backtrace-symbols | 4 +- scripts/upload-build | 4 +- scripts/vstool | 1 + scripts/vstool.cmd | 4 +- 23 files changed, 54 insertions(+), 295 deletions(-) delete mode 100755 scripts/linux/build.sh delete mode 100755 scripts/linux/clean.sh delete mode 100755 scripts/linux/install.sh diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index df30e342b1..5e7d975780 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -3605,7 +3605,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"1.0.20\"\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\n"; + shellScript = "version=\"1.0.20\"\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 -fLo \"${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\n"; }; C68B2D471EC790710020651C /* Download Libraries */ = { isa = PBXShellScriptBuildPhase; @@ -3619,7 +3619,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"28\"\nzipname=\"openrct2-libs-v28-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"; + shellScript = "version=\"28\"\nzipname=\"openrct2-libs-v28-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 -fLo \"${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; @@ -3666,7 +3666,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"0.1.2c\"\nzipname=\"title-sequences.zip\"\nliburl=\"https://github.com/OpenRCT2/title-sequences/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/sequence\" || ! -e \"${SRCROOT}/sequencesversion\" || $(head -n 1 \"${SRCROOT}/sequencesversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/sequence\" ]]; then rm -r \"${SRCROOT}/data/sequence\"; fi\nmkdir -p \"${SRCROOT}/data/sequence\"\n\ncurl -L -o \"${SRCROOT}/data/sequence/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/sequence\" \"${SRCROOT}/data/sequence/$zipname\"\nrm \"${SRCROOT}/data/sequence/$zipname\"\n\necho $version > \"${SRCROOT}/sequencesversion\"\nfi\n"; + shellScript = "version=\"0.1.2c\"\nzipname=\"title-sequences.zip\"\nliburl=\"https://github.com/OpenRCT2/title-sequences/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/sequence\" || ! -e \"${SRCROOT}/sequencesversion\" || $(head -n 1 \"${SRCROOT}/sequencesversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/sequence\" ]]; then rm -r \"${SRCROOT}/data/sequence\"; fi\nmkdir -p \"${SRCROOT}/data/sequence\"\n\ncurl -fLo \"${SRCROOT}/data/sequence/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/sequence\" \"${SRCROOT}/data/sequence/$zipname\"\nrm \"${SRCROOT}/data/sequence/$zipname\"\n\necho $version > \"${SRCROOT}/sequencesversion\"\nfi\n"; }; F76C809F1EC4DB0300FA49E2 /* Get Git Variables */ = { isa = PBXShellScriptBuildPhase; diff --git a/scripts/build b/scripts/build index 160d7c331b..9274410488 100755 --- a/scripts/build +++ b/scripts/build @@ -1,5 +1,4 @@ -#!/bin/bash -set -e +#!/bin/bash -e # Ensure we are in root directory if [[ $(uname) == "Darwin" ]]; then diff --git a/scripts/build-appimage b/scripts/build-appimage index 498706c5ba..0bc94c9a14 100755 --- a/scripts/build-appimage +++ b/scripts/build-appimage @@ -1,5 +1,4 @@ -#!/bin/bash -set -e +#!/bin/bash -e echo -e "\033[0;36mBuilding AppImage for OpenRCT2...\033[0m" @@ -8,7 +7,7 @@ basedir="$(readlink -f `dirname $0`/..)" cd $basedir linuxdeploy=/tmp/linuxdeploy-x86_64.AppImage -curl -Lo $linuxdeploy https://github.com/TheAssassin/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage +curl -fLo $linuxdeploy https://github.com/TheAssassin/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage chmod +x $linuxdeploy pushd bin $linuxdeploy --appimage-extract-and-run --appdir install/ --output appimage --desktop-file install/usr/share/applications/openrct2.desktop diff --git a/scripts/build-installer b/scripts/build-installer index 49101bf4a5..2f2fb5adff 100755 --- a/scripts/build-installer +++ b/scripts/build-installer @@ -1,5 +1,5 @@ -#!/bin/bash -set -e +#!/bin/bash -e + if [[ "$#" -gt 2 || "$1" == "-h" ]]; then echo 'Create a Windows installer for OpenRCT2' echo '' diff --git a/scripts/build-portable b/scripts/build-portable index d1180b9dd5..bd4460cfa1 100755 --- a/scripts/build-portable +++ b/scripts/build-portable @@ -1,5 +1,4 @@ -#!/bin/bash -set -e +#!/bin/bash -e if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]]; then # Create a Windows symbols archive for OpenRCT2 diff --git a/scripts/build-symbols b/scripts/build-symbols index d3e28e446b..5fede436c6 100755 --- a/scripts/build-symbols +++ b/scripts/build-symbols @@ -1,5 +1,14 @@ -#!/bin/bash -set -e +#!/bin/bash -e + +# Check 7z or zip is available +if [ -x "$(command -v 7z)" ]; then + archiver="7z a" +elif [ -x "$(command -v zip)" ]; then + archiver=zip +else + echo -e >&2 "\033[0;7z and zip not found\033[0m" + exit 1 +fi # Create a Windows symbols archive for OpenRCT2 basedir="$(readlink -f `dirname $0`/..)" @@ -7,17 +16,11 @@ cd $basedir/bin destination=../artifacts/openrct2-symbols-$CONFIGURATION-$PLATFORM.zip -# Check 7z is available -if ! [ -x "$(command -v 7z)" ]; then - echo -e >&2 "\033[0;7z not found\033[0m" - exit 1 -fi - echo -e "\033[0;36mCreating symbols archive for OpenRCT2...\033[0m" if [[ -f $destination ]]; then rm $destination fi -7z a $destination openrct2.exe openrct2.com openrct2-win.pdb +$archiver $destination openrct2.exe openrct2.com openrct2-win.pdb destination=$(cygpath -w $(readlink -f $destination)) printf '\033[0;32m%s\033[0m\n' "${destination} created successfully" diff --git a/scripts/check-code-formatting b/scripts/check-code-formatting index 04cc0e1a0d..86c2e64b22 100755 --- a/scripts/check-code-formatting +++ b/scripts/check-code-formatting @@ -1,5 +1,4 @@ -#!/bin/sh -set -e +#!/bin/sh -e readlink_bin='readlink' diff --git a/scripts/get-discord-rpc b/scripts/get-discord-rpc index 1305efacb2..cd785ff567 100755 --- a/scripts/get-discord-rpc +++ b/scripts/get-discord-rpc @@ -1,5 +1,5 @@ -#!/bin/bash -set -e +#!/bin/bash -e + if [[ $(uname) == "Linux" ]]; then basedir="$(readlink -f `dirname $0`/..)" elif [[ $(uname) == "Darwin" ]]; then @@ -10,5 +10,5 @@ else fi cd $basedir -git clone https://github.com/discordapp/discord-rpc -b v3.4.0 -git clone https://github.com/janisozaur/rapidjson discord-rpc/thirdparty/rapidjson -b patch-1 +git clone --depth 1 -b v3.4.0 https://github.com/discordapp/discord-rpc +git clone --depth 1 -b patch-1 https://github.com/janisozaur/rapidjson discord-rpc/thirdparty/rapidjson diff --git a/scripts/install-nsis b/scripts/install-nsis index 43a1ec2029..a31d6e3d18 100755 --- a/scripts/install-nsis +++ b/scripts/install-nsis @@ -1,5 +1,5 @@ -#!/bin/bash -set -e +#!/bin/bash -e + if [[ "$#" -ne 0 && "$#" -ne 2 ]]; then echo 'Install a portable version of NSIS which can build the OpenRCT2 Windows installer.' echo '' @@ -11,7 +11,7 @@ fi if [[ "$1" == "-d" ]]; then echo -e "\033[0;36mDownloading prebuilt NSIS from GitHub...\033[0m" - curl -sLo nsis.zip "https://github.com/OpenRCT2/Dependencies/releases/download/v20/nsis.zip" + curl -sSfLO "https://github.com/OpenRCT2/Dependencies/releases/download/v20/nsis.zip" 7z -bd -y "-o$2" x nsis.zip rm nsis.zip echo -e "\033[0;32mNSIS downloaded, add "$2/bin" to PATH\033[0m" @@ -19,7 +19,7 @@ if [[ "$1" == "-d" ]]; then fi # Download NSIS with chocolatey and then download extra plugins -nsisdir="C:/ProgramData/chocolatey/lib/nsis.portable" +nsisdir="$ProgramData/chocolatey/lib/nsis.portable" if [[ -d $nsisdir ]] then echo -e "\033[0;36mNSIS already installed.\033[0m" @@ -30,13 +30,13 @@ echo -e "\033[0;36mDownloading NSIS from chocolatey...\033[0m" cinst nsis.portable --version=3.01-beta1 echo -e "\033[0;36mDownloading KillProcDLL for NSIS...\033[0m" -curl -sLo nsisxtra.zip "http://nsis.sourceforge.net/mediawiki/images/5/53/KillProcDll%26FindProcDll.zip" +curl -sSfLo nsisxtra.zip "http://nsis.sourceforge.net/mediawiki/images/5/53/KillProcDll%26FindProcDll.zip" 7z x nsisxtra.zip cp FindProcDLL.dll "$nsisdir/tools/nsis-3.0b1/Plugins/x86-ansi" echo -e "\033[0;36mDownloading UAC plugin for NSIS...\033[0m" -curl -sLo uac.zip "http://nsis.sourceforge.net/mediawiki/images/8/8f/UAC.zip" -7z x uac.zip +curl -sSfLO "http://nsis.sourceforge.net/mediawiki/images/8/8f/UAC.zip" +7z x UAC.zip cp UAC.nsh "$nsisdir/tools/nsis-3.0b1/Include" cp -r Plugins "$nsisdir/tools/nsis-3.0b1" diff --git a/scripts/linux/build-appimage-docker.sh b/scripts/linux/build-appimage-docker.sh index 8ac54e010a..cde760edf4 100755 --- a/scripts/linux/build-appimage-docker.sh +++ b/scripts/linux/build-appimage-docker.sh @@ -1,12 +1,10 @@ -#! /bin/bash - -set -ex +#!/bin/bash -ex REPO_ROOT=$(readlink -f $(dirname "$0")/../..) -docker run --rm -it -e NO_CLEANUP=1 -e CI=1 --device /dev/fuse:mrw -v $(readlink -f .):/ws openrct2/openrct2:ubuntu_amd64 bash -xc " +docker run --rm -it -e NO_CLEANUP=1 -e CI=1 --device /dev/fuse:mrw -v $(readlink -f .):/ws openrct2/openrct2:ubuntu_amd64 bash -exc " cd /ws apt-get update apt-get install -y wget libcairo2 -bash -xe scripts/linux/build-appimage.sh +scripts/linux/build-appimage.sh " diff --git a/scripts/linux/build-appimage.sh b/scripts/linux/build-appimage.sh index fd0da9511a..6d2b1529c7 100755 --- a/scripts/linux/build-appimage.sh +++ b/scripts/linux/build-appimage.sh @@ -1,7 +1,4 @@ -#! /bin/bash - -set -e -set -x +#!/bin/bash -ex # use RAM disk if possible if [ "$CI" == "" ] && [ -d /dev/shm ]; then @@ -18,7 +15,7 @@ cleanup () { fi } -[ "$NO_CLEANUP" == "" ] && trap cleanup EXIT +if [ "$NO_CLEANUP" == "" ] && trap cleanup EXIT # store repo root as variable REPO_ROOT=$(readlink -f $(dirname "$0")/../..) diff --git a/scripts/linux/build.sh b/scripts/linux/build.sh deleted file mode 100755 index bbc323b687..0000000000 --- a/scripts/linux/build.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash - -set -e - -if [[ $TRAVIS != "true" ]] -then - echo This script is only meant to be run on Travis-CI. - echo Please use CMake to build the project. - exit 1 -fi - -cachedir=.cache -mkdir -p $cachedir - -ci_env=`bash <(curl -s https://codecov.io/env)` - -# Sets default target to "linux", if none specified -TARGET=${TARGET-linux} - -if [[ ! -d build ]]; then - mkdir -p build -fi - -PARENT=$(readlink -f ./) -chmod -R a+rwX "$(pwd)" -chmod -R g+s "$(pwd)" - -pushd build - echo OPENRCT2_CMAKE_OPTS = "$OPENRCT2_CMAKE_OPTS" - if [[ $TARGET == "docker64" ]] - then - # CMAKE and MAKE opts from environment - docker run $ci_env -e CCACHE_DIR=/ccache -v $HOME/.ccache:/ccache -v "$PARENT":"$PARENT" -w "$PARENT"/build -i -t openrct2/openrct2:64bit-only bash -c "export PATH=/usr/lib/ccache/bin:\$PATH LD_PRELOAD=/usr/lib/libSegFault.so && ccache --show-stats > ccache_before && cmake ../ -DWITH_TESTS=on $OPENRCT2_CMAKE_OPTS && ninja all install $OPENRCT2_MAKE_OPTS && ccache --show-stats > ccache_after && ( diff -U100 ccache_before ccache_after || true ) && ./openrct2-cli scan-objects && ctest --output-on-failure && cd .. && bash <(curl -s https://codecov.io/bash) 2>\&1 | grep -v \"has arcs\"" - elif [[ $TARGET == "ubuntu_i686" ]] - then - # CMAKE and MAKE opts from environment - docker run $ci_env -e CCACHE_DIR=/ccache -v $HOME/.ccache:/ccache -v "$PARENT":"$PARENT" -w "$PARENT"/build -i -t openrct2/openrct2:ubuntu_i686 bash -c "export PATH=/usr/lib/ccache:\$PATH && ccache --show-stats > ccache_before && cmake ../ -DWITH_TESTS=on $OPENRCT2_CMAKE_OPTS && ninja all testpaint install $OPENRCT2_MAKE_OPTS && ccache --show-stats > ccache_after && ( diff -U100 ccache_before ccache_after || true ) && LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so ./openrct2-cli scan-objects && LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so ctest --output-on-failure && ( LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so ./testpaint --quiet || if [[ \$? -eq 1 ]] ; then echo Allowing failed tests to pass ; else echo here ; false; fi ) && cd .. && bash <(curl -s https://codecov.io/bash)" - elif [[ $TARGET == "ubuntu_amd64" ]] - then - # CMAKE and MAKE opts from environment - docker run $ci_env -e CCACHE_DIR=/ccache -v $HOME/.ccache:/ccache -v "$PARENT":"$PARENT" -w "$PARENT"/build -i -t openrct2/openrct2:ubuntu_amd64 bash -c "export PATH=/usr/lib/ccache:\$PATH LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so && ccache --show-stats > ccache_before && cmake ../ -DWITH_TESTS=on $OPENRCT2_CMAKE_OPTS && ninja $OPENRCT2_MAKE_OPTS install && ccache --show-stats > ccache_after && ( diff -U100 ccache_before ccache_after || true ) && ./openrct2-cli scan-objects && ctest --output-on-failure && cd .. && bash <(curl -s https://codecov.io/bash)" - elif [[ $TARGET == "windows" ]] - then - # CMAKE and MAKE opts from environment - docker run -v "$PARENT":"$PARENT" -w "$PARENT"/build -i -t openrct2/openrct2:mingw-arch bash -c "cmake ../ $OPENRCT2_CMAKE_OPTS && ninja $OPENRCT2_MAKE_OPTS" - else - echo "Unknown target $TARGET" - exit 1 - fi -popd - -if [[ $TARGET == "windows" ]]; then - if [[ ! -h openrct2.dll ]]; then - ln -s build/openrct2.dll openrct2.dll - fi -fi - -if [[ ! -h build/data ]]; then - ln -s ../data build/data -fi - -if [[ $TARGET == "ubuntu_i686" ]]; then - if [[ ! -h openrct2 ]]; then - ln -s build/openrct2 openrct2 - fi -fi - -if [[ -z "$DISABLE_G2_BUILD" ]]; then - echo Building: g2.dat - pushd build - ninja g2 - popd -fi - -if [[ $TARGET == "windows" ]]; then - if [[ -t 1 ]]; then - echo -e "\nDone! Run OpenRCT2 by typing:\n\n\033[95mwine openrct2.exe\n\033[0m" - else - echo -e "\nDone! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n" - fi -else - if [[ -t 1 ]]; then - echo -e "\nDone! Run OpenRCT2 by typing:\n\n\033[95m./openrct2\n\033[0m" - else - echo -e "\nDone! Run OpenRCT2 by typing:\n\n./openrct2\n" - fi -fi diff --git a/scripts/linux/clean.sh b/scripts/linux/clean.sh deleted file mode 100755 index 91bf63302b..0000000000 --- a/scripts/linux/clean.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -ev - -if [[ $TRAVIS != "true" ]] -then - echo This script is only meant to be run on Travis-CI. - echo Please use CMake to build the project. - exit 1 -fi - - -sudo rm -rf /usr/local/cross-tools/i686-w64-mingw32 -sudo rm -rf /usr/local/cross-tools/orcalibs -sudo rm -rf /usr/local/cross-tools/orctlibs -rm -rf .cache -rm -rf build diff --git a/scripts/linux/install.sh b/scripts/linux/install.sh deleted file mode 100755 index 438fd0a7b0..0000000000 --- a/scripts/linux/install.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/bin/bash - -if [[ $TRAVIS != "true" ]] -then - echo This script is only meant to be run on Travis-CI. - echo Please use CMake to build the project. - exit 1 -fi - -cachedir=.cache -if [[ $(uname -s) == "Darwin" ]]; then - liburl=https://openrct2.io/files/orctlibs-osx.zip -else - liburl=https://openrct2.io/files/orctlibs.zip -fi -mkdir -p "$cachedir" - -# Sets default target to "ubuntu_amd64", if none specified -TARGET=${TARGET-ubuntu_amd64} - -function has_cmd { - command -v "$1" >/dev/null 2>&1 -} - -function calculate_sha256 { - if has_cmd "shasum"; then - command shasum -a 256 "$1" | cut -f1 -d" " - elif has_cmd "sha256sum"; then - command sha256sum "$1" | cut -f1 -d" " - else - echo "Please install either sha256sum or shasum to continue" - exit 1 - fi -} - -function download { - if has_cmd "curl"; then - curl -L -o "$2" "$1" - elif has_cmd "wget"; then - wget -O "$2" "$1" - else - echo "Please install either wget or curl to continue" - exit 1 - fi -} - -function download_libs { - if [[ ! -f $cachedir/orctlibs.zip ]]; then - download $liburl $cachedir/orctlibs.zip; - fi - if [[ ! -d $cachedir/orctlibs ]]; then - mkdir -p $cachedir/orctlibs - pushd $cachedir/orctlibs - unzip -uaq ../orctlibs.zip - popd - fi -} - -function mac_os_install_mingw_32 { - local mingw_name="mingw-w32-bin_i686-darwin" - local mingw_tar="${mingw_name}_20130531.tar.bz2" - local mingw_path="/usr/local/$mingw_name" - - if [[ ! -f "$cachedir/$mingw_tar" ]]; then - download "https://downloads.sourceforge.net/project/mingw-w64/Toolchains targetting Win32/Automated Builds/$mingw_tar" "$cachedir/$mingw_tar" - fi - - if [[ ! -d "$mingw_path" ]]; then - echo "Extracting contents of $mingw_tar to $mingw_path" - echo "Don't forget to add $mingw_path/bin to your PATH variable!" - - mkdir "$mingw_path" - tar -xyf "$cachedir/$mingw_tar" -C "$mingw_path" - - pushd "$mingw_path" - find . -type d -exec chmod 755 {} \; - popd - fi -} - -echo "HOST = $(uname)" -echo "TARGET = $TARGET" - -if [[ "$(uname)" == "Darwin" ]]; then - if ! has_cmd "brew"; then - echo "Homebrew is not installed, or brew is not in your \$PATH" - echo "install instructions: http://brew.sh/" - exit 1 - fi - - brew install cmake - - if [[ $TARGET == "windows" ]]; then - brew install wine - mac_os_install_mingw_32 - else - brew install jansson sdl2 speex --universal - fi -elif [[ $(uname) == "Linux" ]]; then - # Clone discord-rpc for Discord's Rich Presence support - # Use tagged release to prevent upstream changes from breaking our code - git clone https://github.com/IntelOrca/discord-rpc -b fix/134-iothreadholder - # Use rapidjson with a hack for GCC 8, while awaiting a fix upstream: - # https://github.com/Tencent/rapidjson/issues/1205 - git clone https://github.com/janisozaur/rapidjson discord-rpc/thirdparty/rapidjson -b patch-1 - # prevent build.sh from re-doing all the steps again - case "$TARGET" in - "ubuntu_i686") - docker pull openrct2/openrct2:ubuntu_i686 - ;; - "ubuntu_amd64") - docker pull openrct2/openrct2:ubuntu_amd64 - ;; - "windows") - docker pull openrct2/openrct2:mingw-arch - ;; - "docker64") - docker pull openrct2/openrct2:64bit-only - ;; - *) - echo "unkown target $TARGET" - exit 1 - esac -fi - -if [[ $(uname -s) == "Darwin" ]]; then - download_libs - calculate_sha256 "$cachedir/orctlibs.zip" > "$libVFile" - echo "Downloaded library with sha256sum: $(cat "$libVFile")" - # Local libs are required for all targets -# $(uname -s) == "Darwin" -fi diff --git a/scripts/run-clang-format.py b/scripts/run-clang-format.py index 8f88bfc462..df3c498488 100755 --- a/scripts/run-clang-format.py +++ b/scripts/run-clang-format.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 + """A wrapper script around clang-format, suitable for linting multiple files and to use for continuous integration. diff --git a/scripts/run-testpaint b/scripts/run-testpaint index 479640a7ad..de0968afc3 100755 --- a/scripts/run-testpaint +++ b/scripts/run-testpaint @@ -1,5 +1,4 @@ -#!/bin/bash -set -e +#!/bin/bash -e # Ensure we are in root directory basedir="$(readlink -f `dirname $0`/..)" diff --git a/scripts/run-tests b/scripts/run-tests index 4317a8c1fd..e02f7d926b 100755 --- a/scripts/run-tests +++ b/scripts/run-tests @@ -1,5 +1,4 @@ -#!/bin/bash -set -e +#!/bin/bash -e # Ensure we are in root directory if [[ $(uname) == "Darwin" ]]; then diff --git a/scripts/setenv b/scripts/setenv index b7791237e2..fd9796599b 100755 --- a/scripts/setenv +++ b/scripts/setenv @@ -22,10 +22,10 @@ get_build_number() export OPENRCT2_BUILD=$(get_build_number) # Get the name of the branch and decide whether we should push the build to openrct2.org -export OPENRCT2_TAG= -export OPENRCT2_PUSH= +unset OPENRCT2_TAG +unset OPENRCT2_PUSH if [[ $GITHUB_REF == refs/tags/* ]]; then - export OPENRCT2_BRANCH= + unset OPENRCT2_BRANCH export OPENRCT2_TAG=true export OPENRCT2_PUSH=true else @@ -35,13 +35,13 @@ else fi fi if [[ "$OPENRCT2_ORG_TOKEN" == "" ]]; then - export OPENRCT2_PUSH= + unset OPENRCT2_PUSH fi # Get the short SHA1 export OPENRCT2_SHA1=$GITHUB_SHA export OPENRCT2_SHA1_SHORT=${OPENRCT2_SHA1:0:7} -export OPENRCT2_VERSION_EXTRA= +unset OPENRCT2_VERSION_EXTRA if [[ "$OPENRCT2_TAG" != "true" ]]; then export OPENRCT2_VERSION_EXTRA=$OPENRCT2_BRANCH-$OPENRCT2_SHA1_SHORT fi diff --git a/scripts/stats/count-rct-globals.php b/scripts/stats/count-rct-globals.php index ea04033d53..99ae2f901b 100755 --- a/scripts/stats/count-rct-globals.php +++ b/scripts/stats/count-rct-globals.php @@ -1,4 +1,5 @@ #!/usr/bin/env php + Date: Wed, 14 Apr 2021 14:31:10 +0200 Subject: [PATCH 22/45] Move some globals to Footpath window --- src/openrct2-ui/windows/EditorMain.cpp | 2 +- src/openrct2-ui/windows/Footpath.cpp | 94 ++++++++++++++------------ src/openrct2-ui/windows/Main.cpp | 2 +- src/openrct2-ui/windows/Window.h | 1 + src/openrct2/world/Footpath.cpp | 5 -- src/openrct2/world/Footpath.h | 5 -- 6 files changed, 55 insertions(+), 54 deletions(-) diff --git a/src/openrct2-ui/windows/EditorMain.cpp b/src/openrct2-ui/windows/EditorMain.cpp index d014972adc..b7f22b4a62 100644 --- a/src/openrct2-ui/windows/EditorMain.cpp +++ b/src/openrct2-ui/windows/EditorMain.cpp @@ -48,7 +48,7 @@ rct_window* window_editor_main_open() gShowGridLinesRefCount = 0; gShowLandRightsRefCount = 0; gShowConstuctionRightsRefCount = 0; - gFootpathSelectedType = 0; + window_footpath_reset_selected_path(); context_open_window(WC_TOP_TOOLBAR); context_open_window_view(WV_EDITOR_BOTTOM_TOOLBAR); diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index bafcfb616f..8f758ad743 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -30,6 +30,11 @@ static constexpr const int32_t WH = 381; static constexpr const int32_t WW = 106; static constexpr const uint16_t ARROW_PULSE_DURATION = 200; +static uint8_t _footpathSelectedType; +static uint8_t _footpathConstructDirection; +static uint8_t _footpathConstructValidDirections; +static uint8_t _footpathConstructionMode; + // clang-format off enum { @@ -217,7 +222,7 @@ rct_window* window_footpath_open() show_gridlines(); tool_cancel(); - gFootpathConstructionMode = PATH_CONSTRUCTION_MODE_LAND; + _footpathConstructionMode = PATH_CONSTRUCTION_MODE_LAND; tool_set(window, WIDX_CONSTRUCT_ON_LAND, Tool::PathDown); input_set_flag(INPUT_FLAG_6, true); _footpathErrorOccured = false; @@ -258,7 +263,7 @@ static void window_footpath_mouseup(rct_window* w, rct_widgetindex widgetIndex) window_footpath_remove(); break; case WIDX_CONSTRUCT_ON_LAND: - if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND) + if (_footpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND) { break; } @@ -268,14 +273,14 @@ static void window_footpath_mouseup(rct_window* w, rct_widgetindex widgetIndex) footpath_provisional_update(); map_invalidate_map_selection_tiles(); gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT; - gFootpathConstructionMode = PATH_CONSTRUCTION_MODE_LAND; + _footpathConstructionMode = PATH_CONSTRUCTION_MODE_LAND; tool_set(w, WIDX_CONSTRUCT_ON_LAND, Tool::PathDown); input_set_flag(INPUT_FLAG_6, true); _footpathErrorOccured = false; window_footpath_set_enabled_and_pressed_widgets(); break; case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL: - if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) + if (_footpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) { break; } @@ -285,7 +290,7 @@ static void window_footpath_mouseup(rct_window* w, rct_widgetindex widgetIndex) footpath_provisional_update(); map_invalidate_map_selection_tiles(); gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT; - gFootpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL; + _footpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL; tool_set(w, WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, Tool::Crosshair); input_set_flag(INPUT_FLAG_6, true); _footpathErrorOccured = false; @@ -340,11 +345,11 @@ static void window_footpath_dropdown(rct_window* w, rct_widgetindex widgetIndex, { if (widgetIndex == WIDX_FOOTPATH_TYPE) { - gFootpathSelectedType = SELECTED_PATH_TYPE_NORMAL; + _footpathSelectedType = SELECTED_PATH_TYPE_NORMAL; } else if (widgetIndex == WIDX_QUEUELINE_TYPE) { - gFootpathSelectedType = SELECTED_PATH_TYPE_QUEUE; + _footpathSelectedType = SELECTED_PATH_TYPE_QUEUE; } else { @@ -454,7 +459,7 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* { int32_t type, slope; - if (gFootpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) + if (_footpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) { return; } @@ -486,7 +491,7 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* CoordsXYZ footpathLoc; footpath_get_next_path_info(&type, footpathLoc, &slope); gMapSelectArrowPosition = footpathLoc; - gMapSelectArrowDirection = gFootpathConstructDirection; + gMapSelectArrowDirection = _footpathConstructDirection; if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW) { gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW; @@ -517,7 +522,7 @@ static void window_footpath_update(rct_window* w) } // Check tool - if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND) + if (_footpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND) { if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE))) { @@ -532,7 +537,7 @@ static void window_footpath_update(rct_window* w) window_close(w); } } - else if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) + else if (_footpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) { if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE))) { @@ -558,11 +563,11 @@ static void window_footpath_invalidate(rct_window* w) // Press / unpress footpath and queue type buttons w->pressed_widgets &= ~(1 << WIDX_FOOTPATH_TYPE); w->pressed_widgets &= ~(1 << WIDX_QUEUELINE_TYPE); - w->pressed_widgets |= gFootpathSelectedType == SELECTED_PATH_TYPE_NORMAL ? (1 << WIDX_FOOTPATH_TYPE) + w->pressed_widgets |= _footpathSelectedType == SELECTED_PATH_TYPE_NORMAL ? (1 << WIDX_FOOTPATH_TYPE) : (1 << WIDX_QUEUELINE_TYPE); // Enable / disable construct button - window_footpath_widgets[WIDX_CONSTRUCT].type = gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL + window_footpath_widgets[WIDX_CONSTRUCT].type = _footpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL ? WindowWidgetType::ImgBtn : WindowWidgetType::Empty; @@ -592,7 +597,7 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT))) { // Get construction image - uint8_t direction = (gFootpathConstructDirection + get_current_rotation()) % 4; + uint8_t direction = (_footpathConstructDirection + get_current_rotation()) % 4; uint8_t slope = 0; if (gFootpathConstructSlope == 2) { @@ -604,7 +609,7 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) } int32_t image = ConstructionPreviewImages[slope][direction]; - int32_t selectedPath = gFootpathSelectedId + (MAX_PATH_OBJECTS * gFootpathSelectedType); + int32_t selectedPath = gFootpathSelectedId + (MAX_PATH_OBJECTS * _footpathSelectedType); PathSurfaceEntry* pathType = get_path_surface_entry(selectedPath); image += pathType->image; @@ -683,7 +688,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget static void window_footpath_mousedown_direction(int32_t direction) { footpath_provisional_update(); - gFootpathConstructDirection = (direction - get_current_rotation()) & 3; + _footpathConstructDirection = (direction - get_current_rotation()) & 3; _window_footpath_cost = MONEY32_UNDEFINED; window_footpath_set_enabled_and_pressed_widgets(); } @@ -769,7 +774,7 @@ static void window_footpath_set_provisional_path_at_point(const ScreenCoordsXY& slope &= ~RAISE_FOOTPATH_FLAG; z += PATH_HEIGHT_STEP; } - int32_t pathType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); + int32_t pathType = (_footpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); _window_footpath_cost = footpath_provisional_set(pathType, { info.Loc, z }, slope); window_invalidate_by_class(WC_FOOTPATH); @@ -864,7 +869,7 @@ static void window_footpath_place_path_at_point(const ScreenCoordsXY& screenCoor slope &= ~RAISE_FOOTPATH_FLAG; z += PATH_HEIGHT_STEP; } - auto selectedType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); + auto selectedType = (_footpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); // Try and place path gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE; @@ -935,11 +940,11 @@ static void window_footpath_start_bridge_at_point(const ScreenCoordsXY& screenCo tool_cancel(); gFootpathConstructFromPosition = { mapCoords, z }; - gFootpathConstructDirection = direction; + _footpathConstructDirection = direction; gFootpathProvisionalFlags = 0; gFootpathConstructSlope = 0; - gFootpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL; - gFootpathConstructValidDirections = INVALID_DIRECTION; + _footpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL; + _footpathConstructValidDirections = INVALID_DIRECTION; window_footpath_set_enabled_and_pressed_widgets(); } @@ -957,7 +962,7 @@ static void window_footpath_construct() footpath_get_next_path_info(&type, footpathLoc, &slope); gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE; - auto footpathPlaceAction = FootpathPlaceAction(footpathLoc, slope, type, gFootpathConstructDirection); + auto footpathPlaceAction = FootpathPlaceAction(footpathLoc, slope, type, _footpathConstructDirection); footpathPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) { if (result->Error == GameActions::Status::Ok) { @@ -965,11 +970,11 @@ static void window_footpath_construct() if (gFootpathConstructSlope == 0) { - gFootpathConstructValidDirections = INVALID_DIRECTION; + _footpathConstructValidDirections = INVALID_DIRECTION; } else { - gFootpathConstructValidDirections = gFootpathConstructDirection; + _footpathConstructValidDirections = _footpathConstructDirection; } if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND) @@ -1002,14 +1007,14 @@ static void footpath_remove_tile_element(TileElement* tileElement) { uint8_t slopeDirection = tileElement->AsPath()->GetSlopeDirection(); slopeDirection = direction_reverse(slopeDirection); - if (slopeDirection == gFootpathConstructDirection) + if (slopeDirection == _footpathConstructDirection) { z += PATH_HEIGHT_STEP; } } // Find a connected edge - int32_t edge = direction_reverse(gFootpathConstructDirection); + int32_t edge = direction_reverse(_footpathConstructDirection); if (!(tileElement->AsPath()->GetEdges() & (1 << edge))) { edge = (edge + 1) & 3; @@ -1036,8 +1041,8 @@ static void footpath_remove_tile_element(TileElement* tileElement) gFootpathConstructFromPosition.x -= CoordsDirectionDelta[edge].x; gFootpathConstructFromPosition.y -= CoordsDirectionDelta[edge].y; gFootpathConstructFromPosition.z = z; - gFootpathConstructDirection = edge; - gFootpathConstructValidDirections = INVALID_DIRECTION; + _footpathConstructDirection = edge; + _footpathConstructValidDirections = INVALID_DIRECTION; } /** @@ -1068,7 +1073,7 @@ static TileElement* footpath_get_tile_element_to_remove() { if (tileElement->AsPath()->IsSloped()) { - if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != gFootpathConstructDirection) + if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != _footpathConstructDirection) { continue; } @@ -1080,7 +1085,7 @@ static TileElement* footpath_get_tile_element_to_remove() { if (!tileElement->AsPath()->IsSloped()) { - if ((tileElement->AsPath()->GetSlopeDirection()) == gFootpathConstructDirection) + if ((tileElement->AsPath()->GetSlopeDirection()) == _footpathConstructDirection) { continue; } @@ -1126,13 +1131,13 @@ static void window_footpath_set_enabled_and_pressed_widgets() return; } - if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) + if (_footpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) { map_invalidate_map_selection_tiles(); gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_CONSTRUCT; gMapSelectFlags |= MAP_SELECT_FLAG_GREEN; - int32_t direction = gFootpathConstructDirection; + int32_t direction = _footpathConstructDirection; gMapSelectionTiles.clear(); gMapSelectionTiles.push_back({ gFootpathConstructFromPosition.x + CoordsDirectionDelta[direction].x, gFootpathConstructFromPosition.y + CoordsDirectionDelta[direction].y }); @@ -1144,10 +1149,10 @@ static void window_footpath_set_enabled_and_pressed_widgets() | (1LL << WIDX_SLOPEDOWN) | (1LL << WIDX_LEVEL) | (1LL << WIDX_SLOPEUP)); uint64_t disabledWidgets = 0; int32_t currentRotation = get_current_rotation(); - if (gFootpathConstructionMode >= PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) + if (_footpathConstructionMode >= PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) { // Set pressed directional widget - int32_t direction = (gFootpathConstructDirection + currentRotation) & 3; + int32_t direction = (_footpathConstructDirection + currentRotation) & 3; pressedWidgets |= (1LL << (WIDX_DIRECTION_NW + direction)); // Set pressed slope widget @@ -1166,7 +1171,7 @@ static void window_footpath_set_enabled_and_pressed_widgets() } // Enable / disable directional widgets - direction = gFootpathConstructValidDirections; + direction = _footpathConstructValidDirections; if (direction != INVALID_DIRECTION) { disabledWidgets |= (1 << WIDX_DIRECTION_NW) | (1 << WIDX_DIRECTION_NE) | (1 << WIDX_DIRECTION_SW) @@ -1197,15 +1202,15 @@ static void footpath_get_next_path_info(int32_t* type, CoordsXYZ& footpathLoc, i { int32_t direction; - direction = gFootpathConstructDirection; + direction = _footpathConstructDirection; footpathLoc.x = gFootpathConstructFromPosition.x + CoordsDirectionDelta[direction].x; footpathLoc.y = gFootpathConstructFromPosition.y + CoordsDirectionDelta[direction].y; footpathLoc.z = gFootpathConstructFromPosition.z; - *type = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); + *type = (_footpathSelectedType << 7) + (gFootpathSelectedId & 0xFF); *slope = TILE_ELEMENT_SLOPE_FLAT; if (gFootpathConstructSlope != 0) { - *slope = gFootpathConstructDirection | TILE_ELEMENT_SLOPE_S_CORNER_UP; + *slope = _footpathConstructDirection | TILE_ELEMENT_SLOPE_S_CORNER_UP; if (gFootpathConstructSlope != 2) { footpathLoc.z -= PATH_HEIGHT_STEP; @@ -1247,12 +1252,12 @@ void window_footpath_keyboard_shortcut_turn_left() { rct_window* w = window_find_by_class(WC_FOOTPATH); if (w == nullptr || WidgetIsDisabled(w, WIDX_DIRECTION_NW) || WidgetIsDisabled(w, WIDX_DIRECTION_NE) - || WidgetIsDisabled(w, WIDX_DIRECTION_SW) || WidgetIsDisabled(w, WIDX_DIRECTION_SE) || gFootpathConstructionMode != 2) + || WidgetIsDisabled(w, WIDX_DIRECTION_SW) || WidgetIsDisabled(w, WIDX_DIRECTION_SE) || _footpathConstructionMode != 2) { return; } int32_t currentRotation = get_current_rotation(); - int32_t turnedRotation = gFootpathConstructDirection - currentRotation + (currentRotation % 2 == 1 ? 1 : -1); + int32_t turnedRotation = _footpathConstructDirection - currentRotation + (currentRotation % 2 == 1 ? 1 : -1); window_footpath_mousedown_direction(turnedRotation); } @@ -1260,12 +1265,12 @@ void window_footpath_keyboard_shortcut_turn_right() { rct_window* w = window_find_by_class(WC_FOOTPATH); if (w == nullptr || WidgetIsDisabled(w, WIDX_DIRECTION_NW) || WidgetIsDisabled(w, WIDX_DIRECTION_NE) - || WidgetIsDisabled(w, WIDX_DIRECTION_SW) || WidgetIsDisabled(w, WIDX_DIRECTION_SE) || gFootpathConstructionMode != 2) + || WidgetIsDisabled(w, WIDX_DIRECTION_SW) || WidgetIsDisabled(w, WIDX_DIRECTION_SE) || _footpathConstructionMode != 2) { return; } int32_t currentRotation = get_current_rotation(); - int32_t turnedRotation = gFootpathConstructDirection - currentRotation + (currentRotation % 2 == 1 ? -1 : 1); + int32_t turnedRotation = _footpathConstructDirection - currentRotation + (currentRotation % 2 == 1 ? -1 : 1); window_footpath_mousedown_direction(turnedRotation); } @@ -1337,3 +1342,8 @@ void window_footpath_keyboard_shortcut_build_current() window_event_mouse_up_call(w, WIDX_CONSTRUCT); } + +void window_footpath_reset_selected_path() +{ + _footpathSelectedType = 0; +} diff --git a/src/openrct2-ui/windows/Main.cpp b/src/openrct2-ui/windows/Main.cpp index c4f976765e..7e698b6750 100644 --- a/src/openrct2-ui/windows/Main.cpp +++ b/src/openrct2-ui/windows/Main.cpp @@ -48,7 +48,7 @@ rct_window* window_main_open() gShowGridLinesRefCount = 0; gShowLandRightsRefCount = 0; gShowConstuctionRightsRefCount = 0; - gFootpathSelectedType = 0; + window_footpath_reset_selected_path(); return window; } diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 2b727b62cd..7d6d074207 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -47,6 +47,7 @@ rct_window* window_editor_main_open(); rct_window* window_editor_objective_options_open(); rct_window* window_editor_scenario_options_open(); rct_window* window_footpath_open(); +void window_footpath_reset_selected_path(); rct_window* window_guest_open(Peep* peep); rct_window* window_land_open(); rct_window* window_land_rights_open(); diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index fcf7e9aa32..1e99af5b0c 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -44,14 +44,9 @@ uint8_t gFootpathProvisionalFlags; CoordsXYZ gFootpathProvisionalPosition; uint8_t gFootpathProvisionalType; uint8_t gFootpathProvisionalSlope; -uint8_t gFootpathConstructionMode; uint16_t gFootpathSelectedId; -uint8_t gFootpathSelectedType; CoordsXYZ gFootpathConstructFromPosition; -uint8_t gFootpathConstructDirection; uint8_t gFootpathConstructSlope; -uint8_t gFootpathConstructValidDirections; -money32 gFootpathPrice; uint8_t gFootpathGroundFlags; static ride_id_t* _footpathQueueChainNext; diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 94435e0f6c..79c9ad5283 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -162,14 +162,9 @@ extern uint8_t gFootpathProvisionalFlags; extern CoordsXYZ gFootpathProvisionalPosition; extern uint8_t gFootpathProvisionalType; extern uint8_t gFootpathProvisionalSlope; -extern uint8_t gFootpathConstructionMode; extern uint16_t gFootpathSelectedId; -extern uint8_t gFootpathSelectedType; extern CoordsXYZ gFootpathConstructFromPosition; -extern uint8_t gFootpathConstructDirection; extern uint8_t gFootpathConstructSlope; -extern uint8_t gFootpathConstructValidDirections; -extern money32 gFootpathPrice; extern uint8_t gFootpathGroundFlags; // Given a direction, this will return how to increase/decrease the x and y coordinates. From 5e28586a1c7439462e83c5f5c129b4a77e446f46 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 14 Apr 2021 14:56:28 +0200 Subject: [PATCH 23/45] Create ProvisionalFootpath struct --- src/openrct2-ui/windows/Footpath.cpp | 16 +++++------ src/openrct2-ui/windows/RideConstruction.cpp | 2 +- src/openrct2/world/Footpath.cpp | 29 +++++++++----------- src/openrct2/world/Footpath.h | 13 ++++++--- src/openrct2/world/Map.cpp | 10 +++---- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 8f758ad743..bde13f05b1 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -465,14 +465,14 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* } // Recheck area for construction. Set by ride_construction window - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_2) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_2) { footpath_provisional_remove(); - gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_2; + gProvisionalFootpath.Flags &= ~PROVISIONAL_PATH_FLAG_2; } // Update provisional bridge mode path - if (!(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1)) + if (!(gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_1)) { CoordsXYZ footpathLoc; footpath_get_next_path_info(&type, footpathLoc, &slope); @@ -487,12 +487,12 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* { _footpathConstructionNextArrowPulse = curTime + ARROW_PULSE_DURATION; - gFootpathProvisionalFlags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW; + gProvisionalFootpath.Flags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW; CoordsXYZ footpathLoc; footpath_get_next_path_info(&type, footpathLoc, &slope); gMapSelectArrowPosition = footpathLoc; gMapSelectArrowDirection = _footpathConstructDirection; - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_SHOW_ARROW) { gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW; } @@ -725,8 +725,8 @@ static void window_footpath_set_provisional_path_at_point(const ScreenCoordsXY& else { // Check for change - if ((gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) - && gFootpathProvisionalPosition == CoordsXYZ{ info.Loc, info.Element->GetBaseZ() }) + if ((gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_1) + && gProvisionalFootpath.Position == CoordsXYZ{ info.Loc, info.Element->GetBaseZ() }) { return; } @@ -941,7 +941,7 @@ static void window_footpath_start_bridge_at_point(const ScreenCoordsXY& screenCo tool_cancel(); gFootpathConstructFromPosition = { mapCoords, z }; _footpathConstructDirection = direction; - gFootpathProvisionalFlags = 0; + gProvisionalFootpath.Flags = 0; gFootpathConstructSlope = 0; _footpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL; _footpathConstructValidDirections = INVALID_DIRECTION; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 28ad735e53..d66407bd92 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -650,7 +650,7 @@ static void window_ride_construction_mouseup(rct_window* w, rct_widgetindex widg case WIDX_CONSTRUCT: window_ride_construction_construct(w); // Force any footpath construction to recheck the area. - gFootpathProvisionalFlags |= PROVISIONAL_PATH_FLAG_2; + gProvisionalFootpath.Flags |= PROVISIONAL_PATH_FLAG_2; break; case WIDX_DEMOLISH: window_ride_construction_mouseup_demolish(w); diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 1e99af5b0c..0008fdd356 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -40,10 +40,7 @@ void footpath_update_queue_entrance_banner(const CoordsXY& footpathPos, TileElement* tileElement); -uint8_t gFootpathProvisionalFlags; -CoordsXYZ gFootpathProvisionalPosition; -uint8_t gFootpathProvisionalType; -uint8_t gFootpathProvisionalSlope; +ProvisionalFootpath gProvisionalFootpath; uint16_t gFootpathSelectedId; CoordsXYZ gFootpathConstructFromPosition; uint8_t gFootpathConstructSlope; @@ -153,10 +150,10 @@ money32 footpath_provisional_set(int32_t type, const CoordsXYZ& footpathLoc, int cost = res->Error == GameActions::Status::Ok ? res->Cost : MONEY32_UNDEFINED; if (res->Error == GameActions::Status::Ok) { - gFootpathProvisionalType = type; - gFootpathProvisionalPosition = footpathLoc; - gFootpathProvisionalSlope = slope; - gFootpathProvisionalFlags |= PROVISIONAL_PATH_FLAG_1; + gProvisionalFootpath.Type = type; + gProvisionalFootpath.Position = footpathLoc; + gProvisionalFootpath.Slope = slope; + gProvisionalFootpath.Flags |= PROVISIONAL_PATH_FLAG_1; if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND) { @@ -180,15 +177,15 @@ money32 footpath_provisional_set(int32_t type, const CoordsXYZ& footpathLoc, int } else if ( gFootpathConstructSlope == TILE_ELEMENT_SLOPE_FLAT - || gFootpathProvisionalPosition.z < gFootpathConstructFromPosition.z) + || gProvisionalFootpath.Position.z < gFootpathConstructFromPosition.z) { // Going either straight on, or down. - virtual_floor_set_height(gFootpathProvisionalPosition.z); + virtual_floor_set_height(gProvisionalFootpath.Position.z); } else { // Going up in the world! - virtual_floor_set_height(gFootpathProvisionalPosition.z + LAND_HEIGHT_STEP); + virtual_floor_set_height(gProvisionalFootpath.Position.z + LAND_HEIGHT_STEP); } } @@ -201,12 +198,12 @@ money32 footpath_provisional_set(int32_t type, const CoordsXYZ& footpathLoc, int */ void footpath_provisional_remove() { - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_1) { - gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_1; + gProvisionalFootpath.Flags &= ~PROVISIONAL_PATH_FLAG_1; footpath_remove( - gFootpathProvisionalPosition, + gProvisionalFootpath.Position, GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); } @@ -218,9 +215,9 @@ void footpath_provisional_remove() */ void footpath_provisional_update() { - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_SHOW_ARROW) { - gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_SHOW_ARROW; + gProvisionalFootpath.Flags &= ~PROVISIONAL_PATH_FLAG_SHOW_ARROW; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; map_invalidate_tile_full(gFootpathConstructFromPosition); diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 79c9ad5283..98318556fd 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -72,6 +72,14 @@ struct PathRailingsEntry uint8_t scrolling_mode; }; +struct ProvisionalFootpath +{ + ObjectEntryIndex Type; + CoordsXYZ Position; + uint8_t Slope; + uint8_t Flags; +}; + // Masks for values stored in TileElement.type enum { @@ -158,10 +166,7 @@ enum FOOTPATH_CONNECTED_MAP_EDGE_IGNORE_NO_ENTRY = (1 << 7) }; -extern uint8_t gFootpathProvisionalFlags; -extern CoordsXYZ gFootpathProvisionalPosition; -extern uint8_t gFootpathProvisionalType; -extern uint8_t gFootpathProvisionalSlope; +extern ProvisionalFootpath gProvisionalFootpath; extern uint16_t gFootpathSelectedId; extern CoordsXYZ gFootpathConstructFromPosition; extern uint8_t gFootpathConstructSlope; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index c11694c9c3..6f312bceb1 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1515,10 +1515,10 @@ void map_update_tiles() void map_remove_provisional_elements() { - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_1) { footpath_provisional_remove(); - gFootpathProvisionalFlags |= PROVISIONAL_PATH_FLAG_1; + gProvisionalFootpath.Flags |= PROVISIONAL_PATH_FLAG_1; } if (window_find_by_class(WC_RIDE_CONSTRUCTION) != nullptr) { @@ -1536,10 +1536,10 @@ void map_remove_provisional_elements() void map_restore_provisional_elements() { - if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) + if (gProvisionalFootpath.Flags & PROVISIONAL_PATH_FLAG_1) { - gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_1; - footpath_provisional_set(gFootpathProvisionalType, gFootpathProvisionalPosition, gFootpathProvisionalSlope); + gProvisionalFootpath.Flags &= ~PROVISIONAL_PATH_FLAG_1; + footpath_provisional_set(gProvisionalFootpath.Type, gProvisionalFootpath.Position, gProvisionalFootpath.Slope); } if (window_find_by_class(WC_RIDE_CONSTRUCTION) != nullptr) { From 084bfe0d48a47360aa17aa28e67ba208f8c7c7f9 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 14 Apr 2021 15:03:09 +0200 Subject: [PATCH 24/45] Remove global from PlaceParkEntranceAction --- src/openrct2-ui/windows/Map.cpp | 2 +- src/openrct2/actions/GameActionCompat.cpp | 2 +- src/openrct2/actions/PlaceParkEntranceAction.cpp | 5 +++-- src/openrct2/actions/PlaceParkEntranceAction.h | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index b57e916f5b..6f23ee8883 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1327,7 +1327,7 @@ static void window_map_place_park_entrance_tool_down(const ScreenCoordsXY& scree CoordsXYZD parkEntrancePosition = place_park_entrance_get_map_position(screenCoords); if (!parkEntrancePosition.isNull()) { - auto gameAction = PlaceParkEntranceAction(parkEntrancePosition); + auto gameAction = PlaceParkEntranceAction(parkEntrancePosition, gFootpathSelectedId); auto result = GameActions::Execute(&gameAction); if (result->Error == GameActions::Status::Ok) { diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index 00c45e2090..15c9cc46e2 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -33,7 +33,7 @@ money32 park_entrance_place_ghost(const CoordsXYZD& entranceLoc) { park_entrance_remove_ghost(); - auto gameAction = PlaceParkEntranceAction(entranceLoc); + auto gameAction = PlaceParkEntranceAction(entranceLoc, gFootpathSelectedId); gameAction.SetFlags(GAME_COMMAND_FLAG_GHOST); auto result = GameActions::Execute(&gameAction); diff --git a/src/openrct2/actions/PlaceParkEntranceAction.cpp b/src/openrct2/actions/PlaceParkEntranceAction.cpp index 661a69e1b9..f2b55f58da 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.cpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.cpp @@ -21,8 +21,9 @@ #include "../world/Sprite.h" #include "../world/Surface.h" -PlaceParkEntranceAction::PlaceParkEntranceAction(const CoordsXYZD& location) +PlaceParkEntranceAction::PlaceParkEntranceAction(const CoordsXYZD& location, ObjectEntryIndex pathType) : _loc(location) + , _pathType(pathType) { } @@ -146,7 +147,7 @@ GameActions::Result::Ptr PlaceParkEntranceAction::Execute() const entranceElement->SetDirection(_loc.direction); entranceElement->SetSequenceIndex(index); entranceElement->SetEntranceType(ENTRANCE_TYPE_PARK_ENTRANCE); - entranceElement->SetPathType(gFootpathSelectedId); + entranceElement->SetPathType(_pathType); if (!entranceElement->IsGhost()) { diff --git a/src/openrct2/actions/PlaceParkEntranceAction.h b/src/openrct2/actions/PlaceParkEntranceAction.h index 2514d3ae1a..5c251c2bc5 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.h +++ b/src/openrct2/actions/PlaceParkEntranceAction.h @@ -15,10 +15,11 @@ DEFINE_GAME_ACTION(PlaceParkEntranceAction, GameCommand::PlaceParkEntrance, Game { private: CoordsXYZD _loc; + ObjectEntryIndex _pathType; public: PlaceParkEntranceAction() = default; - PlaceParkEntranceAction(const CoordsXYZD& location); + PlaceParkEntranceAction(const CoordsXYZD& location, ObjectEntryIndex pathType); uint16_t GetActionFlags() const override; From 3a51145567e70856484a43a26bd0fb4fd684e77f Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 12:34:52 -1000 Subject: [PATCH 25/45] setenv: fix typo (#14477) --- scripts/setenv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setenv b/scripts/setenv index fd9796599b..e34e5fd703 100755 --- a/scripts/setenv +++ b/scripts/setenv @@ -1,6 +1,6 @@ #!/bin/bash -# This sets up more environment variables using existing the environment +# This sets up more environment variables using the existing environment # It should be dot sourced into your environment if [[ "$GITHUB_ACTIONS" != "true" ]]; then export OPENRCT2_BUILD_SERVER=$(hostname) From bbf33b6577701a73681c33f3364badeb5601fdc2 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 15 Apr 2021 21:32:26 +0200 Subject: [PATCH 26/45] Fix serialisation of PlaceParkEntranceAction --- src/openrct2/actions/PlaceParkEntranceAction.cpp | 1 + src/openrct2/network/NetworkBase.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/actions/PlaceParkEntranceAction.cpp b/src/openrct2/actions/PlaceParkEntranceAction.cpp index f2b55f58da..5bb1ac7110 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.cpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.cpp @@ -37,6 +37,7 @@ void PlaceParkEntranceAction::Serialise(DataSerialiser& stream) GameAction::Serialise(stream); stream << DS_TAG(_loc); + stream << DS_TAG(_pathType); } GameActions::Result::Ptr PlaceParkEntranceAction::Query() const diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index d3cc97aba8..53cd7e1afe 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -36,7 +36,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; From d857dca36d9a0deb4005e11436c097682f773b3a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 9 Apr 2021 15:56:32 +0200 Subject: [PATCH 27/45] Replace hardcoded max number of trains per ride --- src/openrct2-ui/windows/Ride.cpp | 4 ++-- src/openrct2/actions/RideCreateAction.cpp | 2 +- src/openrct2/actions/TrackDesignAction.cpp | 9 +++++---- src/openrct2/rct1/T4Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 10 +++++----- src/openrct2/ride/Ride.h | 7 ++++--- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 8472a6b37c..d5ff5f4ac3 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -2702,7 +2702,7 @@ static void window_ride_vehicle_mousedown(rct_window* w, rct_widgetindex widgetI window_ride_show_vehicle_type_dropdown(w, &w->widgets[widgetIndex]); break; case WIDX_VEHICLE_TRAINS_INCREASE: - if (ride->num_vehicles < 32) + if (ride->num_vehicles < MAX_VEHICLES_PER_RIDE) ride->SetNumVehicles(ride->num_vehicles + 1); break; case WIDX_VEHICLE_TRAINS_DECREASE: @@ -2710,7 +2710,7 @@ static void window_ride_vehicle_mousedown(rct_window* w, rct_widgetindex widgetI ride->SetNumVehicles(ride->num_vehicles - 1); break; case WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE: - if (ride->num_cars_per_train < 255) + if (ride->num_cars_per_train < MAX_CARS_PER_TRAIN) ride->SetNumCarsPerVehicle(ride->num_cars_per_train + 1); break; case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE: diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 45498fc432..7b481473a7 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -161,7 +161,7 @@ GameActions::Result::Ptr RideCreateAction::Execute() const ride->num_stations = 0; ride->num_vehicles = 1; ride->proposed_num_vehicles = 32; - ride->max_trains = 32; + ride->max_trains = MAX_VEHICLES_PER_RIDE; ride->num_cars_per_train = 1; ride->proposed_num_cars_per_train = 12; ride->min_waiting_time = 10; diff --git a/src/openrct2/actions/TrackDesignAction.cpp b/src/openrct2/actions/TrackDesignAction.cpp index 9119edb609..e72f07d692 100644 --- a/src/openrct2/actions/TrackDesignAction.cpp +++ b/src/openrct2/actions/TrackDesignAction.cpp @@ -259,11 +259,12 @@ GameActions::Result::Ptr TrackDesignAction::Execute() const ride->track_colour[i].supports = _td.track_support_colour[i]; } - for (int32_t i = 0; i <= MAX_VEHICLES_PER_RIDE; i++) + for (size_t i = 0; i <= MAX_VEHICLES_PER_RIDE; i++) { - ride->vehicle_colours[i].Body = _td.vehicle_colours[i].body_colour; - ride->vehicle_colours[i].Trim = _td.vehicle_colours[i].trim_colour; - ride->vehicle_colours[i].Ternary = _td.vehicle_additional_colour[i]; + auto tdIndex = std::min(i, std::size(_td.vehicle_colours) - 1); + ride->vehicle_colours[i].Body = _td.vehicle_colours[tdIndex].body_colour; + ride->vehicle_colours[i].Trim = _td.vehicle_colours[tdIndex].trim_colour; + ride->vehicle_colours[i].Ternary = _td.vehicle_additional_colour[tdIndex]; } for (int32_t count = 1; count == 1 || r->Error != GameActions::Status::Ok; ++count) diff --git a/src/openrct2/rct1/T4Importer.cpp b/src/openrct2/rct1/T4Importer.cpp index 9f2a1579dd..dc11084497 100644 --- a/src/openrct2/rct1/T4Importer.cpp +++ b/src/openrct2/rct1/T4Importer.cpp @@ -212,7 +212,7 @@ private: } } // Set remaining vehicles to same colour as first vehicle - for (int32_t i = RCT1_MAX_TRAINS_PER_RIDE; i <= MAX_VEHICLES_PER_RIDE; i++) + for (size_t i = RCT1_MAX_TRAINS_PER_RIDE; i < std::size(td->vehicle_colours); i++) { td->vehicle_colours[i] = td->vehicle_colours[0]; td->vehicle_additional_colour[i] = td->vehicle_additional_colour[0]; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 444cd3ab86..f0ae28b0d3 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -3095,7 +3095,7 @@ vehicle_colour ride_get_vehicle_colour(Ride* ride, int32_t vehicleIndex) vehicle_colour result; // Prevent indexing array out of bounds - vehicleIndex = std::min(vehicleIndex, MAX_CARS_PER_TRAIN); + vehicleIndex = std::min(vehicleIndex, MAX_CARS_PER_TRAIN); result.main = ride->vehicle_colours[vehicleIndex].Body; result.additional_1 = ride->vehicle_colours[vehicleIndex].Trim; @@ -6402,7 +6402,7 @@ void Ride::UpdateMaxVehicles() { case RideMode::ContinuousCircuitBlockSectioned: case RideMode::PoweredLaunchBlockSectioned: - maxNumTrains = std::clamp(num_stations + num_block_brakes - 1, 1, 31); + maxNumTrains = std::clamp(num_stations + num_block_brakes - 1, 1, MAX_VEHICLES_PER_RIDE); break; case RideMode::ReverseInclineLaunchedShuttle: case RideMode::PoweredLaunchPasstrough: @@ -6434,7 +6434,7 @@ void Ride::UpdateMaxVehicles() if ((mode != RideMode::StationToStation && mode != RideMode::ContinuousCircuit) || !(GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_ALLOW_MORE_VEHICLES_THAN_STATION_FITS))) { - maxNumTrains = std::min(maxNumTrains, 31); + maxNumTrains = std::min(maxNumTrains, int32_t(MAX_VEHICLES_PER_RIDE)); } else { @@ -6463,7 +6463,7 @@ void Ride::UpdateMaxVehicles() { maxNumTrains++; length += totalSpacing; - } while (maxNumTrains < 31 && length < trackLength); + } while (maxNumTrains < MAX_VEHICLES_PER_RIDE && length < trackLength); } break; } @@ -6482,7 +6482,7 @@ void Ride::UpdateMaxVehicles() if (gCheatsDisableTrainLengthLimit) { - maxNumTrains = 31; + maxNumTrains = MAX_VEHICLES_PER_RIDE; } numVehicles = std::min(proposed_num_vehicles, static_cast(maxNumTrains)); diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 13c32587cc..c7e22d1809 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -36,12 +36,13 @@ struct Vehicle; // The max number of different types of vehicle. // Examples of vehicles here are the locomotive, tender and carriage of the Miniature Railway. #define MAX_VEHICLES_PER_RIDE_ENTRY 4 -#define MAX_VEHICLES_PER_RIDE 31 +constexpr const uint8_t MAX_VEHICLES_PER_RIDE = 31; +constexpr const uint8_t MAX_CARS_PER_TRAIN = 255; +constexpr const uint8_t MAX_VEHICLE_COLOURS = std::max(MAX_CARS_PER_TRAIN, MAX_VEHICLES_PER_RIDE); #define NUM_COLOUR_SCHEMES 4 #define MAX_CATEGORIES_PER_RIDE 2 #define DOWNTIME_HISTORY_SIZE 8 #define CUSTOMER_HISTORY_SIZE 10 -#define MAX_CARS_PER_TRAIN 255 #define MAX_STATIONS 4 #define MAX_RIDES 255 #define RIDE_TYPE_NULL 255 @@ -215,7 +216,7 @@ struct Ride ObjectEntryIndex subtype; RideMode mode; uint8_t colour_scheme_type; - VehicleColour vehicle_colours[MAX_CARS_PER_TRAIN]; + VehicleColour vehicle_colours[MAX_VEHICLE_COLOURS]; // 0 = closed, 1 = open, 2 = test uint8_t status; std::string custom_name; From 1c5af028e1b0bcb6d735da764f03d8a52a894441 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 10 Apr 2021 11:32:39 +0200 Subject: [PATCH 28/45] Fix placing entrance/exit for ride ID >= 256 --- src/openrct2-ui/windows/RideConstruction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index d66407bd92..437558b8be 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1981,7 +1981,7 @@ static void window_ride_construction_entrance_click(rct_window* w) else { gRideEntranceExitPlaceType = ENTRANCE_TYPE_RIDE_ENTRANCE; - gRideEntranceExitPlaceRideIndex = w->number & 0xFF; + gRideEntranceExitPlaceRideIndex = static_cast(w->number); gRideEntranceExitPlaceStationIndex = 0; input_set_flag(INPUT_FLAG_6, true); ride_construction_invalidate_current_track(); From 929433680d5716caf2c9fe1a300c33b00dadfbd3 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 18 Apr 2021 12:55:20 +0200 Subject: [PATCH 29/45] Replace TestPaint CI with regular i686 build --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bea51fde6..94b673621f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -237,9 +237,7 @@ jobs: run: . scripts/setenv && get-discord-rpc - name: Build OpenRCT2 shell: bash - env: - TESTPAINT: true - run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DFORCE32=ON -DENABLE_SCRIPTING=OFF -DCMAKE_CXX_FLAGS="-m32 -gz" + run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DFORCE32=ON -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g -gz -m32" - name: Build artifacts shell: bash run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-i686.tar.gz bin/install/usr @@ -251,9 +249,6 @@ jobs: - name: Run Tests shell: bash run: . scripts/setenv -q && run-tests - - name: Run testpaint - shell: bash - run: . scripts/setenv -q && run-testpaint - name: Upload artifacts (openrct2.org) shell: bash run: | From a8702dc2c87e3db7e2be3064bb19af9a8377ef2a Mon Sep 17 00:00:00 2001 From: ceeac Date: Sun, 18 Apr 2021 12:57:46 +0200 Subject: [PATCH 30/45] Fix compile error when DEBUG_LEVEL=1 --- src/openrct2/peep/GuestPathfinding.cpp | 62 +++++++++++++------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index a6a5134087..cf98e8a69e 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -34,9 +34,9 @@ ride_id_t gPeepPathFindQueueRideIndex; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 // Use to guard calls to log messages -bool gPathFindDebug = false; +static bool _pathFindDebug = false; // Use to put the peep name in the log message -utf8 gPathFindDebugPeepName[256]; +static utf8 _pathFindDebugPeepName[256]; #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 static int32_t guest_surface_path_finding(Peep* peep); @@ -1269,10 +1269,10 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) TileCoordsXYZ goal = gPeepPathFindGoalPosition; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose( - "Choose direction for %s for goal %d,%d,%d from %d,%d,%d", gPathFindDebugPeepName, goal.x, goal.y, goal.z, loc.x, + "Choose direction for %s for goal %d,%d,%d from %d,%d,%d", _pathFindDebugPeepName, goal.x, goal.y, goal.z, loc.x, loc.y, loc.z); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -1362,7 +1362,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) edges = pathfindHistory.direction; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose( "Getting untried edges from pf_history for %d,%d,%d: %s,%s,%s,%s", loc.x, loc.y, loc.z, @@ -1384,7 +1384,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) edges = pathfindHistory.direction; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose("All edges tried for %d,%d,%d - resetting to all untried", loc.x, loc.y, loc.z); } @@ -1408,7 +1408,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) // Clear pathfinding history std::fill_n(reinterpret_cast(peep->PathfindHistory), sizeof(peep->PathfindHistory), 0xFF); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose("New goal; clearing pf_history."); } @@ -1433,7 +1433,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) uint8_t bestDirectionList[16]; TileCoordsXYZ bestXYZ; - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose("Pathfind start for goal %d,%d,%d from %d,%d,%d", goal.x, goal.y, goal.z, loc.x, loc.y, loc.z); } @@ -1515,7 +1515,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) endJunctionList, endDirectionList, &endXYZ, &endSteps); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose( "Pathfind test edge: %d score: %d steps: %d end: %d,%d,%d junctions: %d", test_edge, score, endSteps, @@ -1556,7 +1556,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) if (best_score == 0xFFFF) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose("Pathfind heuristic search failed."); } @@ -1564,7 +1564,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) return INVALID_DIRECTION; } #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose("Pathfind best edge %d with score %d steps %d", chosen_edge, best_score, best_sub); for (uint8_t listIdx = 0; listIdx < bestJunctions; listIdx++) @@ -1592,7 +1592,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) * entered the junction from those left to try. */ peep->PathfindHistory[i].direction &= ~(1 << direction_reverse(peep->PeepDirection)); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose( "Updating existing pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i, @@ -1617,7 +1617,7 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) * entered the junction from those left to try. */ peep->PathfindHistory[i].direction &= ~(1 << direction_reverse(peep->PeepDirection)); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_verbose( "Storing new pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i, loc.x, loc.y, @@ -1980,9 +1980,9 @@ int32_t guest_path_finding(Guest* peep) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 PathfindLoggingEnable(peep); - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Starting guest_path_finding for %s", gPathFindDebugPeepName); + log_info("Starting guest_path_finding for %s", _pathFindDebugPeepName); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2050,10 +2050,10 @@ int32_t guest_path_finding(Guest* peep) if ((edges & ~(1 << direction)) == 0) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_info( - "Completed guest_path_finding for %s - taking only direction available: %d.", gPathFindDebugPeepName, + "Completed guest_path_finding for %s - taking only direction available: %d.", _pathFindDebugPeepName, direction); } PathfindLoggingDisable(); @@ -2068,9 +2068,9 @@ int32_t guest_path_finding(Guest* peep) if (peep->OutsideOfPark) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Completed guest_path_finding for %s - peep is outside the park.", gPathFindDebugPeepName); + log_info("Completed guest_path_finding for %s - peep is outside the park.", _pathFindDebugPeepName); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2138,9 +2138,9 @@ int32_t guest_path_finding(Guest* peep) if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Completed guest_path_finding for %s - peep is leaving the park.", gPathFindDebugPeepName); + log_info("Completed guest_path_finding for %s - peep is leaving the park.", _pathFindDebugPeepName); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2150,9 +2150,9 @@ int32_t guest_path_finding(Guest* peep) if (peep->GuestHeadingToRideId == RIDE_ID_NULL) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Completed guest_path_finding for %s - peep is aimless.", gPathFindDebugPeepName); + log_info("Completed guest_path_finding for %s - peep is aimless.", _pathFindDebugPeepName); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2165,10 +2165,10 @@ int32_t guest_path_finding(Guest* peep) if (ride == nullptr || ride->status != RIDE_STATUS_OPEN) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { log_info( - "Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", gPathFindDebugPeepName); + "Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", _pathFindDebugPeepName); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2249,9 +2249,9 @@ int32_t guest_path_finding(Guest* peep) peep->ResetPathfindGoal(); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Completed guest_path_finding for %s - failed to choose a direction == aimless.", gPathFindDebugPeepName); + log_info("Completed guest_path_finding for %s - failed to choose a direction == aimless.", _pathFindDebugPeepName); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2259,9 +2259,9 @@ int32_t guest_path_finding(Guest* peep) return guest_path_find_aimless(peep, edges); } #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Completed guest_path_finding for %s - direction chosen: %d.", gPathFindDebugPeepName, direction); + log_info("Completed guest_path_finding for %s - direction chosen: %d.", _pathFindDebugPeepName, direction); } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 @@ -2302,9 +2302,9 @@ bool IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_ void Peep::ResetPathfindGoal() { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) + if (_pathFindDebug) { - log_info("Resetting PathfindGoal for %s", gPathFindDebugPeepName); + log_info("Resetting PathfindGoal for %s", _pathFindDebugPeepName); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 From 8eabdf8c8fb6e93df9beb096164bfe5fe349c131 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 18 Apr 2021 17:48:21 +0100 Subject: [PATCH 31/45] Split guest and staff peep variables (#14462) * Split guest and staff peep variables * Move variable location * Increment network version * Update replays --- CMakeLists.txt | 4 +- openrct2.proj | 4 +- src/openrct2-ui/windows/GameBottomToolbar.cpp | 28 +- src/openrct2-ui/windows/Guest.cpp | 57 +- src/openrct2-ui/windows/GuestList.cpp | 6 +- src/openrct2-ui/windows/News.cpp | 9 +- src/openrct2-ui/windows/Staff.cpp | 18 - src/openrct2/GameStateSnapshots.cpp | 155 ++- src/openrct2/actions/StaffHireNewAction.cpp | 12 +- src/openrct2/management/Marketing.cpp | 2 +- src/openrct2/management/Marketing.h | 2 +- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/paint/sprite/Paint.Peep.cpp | 37 +- src/openrct2/peep/Guest.cpp | 849 +++++++++++- src/openrct2/peep/GuestPathfinding.cpp | 10 +- src/openrct2/peep/Peep.cpp | 1205 +++-------------- src/openrct2/peep/Peep.h | 25 +- src/openrct2/rct1/S4Importer.cpp | 227 ++-- src/openrct2/rct2/S6Exporter.cpp | 151 ++- src/openrct2/rct2/S6Importer.cpp | 146 +- src/openrct2/ride/Ride.cpp | 24 +- src/openrct2/ride/Ride.h | 8 +- src/openrct2/world/Park.cpp | 8 +- src/openrct2/world/Park.h | 8 +- test/tests/Pathfinding.cpp | 2 +- test/tests/S6ImportExportTests.cpp | 111 +- 26 files changed, 1586 insertions(+), 1524 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a2114bd2f..4a8cfb4a72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,9 +50,9 @@ set(OBJECTS_VERSION "1.0.21") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5") -set(REPLAYS_VERSION "0.0.38") +set(REPLAYS_VERSION "0.0.39") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") -set(REPLAYS_SHA1 "8940FE7B3F86772214C8CF265E6CEA5A25B49FC1") +set(REPLAYS_SHA1 "8AF797661D87394FBE1A059375D82632094290FB") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/openrct2.proj b/openrct2.proj index 02db22bdb3..11be434fc9 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -48,8 +48,8 @@ 304d13a126c15bf2c86ff13b81a2f2cc1856ac8d https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip c38af45d51a6e440386180feacf76c64720b6ac5 - https://github.com/OpenRCT2/replays/releases/download/v0.0.38/replays.zip - 8940FE7B3F86772214C8CF265E6CEA5A25B49FC1 + https://github.com/OpenRCT2/replays/releases/download/v0.0.39/replays.zip + 8AF797661D87394FBE1A059375D82632094290FB diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index aebe359cea..8e8760d12c 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -601,8 +601,8 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo* dpi, rc return; auto clipCoords = ScreenCoordsXY{ 10, 19 }; - - if (peep->Is() && peep->AssignedStaffType == StaffType::Entertainer) + auto* staff = peep->As(); + if (staff != nullptr && staff->AssignedStaffType == StaffType::Entertainer) { clipCoords.y += 3; } @@ -614,17 +614,21 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo* dpi, rc auto image_id = ImageId(image_id_base, peep->TshirtColour, peep->TrousersColour); gfx_draw_sprite(&cliped_dpi, image_id, clipCoords); - if (image_id_base >= 0x2A1D && image_id_base < 0x2A3D) + auto* guest = peep->As(); + if (guest != nullptr) { - gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, peep->BalloonColour), clipCoords); - } - else if (image_id_base >= 0x2BBD && image_id_base < 0x2BDD) - { - gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, peep->UmbrellaColour), clipCoords); - } - else if (image_id_base >= 0x29DD && image_id_base < 0x29FD) - { - gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, peep->HatColour), clipCoords); + if (image_id_base >= 0x2A1D && image_id_base < 0x2A3D) + { + gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, guest->BalloonColour), clipCoords); + } + else if (image_id_base >= 0x2BBD && image_id_base < 0x2BDD) + { + gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, guest->UmbrellaColour), clipCoords); + } + else if (image_id_base >= 0x29DD && image_id_base < 0x29FD) + { + gfx_draw_sprite(&cliped_dpi, ImageId(image_id_base + 32, guest->HatColour), clipCoords); + } } break; } diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index f343d06836..4345fcab8e 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -758,7 +758,8 @@ static void window_guest_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dp return; } - if (peep->Is() && peep->AssignedStaffType == StaffType::Entertainer) + auto* staff = peep->As(); + if (staff != nullptr && staff->AssignedStaffType == StaffType::Entertainer) screenCoords.y++; int32_t animationFrame = GetPeepAnimation(peep->SpriteType).base_image + 1; @@ -775,22 +776,26 @@ static void window_guest_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dp auto sprite_id = ImageId(animationFrame, peep->TshirtColour, peep->TrousersColour); gfx_draw_sprite(&clip_dpi, sprite_id, screenCoords); - // If holding a balloon - if (animationFrame >= 0x2A1D && animationFrame < 0x2A3D) + auto* guest = peep->As(); + if (guest != nullptr) { - gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, peep->BalloonColour), screenCoords); - } + // If holding a balloon + if (animationFrame >= 0x2A1D && animationFrame < 0x2A3D) + { + gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, guest->BalloonColour), screenCoords); + } - // If holding umbrella - if (animationFrame >= 0x2BBD && animationFrame < 0x2BDD) - { - gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, peep->UmbrellaColour), screenCoords); - } + // If holding umbrella + if (animationFrame >= 0x2BBD && animationFrame < 0x2BDD) + { + gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, guest->UmbrellaColour), screenCoords); + } - // If wearing hat - if (animationFrame >= 0x29DD && animationFrame < 0x29FD) - { - gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, peep->HatColour), screenCoords); + // If wearing hat + if (animationFrame >= 0x29DD && animationFrame < 0x29FD) + { + gfx_draw_sprite(&clip_dpi, ImageId(animationFrame + 32, guest->HatColour), screenCoords); + } } } @@ -1833,7 +1838,7 @@ void window_guest_inventory_update(rct_window* w) } } -static std::pair window_guest_inventory_format_item(Peep* peep, ShopItem item) +static std::pair window_guest_inventory_format_item(Guest* guest, ShopItem item) { auto& park = OpenRCT2::GetContext()->GetGameState()->GetPark(); auto parkName = park.Name.c_str(); @@ -1851,10 +1856,10 @@ static std::pair window_guest_inventory_format_item(Pe { case ShopItem::Balloon: ft.Rewind(); - ft.Add(SPRITE_ID_PALETTE_COLOUR_1(peep->BalloonColour) | GetShopItemDescriptor(item).Image); + ft.Add(SPRITE_ID_PALETTE_COLOUR_1(guest->BalloonColour) | GetShopItemDescriptor(item).Image); break; case ShopItem::Photo: - ride = get_ride(peep->Photo1RideRef); + ride = get_ride(guest->Photo1RideRef); if (ride != nullptr) { ft.Rewind(); @@ -1865,10 +1870,10 @@ static std::pair window_guest_inventory_format_item(Pe break; case ShopItem::Umbrella: ft.Rewind(); - ft.Add(SPRITE_ID_PALETTE_COLOUR_1(peep->UmbrellaColour) | GetShopItemDescriptor(item).Image); + ft.Add(SPRITE_ID_PALETTE_COLOUR_1(guest->UmbrellaColour) | GetShopItemDescriptor(item).Image); break; case ShopItem::Voucher: - switch (peep->VoucherType) + switch (guest->VoucherType) { case VOUCHER_TYPE_PARK_ENTRY_FREE: ft.Rewind(); @@ -1878,7 +1883,7 @@ static std::pair window_guest_inventory_format_item(Pe ft.Add(parkName); break; case VOUCHER_TYPE_RIDE_FREE: - ride = get_ride(peep->VoucherRideId); + ride = get_ride(guest->VoucherRideId); if (ride != nullptr) { ft.Rewind(); @@ -1898,20 +1903,20 @@ static std::pair window_guest_inventory_format_item(Pe ft.Rewind(); ft.Increment(6); ft.Add(STR_PEEP_INVENTORY_VOUCHER_FOOD_OR_DRINK_FREE); - ft.Add(GetShopItemDescriptor(peep->VoucherShopItem).Naming.Singular); + ft.Add(GetShopItemDescriptor(guest->VoucherShopItem).Naming.Singular); break; } break; case ShopItem::Hat: ft.Rewind(); - ft.Add(SPRITE_ID_PALETTE_COLOUR_1(peep->HatColour) | GetShopItemDescriptor(item).Image); + ft.Add(SPRITE_ID_PALETTE_COLOUR_1(guest->HatColour) | GetShopItemDescriptor(item).Image); break; case ShopItem::TShirt: ft.Rewind(); - ft.Add(SPRITE_ID_PALETTE_COLOUR_1(peep->TshirtColour) | GetShopItemDescriptor(item).Image); + ft.Add(SPRITE_ID_PALETTE_COLOUR_1(guest->TshirtColour) | GetShopItemDescriptor(item).Image); break; case ShopItem::Photo2: - ride = get_ride(peep->Photo2RideRef); + ride = get_ride(guest->Photo2RideRef); if (ride != nullptr) { ft.Rewind(); @@ -1920,7 +1925,7 @@ static std::pair window_guest_inventory_format_item(Pe } break; case ShopItem::Photo3: - ride = get_ride(peep->Photo3RideRef); + ride = get_ride(guest->Photo3RideRef); if (ride != nullptr) { ft.Rewind(); @@ -1929,7 +1934,7 @@ static std::pair window_guest_inventory_format_item(Pe } break; case ShopItem::Photo4: - ride = get_ride(peep->Photo4RideRef); + ride = get_ride(guest->Photo4RideRef); if (ride != nullptr) { ft.Rewind(); diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index c93b459a2f..b45a53beb9 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -773,7 +773,7 @@ private: } } - bool GuestShouldBeVisible(const Peep& peep) + bool GuestShouldBeVisible(const Guest& peep) { if (_trackingOnly && !(peep.PeepFlags & PEEP_FLAGS_TRACKING)) return false; @@ -794,7 +794,7 @@ private: return true; } - bool IsPeepInFilter(const Peep& peep) + bool IsPeepInFilter(const Guest& peep) { auto guestViewType = _selectedFilter == GuestFilterType::Guests ? GuestViewType::Actions : GuestViewType::Thoughts; auto peepArgs = GetArgumentsFromPeep(peep, guestViewType); @@ -875,7 +875,7 @@ private: /** * Calculates a hash value (arguments) for comparing peep actions/thoughts */ - static FilterArguments GetArgumentsFromPeep(const Peep& peep, GuestViewType type) + static FilterArguments GetArgumentsFromPeep(const Guest& peep, GuestViewType type) { FilterArguments result; Formatter ft(result.args); diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index 09d78458c7..2bcc342b3d 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -246,10 +246,11 @@ public: // If normal peep set sprite to normal (no food) // If staff set sprite to staff sprite auto spriteType = PeepSpriteType::Normal; - if (peep->Is()) + auto* staff = peep->As(); + if (staff != nullptr) { - spriteType = peep->SpriteType; - if (peep->AssignedStaffType == StaffType::Entertainer) + spriteType = staff->SpriteType; + if (staff->AssignedStaffType == StaffType::Entertainer) { clipCoords.y += 3; } @@ -309,4 +310,4 @@ public: rct_window* window_news_open() { return WindowFocusOrCreate(WC_RECENT_NEWS, WW, WH, 0); -} \ No newline at end of file +} diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 0f2ca69cec..d846a00040 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -1034,24 +1034,6 @@ void window_staff_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dpi) ebx += eax; gfx_draw_sprite(&clip_dpi, ImageId(ebx, peep->TshirtColour, peep->TrousersColour), screenCoords); - - // If holding a balloon - if (ebx >= 0x2A1D && ebx < 0x2A3D) - { - gfx_draw_sprite(&clip_dpi, ImageId(ebx + 32, peep->BalloonColour), screenCoords); - } - - // If holding umbrella - if (ebx >= 0x2BBD && ebx < 0x2BDD) - { - gfx_draw_sprite(&clip_dpi, ImageId(ebx + 32, peep->UmbrellaColour), screenCoords); - } - - // If wearing hat - if (ebx >= 0x29DD && ebx < 0x29FD) - { - gfx_draw_sprite(&clip_dpi, ImageId(ebx + 32, peep->HatColour), screenCoords); - } } /** diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp index 68056cffc0..69c065d405 100644 --- a/src/openrct2/GameStateSnapshots.cpp +++ b/src/openrct2/GameStateSnapshots.cpp @@ -218,11 +218,9 @@ struct GameStateSnapshots final : public IGameStateSnapshots COMPARE_FIELD(Peep, NextLoc.y); COMPARE_FIELD(Peep, NextLoc.z); COMPARE_FIELD(Peep, NextFlags); - COMPARE_FIELD(Peep, OutsideOfPark); COMPARE_FIELD(Peep, State); COMPARE_FIELD(Peep, SubState); COMPARE_FIELD(Peep, SpriteType); - COMPARE_FIELD(Peep, GuestNumRides); COMPARE_FIELD(Peep, TshirtColour); COMPARE_FIELD(Peep, TrousersColour); COMPARE_FIELD(Peep, DestinationX); @@ -231,27 +229,8 @@ struct GameStateSnapshots final : public IGameStateSnapshots COMPARE_FIELD(Peep, Var37); COMPARE_FIELD(Peep, Energy); COMPARE_FIELD(Peep, EnergyTarget); - COMPARE_FIELD(Peep, Happiness); - COMPARE_FIELD(Peep, HappinessTarget); - COMPARE_FIELD(Peep, Nausea); - COMPARE_FIELD(Peep, NauseaTarget); - COMPARE_FIELD(Peep, Hunger); - COMPARE_FIELD(Peep, Thirst); - COMPARE_FIELD(Peep, Toilet); COMPARE_FIELD(Peep, Mass); - COMPARE_FIELD(Peep, TimeToConsume); - COMPARE_FIELD(Peep, Intensity); - COMPARE_FIELD(Peep, NauseaTolerance); COMPARE_FIELD(Peep, WindowInvalidateFlags); - COMPARE_FIELD(Peep, PaidOnDrink); - for (int i = 0; i < 16; i++) - { - COMPARE_FIELD(Peep, RideTypesBeenOn[i]); - } - COMPARE_FIELD(Peep, ItemFlags); - COMPARE_FIELD(Peep, Photo2RideRef); - COMPARE_FIELD(Peep, Photo3RideRef); - COMPARE_FIELD(Peep, Photo4RideRef); COMPARE_FIELD(Peep, CurrentRide); COMPARE_FIELD(Peep, CurrentRideStation); COMPARE_FIELD(Peep, CurrentTrain); @@ -263,58 +242,102 @@ struct GameStateSnapshots final : public IGameStateSnapshots COMPARE_FIELD(Peep, Action); COMPARE_FIELD(Peep, ActionFrame); COMPARE_FIELD(Peep, StepProgress); - COMPARE_FIELD(Peep, GuestNextInQueue); COMPARE_FIELD(Peep, MazeLastEdge); COMPARE_FIELD(Peep, InteractionRideIndex); - COMPARE_FIELD(Peep, TimeInQueue); - for (int i = 0; i < 32; i++) - { - COMPARE_FIELD(Peep, RidesBeenOn[i]); - } COMPARE_FIELD(Peep, Id); - COMPARE_FIELD(Peep, CashInPocket); - COMPARE_FIELD(Peep, CashSpent); - COMPARE_FIELD(Peep, ParkEntryTime); - COMPARE_FIELD(Peep, RejoinQueueTimeout); - COMPARE_FIELD(Peep, PreviousRide); - COMPARE_FIELD(Peep, PreviousRideTimeOut); - for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) - { - COMPARE_FIELD(Peep, Thoughts[i]); - } COMPARE_FIELD(Peep, PathCheckOptimisation); - COMPARE_FIELD(Peep, GuestHeadingToRideId); - COMPARE_FIELD(Peep, StaffOrders); - COMPARE_FIELD(Peep, Photo1RideRef); - COMPARE_FIELD(Peep, PeepFlags); COMPARE_FIELD(Peep, PathfindGoal); for (int i = 0; i < 4; i++) { COMPARE_FIELD(Peep, PathfindHistory[i]); } COMPARE_FIELD(Peep, WalkingFrameNum); - COMPARE_FIELD(Peep, LitterCount); - COMPARE_FIELD(Peep, GuestTimeOnRide); - COMPARE_FIELD(Peep, DisgustingCount); - COMPARE_FIELD(Peep, PaidToEnter); - COMPARE_FIELD(Peep, PaidOnRides); - COMPARE_FIELD(Peep, PaidOnFood); - COMPARE_FIELD(Peep, PaidOnSouvenirs); - COMPARE_FIELD(Peep, AmountOfFood); - COMPARE_FIELD(Peep, AmountOfDrinks); - COMPARE_FIELD(Peep, AmountOfSouvenirs); - COMPARE_FIELD(Peep, VandalismSeen); - COMPARE_FIELD(Peep, VoucherType); - COMPARE_FIELD(Peep, VoucherRideId); - COMPARE_FIELD(Peep, SurroundingsThoughtTimeout); - COMPARE_FIELD(Peep, Angriness); - COMPARE_FIELD(Peep, TimeLost); - COMPARE_FIELD(Peep, DaysInQueue); - COMPARE_FIELD(Peep, BalloonColour); - COMPARE_FIELD(Peep, UmbrellaColour); - COMPARE_FIELD(Peep, HatColour); - COMPARE_FIELD(Peep, FavouriteRide); - COMPARE_FIELD(Peep, FavouriteRideRating); + } + + void CompareSpriteDataStaff(const Staff& spriteBase, const Staff& spriteCmp, GameStateSpriteChange_t& changeData) const + { + CompareSpriteDataPeep(spriteBase, spriteCmp, changeData); + + COMPARE_FIELD(Staff, AssignedStaffType); + COMPARE_FIELD(Staff, MechanicTimeSinceCall); + COMPARE_FIELD(Staff, HireDate); + COMPARE_FIELD(Staff, StaffId); + COMPARE_FIELD(Staff, StaffOrders); + COMPARE_FIELD(Staff, StaffMowingTimeout); + COMPARE_FIELD(Staff, StaffRidesFixed); + COMPARE_FIELD(Staff, StaffRidesInspected); + COMPARE_FIELD(Staff, StaffLitterSwept); + COMPARE_FIELD(Staff, StaffBinsEmptied); + } + + void CompareSpriteDataGuest(const Guest& spriteBase, const Guest& spriteCmp, GameStateSpriteChange_t& changeData) const + { + CompareSpriteDataPeep(spriteBase, spriteCmp, changeData); + + COMPARE_FIELD(Guest, OutsideOfPark); + COMPARE_FIELD(Guest, GuestNumRides); + COMPARE_FIELD(Guest, Happiness); + COMPARE_FIELD(Guest, HappinessTarget); + COMPARE_FIELD(Guest, Nausea); + COMPARE_FIELD(Guest, NauseaTarget); + COMPARE_FIELD(Guest, Hunger); + COMPARE_FIELD(Guest, Thirst); + COMPARE_FIELD(Guest, Toilet); + COMPARE_FIELD(Guest, TimeToConsume); + COMPARE_FIELD(Guest, Intensity); + COMPARE_FIELD(Guest, NauseaTolerance); + COMPARE_FIELD(Guest, PaidOnDrink); + for (int i = 0; i < 16; i++) + { + COMPARE_FIELD(Guest, RideTypesBeenOn[i]); + } + COMPARE_FIELD(Guest, ItemFlags); + COMPARE_FIELD(Guest, Photo2RideRef); + COMPARE_FIELD(Guest, Photo3RideRef); + COMPARE_FIELD(Guest, Photo4RideRef); + COMPARE_FIELD(Guest, GuestNextInQueue); + COMPARE_FIELD(Guest, TimeInQueue); + for (int i = 0; i < 32; i++) + { + COMPARE_FIELD(Guest, RidesBeenOn[i]); + } + + COMPARE_FIELD(Guest, CashInPocket); + COMPARE_FIELD(Guest, CashSpent); + COMPARE_FIELD(Guest, ParkEntryTime); + COMPARE_FIELD(Guest, RejoinQueueTimeout); + COMPARE_FIELD(Guest, PreviousRide); + COMPARE_FIELD(Guest, PreviousRideTimeOut); + for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) + { + COMPARE_FIELD(Guest, Thoughts[i]); + } + COMPARE_FIELD(Guest, GuestHeadingToRideId); + COMPARE_FIELD(Guest, GuestIsLostCountdown); + COMPARE_FIELD(Guest, Photo1RideRef); + COMPARE_FIELD(Guest, PeepFlags); + COMPARE_FIELD(Guest, LitterCount); + COMPARE_FIELD(Guest, GuestTimeOnRide); + COMPARE_FIELD(Guest, DisgustingCount); + COMPARE_FIELD(Guest, PaidToEnter); + COMPARE_FIELD(Guest, PaidOnRides); + COMPARE_FIELD(Guest, PaidOnFood); + COMPARE_FIELD(Guest, PaidOnSouvenirs); + COMPARE_FIELD(Guest, AmountOfFood); + COMPARE_FIELD(Guest, AmountOfDrinks); + COMPARE_FIELD(Guest, AmountOfSouvenirs); + COMPARE_FIELD(Guest, VandalismSeen); + COMPARE_FIELD(Guest, VoucherType); + COMPARE_FIELD(Guest, VoucherRideId); + COMPARE_FIELD(Guest, SurroundingsThoughtTimeout); + COMPARE_FIELD(Guest, Angriness); + COMPARE_FIELD(Guest, TimeLost); + COMPARE_FIELD(Guest, DaysInQueue); + COMPARE_FIELD(Guest, BalloonColour); + COMPARE_FIELD(Guest, UmbrellaColour); + COMPARE_FIELD(Guest, HatColour); + COMPARE_FIELD(Guest, FavouriteRide); + COMPARE_FIELD(Guest, FavouriteRideRating); } void CompareSpriteDataVehicle( @@ -480,10 +503,12 @@ struct GameStateSnapshots final : public IGameStateSnapshots switch (spriteBase.misc.Type) { case EntityType::Guest: - CompareSpriteDataPeep(spriteBase.peep, spriteCmp.peep, changeData); + CompareSpriteDataGuest( + static_cast(spriteBase.peep), static_cast(spriteCmp.peep), changeData); break; case EntityType::Staff: - CompareSpriteDataPeep(spriteBase.peep, spriteCmp.peep, changeData); + CompareSpriteDataStaff( + static_cast(spriteBase.peep), static_cast(spriteCmp.peep), changeData); break; case EntityType::Vehicle: CompareSpriteDataVehicle(spriteBase.vehicle, spriteCmp.vehicle, changeData); diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index 1055e3e642..49692d4648 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -128,7 +128,7 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const return MakeResult(GameActions::Status::NoFreeElements, STR_TOO_MANY_STAFF_IN_GAME); } - Peep* newPeep = CreateEntity(); + Staff* newPeep = CreateEntity(); if (newPeep == nullptr) { // Too many peeps exist already. @@ -149,13 +149,11 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const newPeep->WalkingFrameNum = 0; newPeep->ActionSpriteType = PeepActionSpriteType::None; newPeep->PathCheckOptimisation = 0; - newPeep->OutsideOfPark = false; newPeep->PeepFlags = 0; - newPeep->PaidToEnter = 0; - newPeep->PaidOnRides = 0; - newPeep->PaidOnFood = 0; - newPeep->PaidOnSouvenirs = 0; - newPeep->FavouriteRide = RIDE_ID_NULL; + newPeep->StaffLawnsMown = 0; + newPeep->StaffGardensWatered = 0; + newPeep->StaffLitterSwept = 0; + newPeep->StaffBinsEmptied = 0; newPeep->StaffOrders = _staffOrders; // We search for the first available Id for a given staff type diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 39d086e226..f458ea23e4 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -127,7 +127,7 @@ void marketing_update() window_invalidate_by_class(WC_FINANCES); } -void marketing_set_guest_campaign(Peep* peep, int32_t campaignType) +void marketing_set_guest_campaign(Guest* peep, int32_t campaignType) { auto campaign = marketing_get_campaign(campaignType); if (campaign == nullptr) diff --git a/src/openrct2/management/Marketing.h b/src/openrct2/management/Marketing.h index c74e51e6c3..7c0a13f422 100644 --- a/src/openrct2/management/Marketing.h +++ b/src/openrct2/management/Marketing.h @@ -63,7 +63,7 @@ extern std::vector gMarketingCampaigns; uint16_t marketing_get_campaign_guest_generation_probability(int32_t campaign); void marketing_update(); -void marketing_set_guest_campaign(Peep* peep, int32_t campaign); +void marketing_set_guest_campaign(Guest* peep, int32_t campaign); bool marketing_is_campaign_type_applicable(int32_t campaignType); MarketingCampaign* marketing_get_campaign(int32_t campaignType); void marketing_new_campaign(const MarketingCampaign& campaign); diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 53cd7e1afe..eabe5ac4bb 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -36,7 +36,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; diff --git a/src/openrct2/paint/sprite/Paint.Peep.cpp b/src/openrct2/paint/sprite/Paint.Peep.cpp index f330c5ff40..db04c2f376 100644 --- a/src/openrct2/paint/sprite/Paint.Peep.cpp +++ b/src/openrct2/paint/sprite/Paint.Peep.cpp @@ -82,25 +82,28 @@ template<> void PaintEntity(paint_session* session, const Peep* peep, int32_t im uint32_t imageId = baseImageId | peep->TshirtColour << 19 | peep->TrousersColour << 24 | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS; PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); - - if (baseImageId >= 10717 && baseImageId < 10749) + auto* guest = peep->As(); + if (guest != nullptr) { - imageId = (baseImageId + 32) | peep->HatColour << 19 | IMAGE_TYPE_REMAP; - PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); - return; - } + if (baseImageId >= 10717 && baseImageId < 10749) + { + imageId = (baseImageId + 32) | guest->HatColour << 19 | IMAGE_TYPE_REMAP; + PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); + return; + } - if (baseImageId >= 10781 && baseImageId < 10813) - { - imageId = (baseImageId + 32) | peep->BalloonColour << 19 | IMAGE_TYPE_REMAP; - PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); - return; - } + if (baseImageId >= 10781 && baseImageId < 10813) + { + imageId = (baseImageId + 32) | guest->BalloonColour << 19 | IMAGE_TYPE_REMAP; + PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); + return; + } - if (baseImageId >= 11197 && baseImageId < 11229) - { - imageId = (baseImageId + 32) | peep->UmbrellaColour << 19 | IMAGE_TYPE_REMAP; - PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); - return; + if (baseImageId >= 11197 && baseImageId < 11229) + { + imageId = (baseImageId + 32) | guest->UmbrellaColour << 19 | IMAGE_TYPE_REMAP; + PaintAddImageAsChild(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5); + return; + } } } diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index a04082ca8e..19fddfafaa 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -26,6 +26,8 @@ #include "../ride/Station.h" #include "../ride/Track.h" #include "../scenario/Scenario.h" +#include "../scripting/HookEngine.h" +#include "../scripting/ScriptEngine.h" #include "../util/Util.h" #include "../windows/Intent.h" #include "../world/Climate.h" @@ -204,28 +206,219 @@ static constexpr const char *gPeepEasterEggNames[] = { "DAVID ELLIS" }; +// Flags used by PeepThoughtToActionMap +enum PeepThoughtToActionFlag : uint8_t +{ + PEEP_THOUGHT_ACTION_NO_FLAGS = 0, + PEEP_THOUGHT_ACTION_FLAG_RIDE = (1 << 0), + PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR = (1 << 1), + PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE = (1 << 2), +}; + +/** rct2: 0x00981DB0 */ +static struct +{ + PeepActionType action; + PeepThoughtToActionFlag flags; +} PeepThoughtToActionMap[] = { + { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::EmptyPockets, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::Wow, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE }, + { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::Wave, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::Joy, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::CheckTime, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::Wave, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::Wave, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::Disgust, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::BeingWatched, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::Joy, PEEP_THOUGHT_ACTION_NO_FLAGS }, + { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, +}; + // These arrays contain the base minimum and maximum nausea ratings for peeps, based on their nausea tolerance level. static constexpr const ride_rating NauseaMinimumThresholds[] = { 0, 0, 200, 400 }; // clang-format on -static bool peep_has_voucher_for_free_ride(Peep* peep, Ride* ride); +static bool peep_has_voucher_for_free_ride(Guest* peep, Ride* ride); static void peep_ride_is_too_intense(Guest* peep, Ride* ride, bool peepAtRide); -static void peep_reset_ride_heading(Peep* peep); -static void peep_tried_to_enter_full_queue(Peep* peep, Ride* ride); +static void peep_reset_ride_heading(Guest* peep); +static void peep_tried_to_enter_full_queue(Guest* peep, Ride* ride); static int16_t peep_calculate_ride_satisfaction(Guest* peep, Ride* ride); -static void peep_update_favourite_ride(Peep* peep, Ride* ride); -static int16_t peep_calculate_ride_value_satisfaction(Peep* peep, Ride* ride); -static int16_t peep_calculate_ride_intensity_nausea_satisfaction(Peep* peep, Ride* ride); -static void peep_update_ride_nausea_growth(Peep* peep, Ride* ride); -static bool peep_should_go_on_ride_again(Peep* peep, Ride* ride); -static bool peep_should_preferred_intensity_increase(Peep* peep); -static bool peep_really_liked_ride(Peep* peep, Ride* ride); +static void peep_update_favourite_ride(Guest* peep, Ride* ride); +static int16_t peep_calculate_ride_value_satisfaction(Guest* peep, Ride* ride); +static int16_t peep_calculate_ride_intensity_nausea_satisfaction(Guest* peep, Ride* ride); +static void peep_update_ride_nausea_growth(Guest* peep, Ride* ride); +static bool peep_should_go_on_ride_again(Guest* peep, Ride* ride); +static bool peep_should_preferred_intensity_increase(Guest* peep); +static bool peep_really_liked_ride(Guest* peep, Ride* ride); static PeepThoughtType peep_assess_surroundings(int16_t centre_x, int16_t centre_y, int16_t centre_z); -static void peep_update_hunger(Peep* peep); -static void peep_decide_whether_to_leave_park(Peep* peep); -static void peep_leave_park(Peep* peep); +static void peep_update_hunger(Guest* peep); +static void peep_decide_whether_to_leave_park(Guest* peep); +static void peep_leave_park(Guest* peep); static void peep_head_for_nearest_ride_type(Guest* peep, int32_t rideType); static void peep_head_for_nearest_ride_with_flags(Guest* peep, int32_t rideTypeFlags); bool loc_690FD0(Peep* peep, ride_id_t* rideToView, uint8_t* rideSeatToView, TileElement* tileElement); @@ -1747,7 +1940,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t else { // Check if there's room in the queue for the peep to enter. - Peep* lastPeepInQueue = GetEntity(ride->stations[entranceNum].LastPeepInQueue); + Guest* lastPeepInQueue = GetEntity(ride->stations[entranceNum].LastPeepInQueue); if (lastPeepInQueue != nullptr && (abs(lastPeepInQueue->z - z) <= 6)) { int32_t dx = abs(lastPeepInQueue->x - x); @@ -2157,7 +2350,7 @@ void Guest::ReadMap() } } -static bool peep_has_voucher_for_free_ride(Peep* peep, Ride* ride) +static bool peep_has_voucher_for_free_ride(Guest* peep, Ride* ride) { return peep->HasItem(ShopItem::Voucher) && peep->VoucherType == VOUCHER_TYPE_RIDE_FREE && peep->VoucherRideId == ride->id; } @@ -2167,7 +2360,7 @@ static bool peep_has_voucher_for_free_ride(Peep* peep, Ride* ride) * Does not effect peeps that walk up to the queue entrance. * This flag is reset the next time a peep successfully joins the queue. */ -static void peep_tried_to_enter_full_queue(Peep* peep, Ride* ride) +static void peep_tried_to_enter_full_queue(Guest* peep, Ride* ride) { ride->lifecycle_flags |= RIDE_LIFECYCLE_QUEUE_FULL; peep->PreviousRide = ride->id; @@ -2179,7 +2372,7 @@ static void peep_tried_to_enter_full_queue(Peep* peep, Ride* ride) } } -static void peep_reset_ride_heading(Peep* peep) +static void peep_reset_ride_heading(Guest* peep) { peep->GuestHeadingToRideId = RIDE_ID_NULL; peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION; @@ -2452,7 +2645,7 @@ static int16_t peep_calculate_ride_satisfaction(Guest* peep, Ride* ride) * the ride becomes the peep's favourite. (This doesn't happen right away, but will be updated once the peep * exits the ride.) */ -static void peep_update_favourite_ride(Peep* peep, Ride* ride) +static void peep_update_favourite_ride(Guest* peep, Ride* ride) { peep->PeepFlags &= ~PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE; uint8_t peepRideRating = std::clamp((ride->excitement / 4) + peep->Happiness, 0, PEEP_MAX_HAPPINESS); @@ -2467,7 +2660,7 @@ static void peep_update_favourite_ride(Peep* peep, Ride* ride) } /* rct2: 0x00695555 */ -static int16_t peep_calculate_ride_value_satisfaction(Peep* peep, Ride* ride) +static int16_t peep_calculate_ride_value_satisfaction(Guest* peep, Ride* ride) { if (gParkFlags & PARK_FLAGS_NO_MONEY) { @@ -2499,7 +2692,7 @@ static int16_t peep_calculate_ride_value_satisfaction(Peep* peep, Ride* ride) * of the ride fall exactly within the peep's preferences, but lower scores can still be achieved * if the peep's happiness is enough to offset it. */ -static int16_t peep_calculate_ride_intensity_nausea_satisfaction(Peep* peep, Ride* ride) +static int16_t peep_calculate_ride_intensity_nausea_satisfaction(Guest* peep, Ride* ride) { if (!ride_has_ratings(ride)) { @@ -2599,7 +2792,7 @@ static int16_t peep_calculate_ride_intensity_nausea_satisfaction(Peep* peep, Rid * - How hungry the peep is (+0% nausea at 50% hunger up to +100% nausea at 100% hunger) * - The peep's nausea tolerance (Final modifier: none: 100%, low: 50%, average: 25%, high: 12.5%) */ -static void peep_update_ride_nausea_growth(Peep* peep, Ride* ride) +static void peep_update_ride_nausea_growth(Guest* peep, Ride* ride) { uint32_t nauseaMultiplier = std::clamp(256 - peep->HappinessTarget, 64, 200); uint32_t nauseaGrowthRateChange = (ride->nausea * nauseaMultiplier) / 512; @@ -2608,7 +2801,7 @@ static void peep_update_ride_nausea_growth(Peep* peep, Ride* ride) peep->NauseaTarget = static_cast(std::min(peep->NauseaTarget + nauseaGrowthRateChange, 255u)); } -static bool peep_should_go_on_ride_again(Peep* peep, Ride* ride) +static bool peep_should_go_on_ride_again(Guest* peep, Ride* ride) { if (!ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_PEEP_WILL_RIDE_AGAIN)) return false; @@ -2641,7 +2834,7 @@ static bool peep_should_go_on_ride_again(Peep* peep, Ride* ride) return true; } -static bool peep_should_preferred_intensity_increase(Peep* peep) +static bool peep_should_preferred_intensity_increase(Guest* peep) { if (gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) return false; @@ -2651,7 +2844,7 @@ static bool peep_should_preferred_intensity_increase(Peep* peep) return (scenario_rand() & 0xFF) >= static_cast(peep->Intensity); } -static bool peep_really_liked_ride(Peep* peep, Ride* ride) +static bool peep_really_liked_ride(Guest* peep, Ride* ride) { if (peep->Happiness < 215) return false; @@ -2783,7 +2976,7 @@ static PeepThoughtType peep_assess_surroundings(int16_t centre_x, int16_t centre * * rct2: 0x0068F9A9 */ -static void peep_update_hunger(Peep* peep) +static void peep_update_hunger(Guest* peep) { if (peep->Hunger >= 3) { @@ -2800,7 +2993,7 @@ static void peep_update_hunger(Peep* peep) * * rct2: 0x0068F8CD */ -static void peep_decide_whether_to_leave_park(Peep* peep) +static void peep_decide_whether_to_leave_park(Guest* peep) { if (peep->EnergyTarget >= 33) { @@ -2852,7 +3045,7 @@ static void peep_decide_whether_to_leave_park(Peep* peep) * * rct2: 0x0068F93E */ -static void peep_leave_park(Peep* peep) +static void peep_leave_park(Guest* peep) { peep->GuestHeadingToRideId = RIDE_ID_NULL; if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) @@ -3055,7 +3248,7 @@ void Guest::StopPurchaseThought(uint8_t ride_type) * * rct2: 0x0069AEB7 */ -static bool peep_should_use_cash_machine(Peep* peep, ride_id_t rideIndex) +static bool peep_should_use_cash_machine(Guest* peep, ride_id_t rideIndex) { if (gParkFlags & PARK_FLAGS_NO_MONEY) return false; @@ -3639,7 +3832,7 @@ void Guest::UpdateRideFreeVehicleEnterRide(Ride* ride) * * rct2: 0x00691FD4 */ -static void peep_update_ride_no_free_vehicle_rejoin_queue(Peep* peep, Ride* ride) +static void peep_update_ride_no_free_vehicle_rejoin_queue(Guest* peep, Ride* ride) { TileCoordsXYZD entranceLocation = ride_get_entrance_location(ride, peep->CurrentRideStation); @@ -4959,7 +5152,7 @@ void Guest::UpdateRide() } } -static void peep_update_walking_break_scenery(Peep* peep); +static void peep_update_walking_break_scenery(Guest* peep); static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, ride_id_t* rideToView, uint8_t* rideSeatToView); /** @@ -5850,7 +6043,7 @@ static PathElement* FindBreakableElement(const CoordsXYZ& loc) * * rct2: 0x00690848 */ -static void peep_update_walking_break_scenery(Peep* peep) +static void peep_update_walking_break_scenery(Guest* peep) { if (gCheatsDisableVandalism) return; @@ -6557,3 +6750,597 @@ bool Guest::HeadingForRideOrParkExit() const { return (PeepFlags & PEEP_FLAGS_LEAVING_PARK) || (GuestHeadingToRideId != RIDE_ID_NULL); } + +/** + * rct2: 0x00698342 + * thought.item (eax) + * thought.type (ebx) + * argument_1 (esi & ebx) + * argument_2 (esi+2) + */ +void peep_thought_set_format_args(const rct_peep_thought* thought, Formatter& ft) +{ + ft.Add(PeepThoughts[EnumValue(thought->type)]); + + PeepThoughtToActionFlag flags = PeepThoughtToActionMap[EnumValue(thought->type)].flags; + if (flags & PEEP_THOUGHT_ACTION_FLAG_RIDE) + { + auto ride = get_ride(thought->item); + if (ride != nullptr) + { + ride->FormatNameTo(ft); + } + else + { + ft.Add(STR_NONE); + } + } + else if (flags & PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR) + { + ft.Add(GetShopItemDescriptor(ShopItem(thought->item)).Naming.Singular); + } + else if (flags & PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE) + { + ft.Add(GetShopItemDescriptor(ShopItem(thought->item)).Naming.Indefinite); + } +} + +/** + * + * rct2: 0x699F5A + * al:thoughtType + * ah:thoughtArguments + * esi: peep + */ +void Guest::InsertNewThought(PeepThoughtType thoughtType, uint8_t thoughtArguments) +{ + PeepActionType newAction = PeepThoughtToActionMap[EnumValue(thoughtType)].action; + if (newAction != PeepActionType::None2 && this->Action >= PeepActionType::None1) + { + Action = newAction; + ActionFrame = 0; + ActionSpriteImageOffset = 0; + UpdateCurrentActionSpriteType(); + } + + 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 == PeepThoughtType::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; + + WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS; +} + +// clang-format off +/** rct2: 0x009823A0 */ +static constexpr const PeepNauseaTolerance nausea_tolerance_distribution[] = { + PeepNauseaTolerance::None, + PeepNauseaTolerance::Low, PeepNauseaTolerance::Low, + PeepNauseaTolerance::Average, PeepNauseaTolerance::Average, PeepNauseaTolerance::Average, + PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, +}; + +/** rct2: 0x009823BC */ +static constexpr const uint8_t trouser_colours[] = { + COLOUR_BLACK, + COLOUR_GREY, + COLOUR_LIGHT_BROWN, + COLOUR_SATURATED_BROWN, + COLOUR_DARK_BROWN, + COLOUR_SALMON_PINK, + COLOUR_BLACK, + COLOUR_GREY, + COLOUR_LIGHT_BROWN, + COLOUR_SATURATED_BROWN, + COLOUR_DARK_BROWN, + COLOUR_SALMON_PINK, + COLOUR_BLACK, + COLOUR_GREY, + COLOUR_LIGHT_BROWN, + COLOUR_SATURATED_BROWN, + COLOUR_DARK_BROWN, + COLOUR_SALMON_PINK, + COLOUR_DARK_PURPLE, + COLOUR_LIGHT_PURPLE, + COLOUR_DARK_BLUE, + COLOUR_SATURATED_GREEN, + COLOUR_SATURATED_RED, + COLOUR_DARK_ORANGE, + COLOUR_BORDEAUX_RED, +}; + +/** rct2: 0x009823D5 */ +static constexpr const uint8_t tshirt_colours[] = { + COLOUR_BLACK, + COLOUR_GREY, + COLOUR_LIGHT_BROWN, + COLOUR_SATURATED_BROWN, + COLOUR_DARK_BROWN, + COLOUR_SALMON_PINK, + COLOUR_BLACK, + COLOUR_GREY, + COLOUR_LIGHT_BROWN, + COLOUR_SATURATED_BROWN, + COLOUR_DARK_BROWN, + COLOUR_SALMON_PINK, + COLOUR_DARK_PURPLE, + COLOUR_LIGHT_PURPLE, + COLOUR_DARK_BLUE, + COLOUR_SATURATED_GREEN, + COLOUR_SATURATED_RED, + COLOUR_DARK_ORANGE, + COLOUR_BORDEAUX_RED, + COLOUR_WHITE, + COLOUR_BRIGHT_PURPLE, + COLOUR_LIGHT_BLUE, + COLOUR_TEAL, + COLOUR_DARK_GREEN, + COLOUR_MOSS_GREEN, + COLOUR_BRIGHT_GREEN, + COLOUR_OLIVE_GREEN, + COLOUR_DARK_OLIVE_GREEN, + COLOUR_YELLOW, + COLOUR_LIGHT_ORANGE, + COLOUR_BRIGHT_RED, + COLOUR_DARK_PINK, + COLOUR_BRIGHT_PINK, +}; +// clang-format on + +/** + * + * rct2: 0x0069A05D + */ +Guest* Guest::Generate(const CoordsXYZ& coords) +{ + if (GetNumFreeEntities() < 400) + return nullptr; + + Guest* peep = CreateEntity(); + peep->SpriteType = PeepSpriteType::Normal; + peep->OutsideOfPark = true; + peep->State = PeepState::Falling; + peep->Action = PeepActionType::None2; + peep->SpecialSprite = 0; + peep->ActionSpriteImageOffset = 0; + peep->WalkingFrameNum = 0; + peep->ActionSpriteType = PeepActionSpriteType::None; + peep->PeepFlags = 0; + peep->FavouriteRide = RIDE_ID_NULL; + peep->FavouriteRideRating = 0; + + const rct_sprite_bounds* spriteBounds = &GetSpriteBounds(peep->SpriteType, peep->ActionSpriteType); + peep->sprite_width = spriteBounds->sprite_width; + peep->sprite_height_negative = spriteBounds->sprite_height_negative; + peep->sprite_height_positive = spriteBounds->sprite_height_positive; + + peep->MoveTo(coords); + peep->sprite_direction = 0; + peep->Mass = (scenario_rand() & 0x1F) + 45; + peep->PathCheckOptimisation = 0; + peep->InteractionRideIndex = RIDE_ID_NULL; + peep->PreviousRide = RIDE_ID_NULL; + peep->Thoughts->type = PeepThoughtType::None; + peep->WindowInvalidateFlags = 0; + + uint8_t intensityHighest = (scenario_rand() & 0x7) + 3; + uint8_t intensityLowest = std::min(intensityHighest, static_cast(7)) - 3; + + if (intensityHighest >= 7) + intensityHighest = 15; + + /* Check which intensity boxes are enabled + * and apply the appropriate intensity settings. */ + if (gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) + { + if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + { + intensityLowest = 0; + intensityHighest = 15; + } + else + { + intensityLowest = 0; + intensityHighest = 4; + } + } + else if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + { + intensityLowest = 9; + intensityHighest = 15; + } + + peep->Intensity = IntensityRange(intensityLowest, intensityHighest); + + uint8_t nauseaTolerance = scenario_rand() & 0x7; + if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + { + nauseaTolerance += 4; + } + + peep->NauseaTolerance = 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 + * to any value 0..255. */ + peep->Happiness = gGuestInitialHappiness; + /* Assume a default initial happiness of 0 is wrong and set + * to 128 (50%) instead. */ + if (gGuestInitialHappiness == 0) + peep->Happiness = 128; + /* Initial value will vary by -15..16 */ + int8_t happinessDelta = (scenario_rand() & 0x1F) - 15; + /* Adjust by the delta, clamping at min=0 and max=255. */ + peep->Happiness = std::clamp(peep->Happiness + happinessDelta, 0, PEEP_MAX_HAPPINESS); + peep->HappinessTarget = peep->Happiness; + peep->Nausea = 0; + peep->NauseaTarget = 0; + + /* Scenario editor limits initial guest hunger to between 37..253. + * To be on the safe side, assume the value could have been hacked + * to any value 0..255. */ + peep->Hunger = gGuestInitialHunger; + /* 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, 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 + * to any value 0..255. */ + peep->Thirst = gGuestInitialThirst; + /* 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, PEEP_MAX_THIRST); + + peep->Toilet = 0; + peep->TimeToConsume = 0; + std::fill_n(peep->RidesBeenOn, 32, 0x00); + + peep->GuestNumRides = 0; + std::fill_n(peep->RideTypesBeenOn, 16, 0x00); + peep->Id = gNextGuestNumber++; + peep->Name = nullptr; + + money32 cash = (scenario_rand() & 0x3) * 100 - 100 + gGuestInitialCash; + if (cash < 0) + cash = 0; + + if (gGuestInitialCash == 0) + { + cash = 500; + } + + if (gParkFlags & PARK_FLAGS_NO_MONEY) + { + cash = 0; + } + + if (gGuestInitialCash == MONEY16_UNDEFINED) + { + cash = 0; + } + + peep->CashInPocket = cash; + peep->CashSpent = 0; + peep->ParkEntryTime = -1; + peep->ResetPathfindGoal(); + peep->RemoveAllItems(); + peep->GuestHeadingToRideId = RIDE_ID_NULL; + peep->LitterCount = 0; + peep->DisgustingCount = 0; + peep->VandalismSeen = 0; + peep->PaidToEnter = 0; + peep->PaidOnRides = 0; + peep->PaidOnFood = 0; + peep->PaidOnDrink = 0; + peep->PaidOnSouvenirs = 0; + peep->AmountOfFood = 0; + peep->AmountOfDrinks = 0; + peep->AmountOfSouvenirs = 0; + peep->SurroundingsThoughtTimeout = 0; + peep->Angriness = 0; + peep->TimeLost = 0; + + uint8_t tshirtColour = static_cast(scenario_rand() % std::size(tshirt_colours)); + peep->TshirtColour = tshirt_colours[tshirtColour]; + + uint8_t trousersColour = static_cast(scenario_rand() % std::size(trouser_colours)); + peep->TrousersColour = 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% */ + uint8_t energy = (scenario_rand() % 64) + 65; + peep->Energy = energy; + peep->EnergyTarget = energy; + + increment_guests_heading_for_park(); + +#ifdef ENABLE_SCRIPTING + auto& hookEngine = OpenRCT2::GetContext()->GetScriptEngine().GetHookEngine(); + if (hookEngine.HasSubscriptions(OpenRCT2::Scripting::HOOK_TYPE::GUEST_GENERATION)) + { + auto ctx = OpenRCT2::GetContext()->GetScriptEngine().GetContext(); + + // Create event args object + auto obj = OpenRCT2::Scripting::DukObject(ctx); + obj.Set("id", peep->sprite_index); + + // Call the subscriptions + auto e = obj.Take(); + hookEngine.Call(OpenRCT2::Scripting::HOOK_TYPE::GUEST_GENERATION, e, true); + } +#endif + + return peep; +} + +enum +{ + PEEP_FACE_OFFSET_ANGRY = 0, + PEEP_FACE_OFFSET_VERY_VERY_SICK, + PEEP_FACE_OFFSET_VERY_SICK, + PEEP_FACE_OFFSET_SICK, + PEEP_FACE_OFFSET_VERY_TIRED, + PEEP_FACE_OFFSET_TIRED, + PEEP_FACE_OFFSET_VERY_VERY_UNHAPPY, + PEEP_FACE_OFFSET_VERY_UNHAPPY, + PEEP_FACE_OFFSET_UNHAPPY, + PEEP_FACE_OFFSET_NORMAL, + PEEP_FACE_OFFSET_HAPPY, + PEEP_FACE_OFFSET_VERY_HAPPY, + PEEP_FACE_OFFSET_VERY_VERY_HAPPY, +}; + +static constexpr const int32_t face_sprite_small[] = { + SPR_PEEP_SMALL_FACE_ANGRY, + SPR_PEEP_SMALL_FACE_VERY_VERY_SICK, + SPR_PEEP_SMALL_FACE_VERY_SICK, + SPR_PEEP_SMALL_FACE_SICK, + SPR_PEEP_SMALL_FACE_VERY_TIRED, + SPR_PEEP_SMALL_FACE_TIRED, + SPR_PEEP_SMALL_FACE_VERY_VERY_UNHAPPY, + SPR_PEEP_SMALL_FACE_VERY_UNHAPPY, + SPR_PEEP_SMALL_FACE_UNHAPPY, + SPR_PEEP_SMALL_FACE_NORMAL, + SPR_PEEP_SMALL_FACE_HAPPY, + SPR_PEEP_SMALL_FACE_VERY_HAPPY, + SPR_PEEP_SMALL_FACE_VERY_VERY_HAPPY, +}; + +static constexpr const int32_t face_sprite_large[] = { + SPR_PEEP_LARGE_FACE_ANGRY_0, + SPR_PEEP_LARGE_FACE_VERY_VERY_SICK_0, + SPR_PEEP_LARGE_FACE_VERY_SICK_0, + SPR_PEEP_LARGE_FACE_SICK, + SPR_PEEP_LARGE_FACE_VERY_TIRED, + SPR_PEEP_LARGE_FACE_TIRED, + SPR_PEEP_LARGE_FACE_VERY_VERY_UNHAPPY, + SPR_PEEP_LARGE_FACE_VERY_UNHAPPY, + SPR_PEEP_LARGE_FACE_UNHAPPY, + SPR_PEEP_LARGE_FACE_NORMAL, + SPR_PEEP_LARGE_FACE_HAPPY, + SPR_PEEP_LARGE_FACE_VERY_HAPPY, + SPR_PEEP_LARGE_FACE_VERY_VERY_HAPPY, +}; + +static int32_t get_face_sprite_offset(Guest* peep) +{ + // ANGRY + if (peep->Angriness > 0) + return PEEP_FACE_OFFSET_ANGRY; + + // VERY_VERY_SICK + if (peep->Nausea > 200) + return PEEP_FACE_OFFSET_VERY_VERY_SICK; + + // VERY_SICK + if (peep->Nausea > 170) + return PEEP_FACE_OFFSET_VERY_SICK; + + // SICK + if (peep->Nausea > 140) + return PEEP_FACE_OFFSET_SICK; + + // VERY_TIRED + if (peep->Energy < 46) + return PEEP_FACE_OFFSET_VERY_TIRED; + + // TIRED + if (peep->Energy < 70) + return PEEP_FACE_OFFSET_TIRED; + + int32_t offset = PEEP_FACE_OFFSET_VERY_VERY_UNHAPPY; + // There are 7 different happiness based faces + for (int32_t i = 37; peep->Happiness >= i; i += 37) + { + offset++; + } + + return offset; +} + +/** + * Function split into large and small sprite + * rct2: 0x00698721 + */ +int32_t get_peep_face_sprite_small(Guest* peep) +{ + return face_sprite_small[get_face_sprite_offset(peep)]; +} + +/** + * Function split into large and small sprite + * rct2: 0x00698721 + */ +int32_t get_peep_face_sprite_large(Guest* peep) +{ + return face_sprite_large[get_face_sprite_offset(peep)]; +} + +/** + * + * rct2: 0x00693CBB + */ +bool Guest::UpdateQueuePosition(PeepActionType previous_action) +{ + TimeInQueue++; + + auto* guestNext = GetEntity(GuestNextInQueue); + if (guestNext == nullptr) + { + return false; + } + + int16_t x_diff = abs(guestNext->x - x); + int16_t y_diff = abs(guestNext->y - y); + int16_t z_diff = abs(guestNext->z - z); + + if (z_diff > 10) + return false; + + if (x_diff < y_diff) + { + int16_t temp_x = x_diff; + x_diff = y_diff; + y_diff = temp_x; + } + + x_diff += y_diff / 2; + if (x_diff > 7) + { + if (x_diff > 13) + { + if ((x & 0xFFE0) != (guestNext->x & 0xFFE0) || (y & 0xFFE0) != (guestNext->y & 0xFFE0)) + return false; + } + + if (sprite_direction != guestNext->sprite_direction) + return false; + + switch (guestNext->sprite_direction / 8) + { + case 0: + if (x >= guestNext->x) + return false; + break; + case 1: + if (y <= guestNext->y) + return false; + break; + case 2: + if (x <= guestNext->x) + return false; + break; + case 3: + if (y >= guestNext->y) + return false; + break; + } + } + + if (Action < PeepActionType::None1) + UpdateAction(); + + if (Action != PeepActionType::None2) + return true; + + Action = PeepActionType::None1; + NextActionSpriteType = PeepActionSpriteType::WatchRide; + if (previous_action != PeepActionType::None1) + Invalidate(); + return true; +} + +/** + * + * rct2: 0x006966A9 + */ +void Guest::RemoveFromQueue() +{ + auto ride = get_ride(CurrentRide); + if (ride == nullptr) + return; + + auto& station = ride->stations[CurrentRideStation]; + // Make sure we don't underflow, building while paused might reset it to 0 where peeps have + // not yet left the queue. + if (station.QueueLength > 0) + { + station.QueueLength--; + } + + if (sprite_index == station.LastPeepInQueue) + { + station.LastPeepInQueue = GuestNextInQueue; + return; + } + + auto* otherGuest = GetEntity(station.LastPeepInQueue); + if (otherGuest == nullptr) + { + log_error("Invalid Guest Queue list!"); + return; + } + for (; otherGuest != nullptr; otherGuest = GetEntity(otherGuest->GuestNextInQueue)) + { + if (sprite_index == otherGuest->GuestNextInQueue) + { + otherGuest->GuestNextInQueue = GuestNextInQueue; + return; + } + } +} + +uint64_t Guest::GetItemFlags() const +{ + return ItemFlags; +} + +void Guest::SetItemFlags(uint64_t itemFlags) +{ + ItemFlags = itemFlags; +} + +void Guest::RemoveAllItems() +{ + ItemFlags = 0; +} + +void Guest::RemoveItem(ShopItem item) +{ + ItemFlags &= ~EnumToFlag(item); +} + +void Guest::GiveItem(ShopItem item) +{ + ItemFlags |= EnumToFlag(item); +} + +bool Guest::HasItem(ShopItem peepItem) const +{ + return GetItemFlags() & EnumToFlag(peepItem); +} diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index cf98e8a69e..57ac7c0b09 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -493,15 +493,19 @@ static uint8_t peep_pathfind_get_max_number_junctions(Peep* peep) return 8; } - if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK && peep->GuestIsLostCountdown < 90) + auto* guest = peep->As(); + if (guest == nullptr) + return 8; + + if (guest->PeepFlags & PEEP_FLAGS_LEAVING_PARK && guest->GuestIsLostCountdown < 90) { return 8; } - if (peep->HasItem(ShopItem::Map)) + if (guest->HasItem(ShopItem::Map)) return 7; - if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) + if (guest->PeepFlags & PEEP_FLAGS_LEAVING_PARK) return 7; return 5; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index f6dc7d7a47..daf4e082cc 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -31,8 +31,6 @@ #include "../ride/Station.h" #include "../ride/Track.h" #include "../scenario/Scenario.h" -#include "../scripting/HookEngine.h" -#include "../scripting/ScriptEngine.h" #include "../sprites.h" #include "../util/Util.h" #include "../windows/Intent.h" @@ -76,197 +74,6 @@ static void peep_128_tick_update(Peep* peep, int32_t index); static void peep_release_balloon(Guest* peep, int16_t spawn_height); // clang-format off -// Flags used by PeepThoughtToActionMap -enum PeepThoughtToActionFlag : uint8_t -{ - PEEP_THOUGHT_ACTION_NO_FLAGS = 0, - PEEP_THOUGHT_ACTION_FLAG_RIDE = (1 << 0), - PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR = (1 << 1), - PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE = (1 << 2), -}; - -/** rct2: 0x00981DB0 */ -static struct -{ - PeepActionType action; - PeepThoughtToActionFlag flags; -} PeepThoughtToActionMap[] = { - { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::EmptyPockets, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::Wow, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE }, - { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::Wave, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::Joy, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::CheckTime, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::Wave, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::Wave, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::Disgust, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::BeingWatched, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::ShakeHead, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::Joy, PEEP_THOUGHT_ACTION_NO_FLAGS }, - { PeepActionType::None2, PEEP_THOUGHT_ACTION_FLAG_RIDE }, -}; - static PeepActionSpriteType PeepSpecialSpriteToSpriteTypeMap[] = { PeepActionSpriteType::None, PeepActionSpriteType::HoldMat, @@ -379,11 +186,6 @@ bool Peep::CanBePickedUp() const return false; } -Peep* try_get_guest(uint16_t spriteIndex) -{ - return TryGetEntity(spriteIndex); -} - int32_t peep_get_staff_count() { return GetEntityListCount(EntityType::Staff); @@ -653,20 +455,21 @@ std::optional Peep::UpdateAction(int16_t& xy_distance) } ActionSpriteImageOffset = peepAnimation[EnumValue(ActionSpriteType)].frame_offsets[ActionFrame]; + auto* guest = As(); // If not throwing up and not at the frame where sick appears. - if (Action != PeepActionType::ThrowUp || ActionFrame != 15) + if (Action != PeepActionType::ThrowUp || ActionFrame != 15 || guest == nullptr) { return { { x, y } }; } // We are throwing up - Hunger /= 2; - NauseaTarget /= 2; + guest->Hunger /= 2; + guest->NauseaTarget /= 2; - if (Nausea < 30) - Nausea = 0; + if (guest->Nausea < 30) + guest->Nausea = 0; else - Nausea -= 30; + guest->Nausea -= 30; WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_2; @@ -811,11 +614,11 @@ std::unique_ptr Peep::Place(const TileCoordsXYZ& location, ActionSpriteType = PeepActionSpriteType::None; PathCheckOptimisation = 0; EntityTweener::Get().Reset(); - - if (Is()) + auto* guest = As(); + if (guest != nullptr) { ActionSpriteType = PeepActionSpriteType::Invalid; - HappinessTarget = std::max(HappinessTarget - 10, 0); + guest->HappinessTarget = std::max(guest->HappinessTarget - 10, 0); UpdateCurrentActionSpriteType(); } } @@ -840,18 +643,19 @@ void peep_sprite_remove(Peep* peep) window_close_by_number(WC_FIRE_PROMPT, EnumValue(peep->Type)); + auto* staff = peep->As(); // Needed for invalidations after sprite removal - bool wasGuest = peep->Is(); + bool wasGuest = staff == nullptr; if (wasGuest) { News::DisableNewsItems(News::ItemType::PeepOnRide, peep->sprite_index); } else { - gStaffModes[peep->StaffId] = StaffMode::None; + gStaffModes[staff->StaffId] = StaffMode::None; staff_update_greyed_patrol_areas(); - News::DisableNewsItems(News::ItemType::Peep, peep->sprite_index); + News::DisableNewsItems(News::ItemType::Peep, staff->sprite_index); } sprite_remove(peep); @@ -864,9 +668,10 @@ void peep_sprite_remove(Peep* peep) */ void Peep::Remove() { - if (Is()) + auto* guest = As(); + if (guest != nullptr) { - if (!OutsideOfPark) + if (!guest->OutsideOfPark) { decrement_guests_in_park(); auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT); @@ -946,10 +751,9 @@ void Peep::UpdateFalling() { // Drop balloon if held peep_release_balloon(guest, height); + guest->InsertNewThought(PeepThoughtType::Drowning, PEEP_THOUGHT_ITEM_NONE); } - InsertNewThought(PeepThoughtType::Drowning, PEEP_THOUGHT_ITEM_NONE); - Action = PeepActionType::Drowning; ActionFrame = 0; ActionSpriteImageOffset = 0; @@ -1036,14 +840,15 @@ void Peep::UpdatePicked() if (gCurrentTicks & 0x1F) return; SubState++; - if (SubState == 13) + auto* guest = As(); + if (SubState == 13 && guest != nullptr) { - InsertNewThought(PeepThoughtType::Help, PEEP_THOUGHT_ITEM_NONE); + guest->InsertNewThought(PeepThoughtType::Help, PEEP_THOUGHT_ITEM_NONE); } } /* From peep_update */ -static void peep_update_thoughts(Peep* peep) +static void peep_update_thoughts(Guest* peep) { // Thoughts must always have a gap of at least // 220 ticks in age between them. In order to @@ -1109,13 +914,14 @@ static void peep_update_thoughts(Peep* peep) */ void Peep::Update() { - if (Is()) + auto* guest = As(); + if (guest != nullptr) { - if (PreviousRide != RIDE_ID_NULL) - if (++PreviousRideTimeOut >= 720) - PreviousRide = RIDE_ID_NULL; + if (guest->PreviousRide != RIDE_ID_NULL) + if (++guest->PreviousRideTimeOut >= 720) + guest->PreviousRide = RIDE_ID_NULL; - peep_update_thoughts(this); + peep_update_thoughts(guest); } // Walking speed logic @@ -1135,7 +941,6 @@ void Peep::Update() StepProgress = carryCheck; if (carryCheck <= 255) { - auto* guest = As(); if (guest != nullptr) { guest->UpdateEasterEggInteractions(); @@ -1160,7 +965,6 @@ void Peep::Update() break; default: { - auto* guest = As(); if (guest != nullptr) { guest->UpdateGuest(); @@ -1475,319 +1279,6 @@ void peep_update_days_in_queue() } } -// clang-format off -/** rct2: 0x009823A0 */ -static constexpr const PeepNauseaTolerance nausea_tolerance_distribution[] = { - PeepNauseaTolerance::None, - PeepNauseaTolerance::Low, PeepNauseaTolerance::Low, - PeepNauseaTolerance::Average, PeepNauseaTolerance::Average, PeepNauseaTolerance::Average, - PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, PeepNauseaTolerance::High, -}; - -/** rct2: 0x009823BC */ -static constexpr const uint8_t trouser_colours[] = { - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_DARK_PURPLE, - COLOUR_LIGHT_PURPLE, - COLOUR_DARK_BLUE, - COLOUR_SATURATED_GREEN, - COLOUR_SATURATED_RED, - COLOUR_DARK_ORANGE, - COLOUR_BORDEAUX_RED, -}; - -/** rct2: 0x009823D5 */ -static constexpr const uint8_t tshirt_colours[] = { - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_DARK_PURPLE, - COLOUR_LIGHT_PURPLE, - COLOUR_DARK_BLUE, - COLOUR_SATURATED_GREEN, - COLOUR_SATURATED_RED, - COLOUR_DARK_ORANGE, - COLOUR_BORDEAUX_RED, - COLOUR_WHITE, - COLOUR_BRIGHT_PURPLE, - COLOUR_LIGHT_BLUE, - COLOUR_TEAL, - COLOUR_DARK_GREEN, - COLOUR_MOSS_GREEN, - COLOUR_BRIGHT_GREEN, - COLOUR_OLIVE_GREEN, - COLOUR_DARK_OLIVE_GREEN, - COLOUR_YELLOW, - COLOUR_LIGHT_ORANGE, - COLOUR_BRIGHT_RED, - COLOUR_DARK_PINK, - COLOUR_BRIGHT_PINK, -}; -// clang-format on - -/** - * - * rct2: 0x699F5A - * al:thoughtType - * ah:thoughtArguments - * esi: peep - */ -void Peep::InsertNewThought(PeepThoughtType thoughtType, uint8_t thoughtArguments) -{ - PeepActionType newAction = PeepThoughtToActionMap[EnumValue(thoughtType)].action; - if (newAction != PeepActionType::None2 && this->Action >= PeepActionType::None1) - { - Action = newAction; - ActionFrame = 0; - ActionSpriteImageOffset = 0; - UpdateCurrentActionSpriteType(); - } - - 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 == PeepThoughtType::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; - - WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS; -} - -/** - * - * rct2: 0x0069A05D - */ -Peep* Peep::Generate(const CoordsXYZ& coords) -{ - if (GetNumFreeEntities() < 400) - return nullptr; - - Peep* peep = CreateEntity(); - peep->SpriteType = PeepSpriteType::Normal; - peep->OutsideOfPark = true; - peep->State = PeepState::Falling; - peep->Action = PeepActionType::None2; - peep->SpecialSprite = 0; - peep->ActionSpriteImageOffset = 0; - peep->WalkingFrameNum = 0; - peep->ActionSpriteType = PeepActionSpriteType::None; - peep->PeepFlags = 0; - peep->FavouriteRide = RIDE_ID_NULL; - peep->FavouriteRideRating = 0; - - const rct_sprite_bounds* spriteBounds = &GetSpriteBounds(peep->SpriteType, peep->ActionSpriteType); - peep->sprite_width = spriteBounds->sprite_width; - peep->sprite_height_negative = spriteBounds->sprite_height_negative; - peep->sprite_height_positive = spriteBounds->sprite_height_positive; - - peep->MoveTo(coords); - peep->sprite_direction = 0; - peep->Mass = (scenario_rand() & 0x1F) + 45; - peep->PathCheckOptimisation = 0; - peep->InteractionRideIndex = RIDE_ID_NULL; - peep->PreviousRide = RIDE_ID_NULL; - peep->Thoughts->type = PeepThoughtType::None; - peep->WindowInvalidateFlags = 0; - - uint8_t intensityHighest = (scenario_rand() & 0x7) + 3; - uint8_t intensityLowest = std::min(intensityHighest, static_cast(7)) - 3; - - if (intensityHighest >= 7) - intensityHighest = 15; - - /* Check which intensity boxes are enabled - * and apply the appropriate intensity settings. */ - if (gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) - { - if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) - { - intensityLowest = 0; - intensityHighest = 15; - } - else - { - intensityLowest = 0; - intensityHighest = 4; - } - } - else if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) - { - intensityLowest = 9; - intensityHighest = 15; - } - - peep->Intensity = IntensityRange(intensityLowest, intensityHighest); - - uint8_t nauseaTolerance = scenario_rand() & 0x7; - if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) - { - nauseaTolerance += 4; - } - - peep->NauseaTolerance = 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 - * to any value 0..255. */ - peep->Happiness = gGuestInitialHappiness; - /* Assume a default initial happiness of 0 is wrong and set - * to 128 (50%) instead. */ - if (gGuestInitialHappiness == 0) - peep->Happiness = 128; - /* Initial value will vary by -15..16 */ - int8_t happinessDelta = (scenario_rand() & 0x1F) - 15; - /* Adjust by the delta, clamping at min=0 and max=255. */ - peep->Happiness = std::clamp(peep->Happiness + happinessDelta, 0, PEEP_MAX_HAPPINESS); - peep->HappinessTarget = peep->Happiness; - peep->Nausea = 0; - peep->NauseaTarget = 0; - - /* Scenario editor limits initial guest hunger to between 37..253. - * To be on the safe side, assume the value could have been hacked - * to any value 0..255. */ - peep->Hunger = gGuestInitialHunger; - /* 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, 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 - * to any value 0..255. */ - peep->Thirst = gGuestInitialThirst; - /* 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, PEEP_MAX_THIRST); - - peep->Toilet = 0; - peep->TimeToConsume = 0; - std::fill_n(peep->RidesBeenOn, 32, 0x00); - - peep->GuestNumRides = 0; - std::fill_n(peep->RideTypesBeenOn, 16, 0x00); - peep->Id = gNextGuestNumber++; - peep->Name = nullptr; - - money32 cash = (scenario_rand() & 0x3) * 100 - 100 + gGuestInitialCash; - if (cash < 0) - cash = 0; - - if (gGuestInitialCash == 0) - { - cash = 500; - } - - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - cash = 0; - } - - if (gGuestInitialCash == MONEY16_UNDEFINED) - { - cash = 0; - } - - peep->CashInPocket = cash; - peep->CashSpent = 0; - peep->ParkEntryTime = -1; - peep->ResetPathfindGoal(); - peep->RemoveAllItems(); - peep->GuestHeadingToRideId = RIDE_ID_NULL; - peep->LitterCount = 0; - peep->DisgustingCount = 0; - peep->VandalismSeen = 0; - peep->PaidToEnter = 0; - peep->PaidOnRides = 0; - peep->PaidOnFood = 0; - peep->PaidOnDrink = 0; - peep->PaidOnSouvenirs = 0; - peep->AmountOfFood = 0; - peep->AmountOfDrinks = 0; - peep->AmountOfSouvenirs = 0; - peep->SurroundingsThoughtTimeout = 0; - peep->Angriness = 0; - peep->TimeLost = 0; - - uint8_t tshirtColour = static_cast(scenario_rand() % std::size(tshirt_colours)); - peep->TshirtColour = tshirt_colours[tshirtColour]; - - uint8_t trousersColour = static_cast(scenario_rand() % std::size(trouser_colours)); - peep->TrousersColour = 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% */ - uint8_t energy = (scenario_rand() % 64) + 65; - peep->Energy = energy; - peep->EnergyTarget = energy; - - increment_guests_heading_for_park(); - -#ifdef ENABLE_SCRIPTING - auto& hookEngine = OpenRCT2::GetContext()->GetScriptEngine().GetHookEngine(); - if (hookEngine.HasSubscriptions(OpenRCT2::Scripting::HOOK_TYPE::GUEST_GENERATION)) - { - auto ctx = OpenRCT2::GetContext()->GetScriptEngine().GetContext(); - - // Create event args object - auto obj = OpenRCT2::Scripting::DukObject(ctx); - obj.Set("id", peep->sprite_index); - - // Call the subscriptions - auto e = obj.Take(); - hookEngine.Call(OpenRCT2::Scripting::HOOK_TYPE::GUEST_GENERATION, e, true); - } -#endif - - return peep; -} - void Peep::FormatActionTo(Formatter& ft) const { switch (State) @@ -1831,20 +1322,26 @@ void Peep::FormatActionTo(Formatter& ft) const } case PeepState::Walking: case PeepState::UsingBin: - if (GuestHeadingToRideId != RIDE_ID_NULL) + { + auto* guest = As(); + if (guest != nullptr) { - auto ride = get_ride(GuestHeadingToRideId); - if (ride != nullptr) + if (guest->GuestHeadingToRideId != RIDE_ID_NULL) { - ft.Add(STR_HEADING_FOR); - ride->FormatNameTo(ft); + auto ride = get_ride(guest->GuestHeadingToRideId); + if (ride != nullptr) + { + ft.Add(STR_HEADING_FOR); + ride->FormatNameTo(ft); + } + } + else + { + ft.Add((PeepFlags & PEEP_FLAGS_LEAVING_PARK) ? STR_LEAVING_PARK : STR_WALKING); } } - else - { - ft.Add((PeepFlags & PEEP_FLAGS_LEAVING_PARK) ? STR_LEAVING_PARK : STR_WALKING); - } break; + } case PeepState::QueuingFront: case PeepState::Queuing: { @@ -1966,7 +1463,8 @@ void Peep::FormatNameTo(Formatter& ft) const { if (Name == nullptr) { - if (Is()) + auto* staff = As(); + if (staff != nullptr) { static constexpr const rct_string_id staffNames[] = { STR_HANDYMAN_X, @@ -1975,7 +1473,7 @@ void Peep::FormatNameTo(Formatter& ft) const STR_ENTERTAINER_X, }; - auto staffNameIndex = static_cast(AssignedStaffType); + auto staffNameIndex = static_cast(staff->AssignedStaffType); if (staffNameIndex > sizeof(staffNames)) { staffNameIndex = 0; @@ -2030,152 +1528,16 @@ bool Peep::SetName(std::string_view value) return false; } -/** - * rct2: 0x00698342 - * thought.item (eax) - * thought.type (ebx) - * argument_1 (esi & ebx) - * argument_2 (esi+2) - */ -void peep_thought_set_format_args(const rct_peep_thought* thought, Formatter& ft) -{ - ft.Add(PeepThoughts[EnumValue(thought->type)]); - - PeepThoughtToActionFlag flags = PeepThoughtToActionMap[EnumValue(thought->type)].flags; - if (flags & PEEP_THOUGHT_ACTION_FLAG_RIDE) - { - auto ride = get_ride(thought->item); - if (ride != nullptr) - { - ride->FormatNameTo(ft); - } - else - { - ft.Add(STR_NONE); - } - } - else if (flags & PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_SINGULAR) - { - ft.Add(GetShopItemDescriptor(ShopItem(thought->item)).Naming.Singular); - } - else if (flags & PEEP_THOUGHT_ACTION_FLAG_SHOP_ITEM_INDEFINITE) - { - ft.Add(GetShopItemDescriptor(ShopItem(thought->item)).Naming.Indefinite); - } -} - -enum -{ - PEEP_FACE_OFFSET_ANGRY = 0, - PEEP_FACE_OFFSET_VERY_VERY_SICK, - PEEP_FACE_OFFSET_VERY_SICK, - PEEP_FACE_OFFSET_SICK, - PEEP_FACE_OFFSET_VERY_TIRED, - PEEP_FACE_OFFSET_TIRED, - PEEP_FACE_OFFSET_VERY_VERY_UNHAPPY, - PEEP_FACE_OFFSET_VERY_UNHAPPY, - PEEP_FACE_OFFSET_UNHAPPY, - PEEP_FACE_OFFSET_NORMAL, - PEEP_FACE_OFFSET_HAPPY, - PEEP_FACE_OFFSET_VERY_HAPPY, - PEEP_FACE_OFFSET_VERY_VERY_HAPPY, -}; - -static constexpr const int32_t face_sprite_small[] = { - SPR_PEEP_SMALL_FACE_ANGRY, - SPR_PEEP_SMALL_FACE_VERY_VERY_SICK, - SPR_PEEP_SMALL_FACE_VERY_SICK, - SPR_PEEP_SMALL_FACE_SICK, - SPR_PEEP_SMALL_FACE_VERY_TIRED, - SPR_PEEP_SMALL_FACE_TIRED, - SPR_PEEP_SMALL_FACE_VERY_VERY_UNHAPPY, - SPR_PEEP_SMALL_FACE_VERY_UNHAPPY, - SPR_PEEP_SMALL_FACE_UNHAPPY, - SPR_PEEP_SMALL_FACE_NORMAL, - SPR_PEEP_SMALL_FACE_HAPPY, - SPR_PEEP_SMALL_FACE_VERY_HAPPY, - SPR_PEEP_SMALL_FACE_VERY_VERY_HAPPY, -}; - -static constexpr const int32_t face_sprite_large[] = { - SPR_PEEP_LARGE_FACE_ANGRY_0, - SPR_PEEP_LARGE_FACE_VERY_VERY_SICK_0, - SPR_PEEP_LARGE_FACE_VERY_SICK_0, - SPR_PEEP_LARGE_FACE_SICK, - SPR_PEEP_LARGE_FACE_VERY_TIRED, - SPR_PEEP_LARGE_FACE_TIRED, - SPR_PEEP_LARGE_FACE_VERY_VERY_UNHAPPY, - SPR_PEEP_LARGE_FACE_VERY_UNHAPPY, - SPR_PEEP_LARGE_FACE_UNHAPPY, - SPR_PEEP_LARGE_FACE_NORMAL, - SPR_PEEP_LARGE_FACE_HAPPY, - SPR_PEEP_LARGE_FACE_VERY_HAPPY, - SPR_PEEP_LARGE_FACE_VERY_VERY_HAPPY, -}; - -static int32_t get_face_sprite_offset(Peep* peep) -{ - // ANGRY - if (peep->Angriness > 0) - return PEEP_FACE_OFFSET_ANGRY; - - // VERY_VERY_SICK - if (peep->Nausea > 200) - return PEEP_FACE_OFFSET_VERY_VERY_SICK; - - // VERY_SICK - if (peep->Nausea > 170) - return PEEP_FACE_OFFSET_VERY_SICK; - - // SICK - if (peep->Nausea > 140) - return PEEP_FACE_OFFSET_SICK; - - // VERY_TIRED - if (peep->Energy < 46) - return PEEP_FACE_OFFSET_VERY_TIRED; - - // TIRED - if (peep->Energy < 70) - return PEEP_FACE_OFFSET_TIRED; - - int32_t offset = PEEP_FACE_OFFSET_VERY_VERY_UNHAPPY; - // There are 7 different happiness based faces - for (int32_t i = 37; peep->Happiness >= i; i += 37) - { - offset++; - } - - return offset; -} - -/** - * Function split into large and small sprite - * rct2: 0x00698721 - */ -int32_t get_peep_face_sprite_small(Peep* peep) -{ - return face_sprite_small[get_face_sprite_offset(peep)]; -} - -/** - * Function split into large and small sprite - * rct2: 0x00698721 - */ -int32_t get_peep_face_sprite_large(Peep* peep) -{ - return face_sprite_large[get_face_sprite_offset(peep)]; -} - void peep_set_map_tooltip(Peep* peep) { auto ft = Formatter(); - if (peep->Is()) + auto* guest = peep->As(); + if (guest != nullptr) { ft.Add((peep->PeepFlags & PEEP_FLAGS_TRACKING) ? STR_TRACKED_GUEST_MAP_TIP : STR_GUEST_MAP_TIP); - ft.Add(get_peep_face_sprite_small(peep)); - peep->FormatNameTo(ft); - peep->FormatActionTo(ft); + ft.Add(get_peep_face_sprite_small(guest)); + guest->FormatNameTo(ft); + guest->FormatActionTo(ft); } else { @@ -2207,80 +1569,6 @@ void Peep::SwitchNextActionSpriteType() } } -/** - * - * rct2: 0x00693CBB - */ -static bool peep_update_queue_position(Peep* peep, PeepActionType previous_action) -{ - peep->TimeInQueue++; - - auto* guestNext = GetEntity(peep->GuestNextInQueue); - if (guestNext == nullptr) - { - return false; - } - - int16_t x_diff = abs(guestNext->x - peep->x); - int16_t y_diff = abs(guestNext->y - peep->y); - int16_t z_diff = abs(guestNext->z - peep->z); - - if (z_diff > 10) - return false; - - if (x_diff < y_diff) - { - int16_t temp_x = x_diff; - x_diff = y_diff; - y_diff = temp_x; - } - - x_diff += y_diff / 2; - if (x_diff > 7) - { - if (x_diff > 13) - { - if ((peep->x & 0xFFE0) != (guestNext->x & 0xFFE0) || (peep->y & 0xFFE0) != (guestNext->y & 0xFFE0)) - return false; - } - - if (peep->sprite_direction != guestNext->sprite_direction) - return false; - - switch (guestNext->sprite_direction / 8) - { - case 0: - if (peep->x >= guestNext->x) - return false; - break; - case 1: - if (peep->y <= guestNext->y) - return false; - break; - case 2: - if (peep->x <= guestNext->x) - return false; - break; - case 3: - if (peep->y >= guestNext->y) - return false; - break; - } - } - - if (peep->Action < PeepActionType::None1) - peep->UpdateAction(); - - if (peep->Action != PeepActionType::None2) - return true; - - peep->Action = PeepActionType::None1; - peep->NextActionSpriteType = PeepActionSpriteType::WatchRide; - if (previous_action != PeepActionType::None1) - peep->Invalidate(); - return true; -} - /** * * rct2: 0x00693EF2 @@ -2350,26 +1638,26 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin return true; } - if (peep->State == PeepState::Queuing) + if (guest->State == PeepState::Queuing) { // Guest is in the ride queue. - peep->RideSubState = PeepRideSubState::AtQueueFront; - peep->ActionSpriteImageOffset = _unk_F1AEF0; + guest->RideSubState = PeepRideSubState::AtQueueFront; + guest->ActionSpriteImageOffset = _unk_F1AEF0; return true; } // Guest is on a normal path, i.e. ride has no queue. - if (peep->InteractionRideIndex == rideIndex) + if (guest->InteractionRideIndex == rideIndex) { // Peep is retrying the ride entrance without leaving // the path tile and without trying any other ride // attached to this path tile. i.e. stick with the // peeps previous decision not to go on the ride. - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } - peep->TimeLost = 0; + guest->TimeLost = 0; auto stationNum = tile_element->AsEntrance()->GetStationIndex(); // Guest walks up to the ride for the first time since entering // the path tile or since considering another ride attached to @@ -2378,35 +1666,35 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin { // Peep remembers that this is the last ride they // considered while on this path tile. - peep->InteractionRideIndex = rideIndex; - peep_return_to_centre_of_tile(peep); + guest->InteractionRideIndex = rideIndex; + peep_return_to_centre_of_tile(guest); return true; } // Guest has decided to go on the ride. - peep->ActionSpriteImageOffset = _unk_F1AEF0; - peep->InteractionRideIndex = rideIndex; + guest->ActionSpriteImageOffset = _unk_F1AEF0; + guest->InteractionRideIndex = rideIndex; uint16_t previous_last = ride->stations[stationNum].LastPeepInQueue; - ride->stations[stationNum].LastPeepInQueue = peep->sprite_index; - peep->GuestNextInQueue = previous_last; + ride->stations[stationNum].LastPeepInQueue = guest->sprite_index; + guest->GuestNextInQueue = previous_last; ride->stations[stationNum].QueueLength++; - peep->CurrentRide = rideIndex; - peep->CurrentRideStation = stationNum; - peep->DaysInQueue = 0; - peep->SetState(PeepState::Queuing); - peep->RideSubState = PeepRideSubState::AtQueueFront; - peep->TimeInQueue = 0; - if (peep->PeepFlags & PEEP_FLAGS_TRACKING) + guest->CurrentRide = rideIndex; + guest->CurrentRideStation = stationNum; + guest->DaysInQueue = 0; + guest->SetState(PeepState::Queuing); + guest->RideSubState = PeepRideSubState::AtQueueFront; + guest->TimeInQueue = 0; + if (guest->PeepFlags & PEEP_FLAGS_TRACKING) { auto ft = Formatter(); - peep->FormatNameTo(ft); + guest->FormatNameTo(ft); ride->FormatNameTo(ft); if (gConfigNotifications.guest_queuing_for_ride) { News::AddItemToQueue( - News::ItemType::PeepOnRide, STR_PEEP_TRACKING_PEEP_JOINED_QUEUE_FOR_X, peep->sprite_index, ft); + News::ItemType::PeepOnRide, STR_PEEP_TRACKING_PEEP_JOINED_QUEUE_FOR_X, guest->sprite_index, ft); } } } @@ -2424,49 +1712,49 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin // If not the centre of the entrance arch if (tile_element->AsEntrance()->GetSequenceIndex() != 0) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } uint8_t entranceDirection = tile_element->GetDirection(); - if (entranceDirection != peep->PeepDirection) + if (entranceDirection != guest->PeepDirection) { - if (direction_reverse(entranceDirection) != peep->PeepDirection) + if (direction_reverse(entranceDirection) != guest->PeepDirection) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } // Peep is leaving the park. - if (peep->State != PeepState::Walking) + if (guest->State != PeepState::Walking) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } - if (!(peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK)) + if (!(guest->PeepFlags & PEEP_FLAGS_LEAVING_PARK)) { // If the park is open and leaving flag isn't set return to centre if (gParkFlags & PARK_FLAGS_PARK_OPEN) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } } - auto destination = peep->GetDestination() + CoordsDirectionDelta[peep->PeepDirection]; - peep->SetDestination(destination, 9); - peep->MoveTo({ coords, peep->z }); - peep->SetState(PeepState::LeavingPark); + auto destination = guest->GetDestination() + CoordsDirectionDelta[guest->PeepDirection]; + guest->SetDestination(destination, 9); + guest->MoveTo({ coords, guest->z }); + guest->SetState(PeepState::LeavingPark); - peep->Var37 = 0; - if (peep->PeepFlags & PEEP_FLAGS_TRACKING) + guest->Var37 = 0; + if (guest->PeepFlags & PEEP_FLAGS_TRACKING) { auto ft = Formatter(); - peep->FormatNameTo(ft); + guest->FormatNameTo(ft); if (gConfigNotifications.guest_left_park) { - News::AddItemToQueue(News::ItemType::PeepOnRide, STR_PEEP_TRACKING_LEFT_PARK, peep->sprite_index, ft); + News::AddItemToQueue(News::ItemType::PeepOnRide, STR_PEEP_TRACKING_LEFT_PARK, guest->sprite_index, ft); } } return true; @@ -2474,19 +1762,19 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin // Peep is entering the park. - if (peep->State != PeepState::EnteringPark) + if (guest->State != PeepState::EnteringPark) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } if (!(gParkFlags & PARK_FLAGS_PARK_OPEN)) { - peep->State = PeepState::LeavingPark; - peep->Var37 = 1; + guest->State = PeepState::LeavingPark; + guest->Var37 = 1; decrement_guests_heading_for_park(); - peep_window_state_update(peep); - peep_return_to_centre_of_tile(peep); + peep_window_state_update(guest); + peep_return_to_centre_of_tile(guest); return true; } @@ -2546,55 +1834,55 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin if (!found) { - peep->State = PeepState::LeavingPark; - peep->Var37 = 1; + guest->State = PeepState::LeavingPark; + guest->Var37 = 1; decrement_guests_heading_for_park(); - peep_window_state_update(peep); - peep_return_to_centre_of_tile(peep); + peep_window_state_update(guest); + peep_return_to_centre_of_tile(guest); return true; } money16 entranceFee = park_get_entrance_fee(); if (entranceFee != 0) { - if (peep->HasItem(ShopItem::Voucher)) + if (guest->HasItem(ShopItem::Voucher)) { - if (peep->VoucherType == VOUCHER_TYPE_PARK_ENTRY_HALF_PRICE) + if (guest->VoucherType == VOUCHER_TYPE_PARK_ENTRY_HALF_PRICE) { entranceFee /= 2; - peep->RemoveItem(ShopItem::Voucher); - peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY; + guest->RemoveItem(ShopItem::Voucher); + guest->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY; } - else if (peep->VoucherType == VOUCHER_TYPE_PARK_ENTRY_FREE) + else if (guest->VoucherType == VOUCHER_TYPE_PARK_ENTRY_FREE) { entranceFee = 0; - peep->RemoveItem(ShopItem::Voucher); - peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY; + guest->RemoveItem(ShopItem::Voucher); + guest->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY; } } - if (entranceFee > peep->CashInPocket) + if (entranceFee > guest->CashInPocket) { - peep->State = PeepState::LeavingPark; - peep->Var37 = 1; + guest->State = PeepState::LeavingPark; + guest->Var37 = 1; decrement_guests_heading_for_park(); - peep_window_state_update(peep); - peep_return_to_centre_of_tile(peep); + peep_window_state_update(guest); + peep_return_to_centre_of_tile(guest); return true; } gTotalIncomeFromAdmissions += entranceFee; - guest->SpendMoney(peep->PaidToEnter, entranceFee, ExpenditureType::ParkEntranceTickets); - peep->PeepFlags |= PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY; + guest->SpendMoney(guest->PaidToEnter, entranceFee, ExpenditureType::ParkEntranceTickets); + guest->PeepFlags |= PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY; } gTotalAdmissions++; window_invalidate_by_number(WC_PARK_INFORMATION, 0); - peep->Var37 = 1; - auto destination = peep->GetDestination(); - destination += CoordsDirectionDelta[peep->PeepDirection]; - peep->SetDestination(destination, 7); - peep->MoveTo({ coords, peep->z }); + guest->Var37 = 1; + auto destination = guest->GetDestination(); + destination += CoordsDirectionDelta[guest->PeepDirection]; + guest->SetDestination(destination, 7); + guest->MoveTo({ coords, guest->z }); } return true; } @@ -2611,15 +1899,16 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool int16_t z = peep->GetZOnSlope(coords.x, coords.y); - if (peep->Is()) + auto* guest = peep->As(); + if (guest == nullptr) { peep->MoveTo({ coords, z }); return; } - uint8_t vandalThoughtTimeout = (peep->VandalismSeen & 0xC0) >> 6; + uint8_t vandalThoughtTimeout = (guest->VandalismSeen & 0xC0) >> 6; // Advance the vandalised tiles by 1 - uint8_t vandalisedTiles = (peep->VandalismSeen * 2) & 0x3F; + uint8_t vandalisedTiles = (guest->VandalismSeen * 2) & 0x3F; if (vandalism) { @@ -2630,8 +1919,8 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool { if ((scenario_rand() & 0xFFFF) <= 10922) { - peep->InsertNewThought(PeepThoughtType::Vandalism, PEEP_THOUGHT_ITEM_NONE); - peep->HappinessTarget = std::max(0, peep->HappinessTarget - 17); + guest->InsertNewThought(PeepThoughtType::Vandalism, PEEP_THOUGHT_ITEM_NONE); + guest->HappinessTarget = std::max(0, guest->HappinessTarget - 17); } vandalThoughtTimeout = 3; } @@ -2642,7 +1931,7 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool vandalThoughtTimeout--; } - peep->VandalismSeen = (vandalThoughtTimeout << 6) | vandalisedTiles; + guest->VandalismSeen = (vandalThoughtTimeout << 6) | vandalisedTiles; uint16_t crowded = 0; uint8_t litter_count = 0; uint8_t sick_count = 0; @@ -2654,14 +1943,14 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool if (other_peep->State != PeepState::Walking) continue; - if (abs(other_peep->z - peep->NextLoc.z) > 16) + if (abs(other_peep->z - guest->NextLoc.z) > 16) continue; crowded++; continue; } else if (auto litter = entity->As(); litter != nullptr) { - if (abs(litter->z - peep->NextLoc.z) > 16) + if (abs(litter->z - guest->NextLoc.z) > 16) continue; litter_count++; @@ -2673,23 +1962,23 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool } } - if (crowded >= 10 && peep->State == PeepState::Walking && (scenario_rand() & 0xFFFF) <= 21845) + if (crowded >= 10 && guest->State == PeepState::Walking && (scenario_rand() & 0xFFFF) <= 21845) { - peep->InsertNewThought(PeepThoughtType::Crowded, PEEP_THOUGHT_ITEM_NONE); - peep->HappinessTarget = std::max(0, peep->HappinessTarget - 14); + guest->InsertNewThought(PeepThoughtType::Crowded, PEEP_THOUGHT_ITEM_NONE); + guest->HappinessTarget = std::max(0, guest->HappinessTarget - 14); } litter_count = std::min(static_cast(3), litter_count); sick_count = std::min(static_cast(3), sick_count); - uint8_t disgusting_time = peep->DisgustingCount & 0xC0; - uint8_t disgusting_count = ((peep->DisgustingCount & 0xF) << 2) | sick_count; - peep->DisgustingCount = disgusting_count | disgusting_time; + uint8_t disgusting_time = guest->DisgustingCount & 0xC0; + uint8_t disgusting_count = ((guest->DisgustingCount & 0xF) << 2) | sick_count; + guest->DisgustingCount = disgusting_count | disgusting_time; if (disgusting_time & 0xC0 && (scenario_rand() & 0xFFFF) <= 4369) { // Reduce the disgusting time - peep->DisgustingCount -= 0x40; + guest->DisgustingCount -= 0x40; } else { @@ -2701,21 +1990,21 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool if (total_sick >= 3 && (scenario_rand() & 0xFFFF) <= 10922) { - peep->InsertNewThought(PeepThoughtType::PathDisgusting, PEEP_THOUGHT_ITEM_NONE); - peep->HappinessTarget = std::max(0, peep->HappinessTarget - 17); + guest->InsertNewThought(PeepThoughtType::PathDisgusting, PEEP_THOUGHT_ITEM_NONE); + guest->HappinessTarget = std::max(0, guest->HappinessTarget - 17); // Reset disgusting time - peep->DisgustingCount |= 0xC0; + guest->DisgustingCount |= 0xC0; } } - uint8_t litter_time = peep->LitterCount & 0xC0; - litter_count = ((peep->LitterCount & 0xF) << 2) | litter_count; - peep->LitterCount = litter_count | litter_time; + uint8_t litter_time = guest->LitterCount & 0xC0; + litter_count = ((guest->LitterCount & 0xF) << 2) | litter_count; + guest->LitterCount = litter_count | litter_time; if (litter_time & 0xC0 && (scenario_rand() & 0xFFFF) <= 4369) { // Reduce the litter time - peep->LitterCount -= 0x40; + guest->LitterCount -= 0x40; } else { @@ -2727,14 +2016,14 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool if (total_litter >= 3 && (scenario_rand() & 0xFFFF) <= 10922) { - peep->InsertNewThought(PeepThoughtType::BadLitter, PEEP_THOUGHT_ITEM_NONE); - peep->HappinessTarget = std::max(0, peep->HappinessTarget - 17); + guest->InsertNewThought(PeepThoughtType::BadLitter, PEEP_THOUGHT_ITEM_NONE); + guest->HappinessTarget = std::max(0, guest->HappinessTarget - 17); // Reset litter time - peep->LitterCount |= 0xC0; + guest->LitterCount |= 0xC0; } } - peep->MoveTo({ coords, z }); + guest->MoveTo({ coords, z }); } /** @@ -2753,54 +2042,54 @@ static void peep_interact_with_path(Peep* peep, const CoordsXYE& coords) } int16_t z = tile_element->GetBaseZ(); + auto* guest = peep->As(); if (map_is_location_owned({ coords, z })) { - if (peep->OutsideOfPark) + if (guest && guest->OutsideOfPark) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return; } } else { - if (!peep->OutsideOfPark) + if (guest == nullptr || !guest->OutsideOfPark) { peep_return_to_centre_of_tile(peep); return; } } - auto* guest = peep->As(); if (guest != nullptr && tile_element->AsPath()->IsQueue()) { auto rideIndex = tile_element->AsPath()->GetRideIndex(); - if (peep->State == PeepState::Queuing) + if (guest->State == PeepState::Queuing) { // Check if this queue is connected to the ride the // peep is queuing for, i.e. the player hasn't edited // the queue, rebuilt the ride, etc. - if (peep->CurrentRide == rideIndex) + if (guest->CurrentRide == rideIndex) { - peep_footpath_move_forward(peep, { coords, tile_element }, vandalism_present); + peep_footpath_move_forward(guest, { coords, tile_element }, vandalism_present); } else { // Queue got disconnected from the original ride. - peep->InteractionRideIndex = RIDE_ID_NULL; + guest->InteractionRideIndex = RIDE_ID_NULL; guest->RemoveFromQueue(); - peep->SetState(PeepState::One); - peep_footpath_move_forward(peep, { coords, tile_element }, vandalism_present); + guest->SetState(PeepState::One); + peep_footpath_move_forward(guest, { coords, tile_element }, vandalism_present); } } else { // Peep is not queuing. - peep->TimeLost = 0; + guest->TimeLost = 0; auto stationNum = tile_element->AsPath()->GetStationIndex(); if ((tile_element->AsPath()->HasQueueBanner()) && (tile_element->AsPath()->GetQueueBannerDirection() - == direction_reverse(peep->PeepDirection)) // Ride sign is facing the direction the peep is walking + == direction_reverse(guest->PeepDirection)) // Ride sign is facing the direction the peep is walking ) { /* Peep is approaching the entrance of a ride queue. @@ -2809,59 +2098,59 @@ static void peep_interact_with_path(Peep* peep, const CoordsXYE& coords) if (ride != nullptr && guest->ShouldGoOnRide(ride, stationNum, true, false)) { // Peep has decided to go on the ride at the queue. - peep->InteractionRideIndex = rideIndex; + guest->InteractionRideIndex = rideIndex; // Add the peep to the ride queue. uint16_t old_last_peep = ride->stations[stationNum].LastPeepInQueue; - ride->stations[stationNum].LastPeepInQueue = peep->sprite_index; - peep->GuestNextInQueue = old_last_peep; + ride->stations[stationNum].LastPeepInQueue = guest->sprite_index; + guest->GuestNextInQueue = old_last_peep; ride->stations[stationNum].QueueLength++; - peep_decrement_num_riders(peep); - peep->CurrentRide = rideIndex; - peep->CurrentRideStation = stationNum; - peep->State = PeepState::Queuing; - peep->DaysInQueue = 0; - peep_window_state_update(peep); + peep_decrement_num_riders(guest); + guest->CurrentRide = rideIndex; + guest->CurrentRideStation = stationNum; + guest->State = PeepState::Queuing; + guest->DaysInQueue = 0; + peep_window_state_update(guest); - peep->RideSubState = PeepRideSubState::InQueue; - peep->DestinationTolerance = 2; - peep->TimeInQueue = 0; - if (peep->PeepFlags & PEEP_FLAGS_TRACKING) + guest->RideSubState = PeepRideSubState::InQueue; + guest->DestinationTolerance = 2; + guest->TimeInQueue = 0; + if (guest->PeepFlags & PEEP_FLAGS_TRACKING) { auto ft = Formatter(); - peep->FormatNameTo(ft); + guest->FormatNameTo(ft); ride->FormatNameTo(ft); if (gConfigNotifications.guest_queuing_for_ride) { News::AddItemToQueue( - News::ItemType::PeepOnRide, STR_PEEP_TRACKING_PEEP_JOINED_QUEUE_FOR_X, peep->sprite_index, ft); + News::ItemType::PeepOnRide, STR_PEEP_TRACKING_PEEP_JOINED_QUEUE_FOR_X, guest->sprite_index, ft); } } - peep_footpath_move_forward(peep, { coords, tile_element }, vandalism_present); + peep_footpath_move_forward(guest, { coords, tile_element }, vandalism_present); } else { // Peep has decided not to go on the ride. - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); } } else { /* Peep is approaching a queue tile without a ride * sign facing the peep. */ - peep_footpath_move_forward(peep, { coords, tile_element }, vandalism_present); + peep_footpath_move_forward(guest, { coords, tile_element }, vandalism_present); } } } else { peep->InteractionRideIndex = RIDE_ID_NULL; - if (peep->State == PeepState::Queuing) + if (guest != nullptr && peep->State == PeepState::Queuing) { - peep->RemoveFromQueue(); - peep->SetState(PeepState::One); + guest->RemoveFromQueue(); + guest->SetState(PeepState::One); } peep_footpath_move_forward(peep, { coords, tile_element }, vandalism_present); } @@ -2887,37 +2176,37 @@ static bool peep_interact_with_shop(Peep* peep, const CoordsXYE& coords) // If we are queuing ignore the 'shop' // This can happen when paths clip through track - if (peep->State == PeepState::Queuing) + if (guest->State == PeepState::Queuing) { return false; } - peep->TimeLost = 0; + guest->TimeLost = 0; if (ride->status != RIDE_STATUS_OPEN) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } - if (peep->InteractionRideIndex == rideIndex) + if (guest->InteractionRideIndex == rideIndex) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } - if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) + if (guest->PeepFlags & PEEP_FLAGS_LEAVING_PARK) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } if (ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_PEEP_SHOULD_GO_INSIDE_FACILITY)) { - peep->TimeLost = 0; + guest->TimeLost = 0; if (!guest->ShouldGoOnRide(ride, 0, false, false)) { - peep_return_to_centre_of_tile(peep); + peep_return_to_centre_of_tile(guest); return true; } @@ -2933,35 +2222,35 @@ static bool peep_interact_with_shop(Peep* peep, const CoordsXYE& coords) } auto coordsCentre = coords.ToTileCentre(); - peep->SetDestination(coordsCentre, 3); - peep->CurrentRide = rideIndex; - peep->SetState(PeepState::EnteringRide); - peep->RideSubState = PeepRideSubState::ApproachShop; + guest->SetDestination(coordsCentre, 3); + guest->CurrentRide = rideIndex; + guest->SetState(PeepState::EnteringRide); + guest->RideSubState = PeepRideSubState::ApproachShop; - peep->GuestTimeOnRide = 0; + guest->GuestTimeOnRide = 0; ride->cur_num_customers++; - if (peep->PeepFlags & PEEP_FLAGS_TRACKING) + if (guest->PeepFlags & PEEP_FLAGS_TRACKING) { auto ft = Formatter(); - peep->FormatNameTo(ft); + guest->FormatNameTo(ft); ride->FormatNameTo(ft); rct_string_id string_id = ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_IN_RIDE) ? STR_PEEP_TRACKING_PEEP_IS_IN_X : STR_PEEP_TRACKING_PEEP_IS_ON_X; if (gConfigNotifications.guest_used_facility) { - News::AddItemToQueue(News::ItemType::PeepOnRide, string_id, peep->sprite_index, ft); + News::AddItemToQueue(News::ItemType::PeepOnRide, string_id, guest->sprite_index, ft); } } } else { - if (peep->GuestHeadingToRideId == rideIndex) - peep->GuestHeadingToRideId = RIDE_ID_NULL; - peep->ActionSpriteImageOffset = _unk_F1AEF0; - peep->SetState(PeepState::Buying); - peep->CurrentRide = rideIndex; - peep->SubState = 0; + if (guest->GuestHeadingToRideId == rideIndex) + guest->GuestHeadingToRideId = RIDE_ID_NULL; + guest->ActionSpriteImageOffset = _unk_F1AEF0; + guest->SetState(PeepState::Buying); + guest->CurrentRide = rideIndex; + guest->SubState = 0; } return true; @@ -2985,9 +2274,10 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) if (Action == PeepActionType::None1) Action = PeepActionType::None2; - if (State == PeepState::Queuing) + auto* guest = As(); + if (State == PeepState::Queuing && guest != nullptr) { - if (peep_update_queue_position(this, previousAction)) + if (guest->UpdateQueuePosition(previousAction)) return; } @@ -2997,7 +2287,6 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) pathing_result |= PATHING_DESTINATION_REACHED; uint8_t result = 0; - auto* guest = As(); if (guest != nullptr) { result = guest_path_finding(guest); @@ -3026,7 +2315,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) if (map_is_edge(newLoc)) { - if (OutsideOfPark) + if (guest != nullptr && guest->OutsideOfPark) { pathing_result |= PATHING_OUTSIDE_PARK; } @@ -3079,9 +2368,9 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) if (height <= 3 || (Is() && height <= 32)) { InteractionRideIndex = RIDE_ID_NULL; - if (State == PeepState::Queuing) + if (guest != nullptr && State == PeepState::Queuing) { - RemoveFromQueue(); + guest->RemoveFromQueue(); SetState(PeepState::One); } @@ -3105,12 +2394,13 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) return; } - if (Is() && !GetNextIsSurface()) + auto* staff = As(); + if (staff != nullptr && !GetNextIsSurface()) { // Prevent staff from leaving the path on their own unless they're allowed to mow. - if (!((this->StaffOrders & STAFF_ORDERS_MOWING) && this->StaffMowingTimeout >= 12)) + if (!((staff->StaffOrders & STAFF_ORDERS_MOWING) && staff->StaffMowingTimeout >= 12)) { - peep_return_to_centre_of_tile(this); + peep_return_to_centre_of_tile(staff); return; } } @@ -3296,89 +2586,20 @@ static void peep_release_balloon(Guest* peep, int16_t spawn_height) } } -/** - * - * rct2: 0x006966A9 - */ -void Peep::RemoveFromQueue() -{ - auto ride = get_ride(CurrentRide); - if (ride == nullptr) - return; - - auto& station = ride->stations[CurrentRideStation]; - // Make sure we don't underflow, building while paused might reset it to 0 where peeps have - // not yet left the queue. - if (station.QueueLength > 0) - { - station.QueueLength--; - } - - if (sprite_index == station.LastPeepInQueue) - { - station.LastPeepInQueue = GuestNextInQueue; - return; - } - - auto* otherGuest = GetEntity(station.LastPeepInQueue); - if (otherGuest == nullptr) - { - log_error("Invalid Guest Queue list!"); - return; - } - for (; otherGuest != nullptr; otherGuest = GetEntity(otherGuest->GuestNextInQueue)) - { - if (sprite_index == otherGuest->GuestNextInQueue) - { - otherGuest->GuestNextInQueue = GuestNextInQueue; - return; - } - } -} - /** * * rct2: 0x0069A512 */ void Peep::RemoveFromRide() { - if (State == PeepState::Queuing) + auto* guest = As(); + if (guest != nullptr && State == PeepState::Queuing) { - RemoveFromQueue(); + guest->RemoveFromQueue(); } StateReset(); } -uint64_t Peep::GetItemFlags() const -{ - return ItemFlags; -} - -void Peep::SetItemFlags(uint64_t itemFlags) -{ - ItemFlags = itemFlags; -} - -void Peep::RemoveAllItems() -{ - ItemFlags = 0; -} - -void Peep::RemoveItem(ShopItem item) -{ - ItemFlags &= ~EnumToFlag(item); -} - -void Peep::GiveItem(ShopItem item) -{ - ItemFlags |= EnumToFlag(item); -} - -bool Peep::HasItem(ShopItem peepItem) const -{ - return GetItemFlags() & EnumToFlag(peepItem); -} - void Peep::SetDestination(const CoordsXY& coords) { DestinationX = static_cast(coords.x); diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 7798acd0b0..d104c20dab 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -736,10 +736,7 @@ public: // Peep void Pickup(); void PickupAbort(int32_t old_x); std::unique_ptr Place(const TileCoordsXYZ& location, bool apply); - static Peep* Generate(const CoordsXYZ& coords); - void RemoveFromQueue(); void RemoveFromRide(); - void InsertNewThought(PeepThoughtType thought_type, uint8_t thought_arguments); void FormatActionTo(Formatter&) const; void FormatNameTo(Formatter&) const; std::string GetName() const; @@ -748,12 +745,6 @@ public: // Peep // Reset the peep's stored goal, which means they will forget any stored pathfinding history // on the next peep_pathfind_choose_direction call. void ResetPathfindGoal(); - uint64_t GetItemFlags() const; - void SetItemFlags(uint64_t itemFlags); - void RemoveAllItems(); - void RemoveItem(ShopItem item); - void GiveItem(ShopItem item); - bool HasItem(ShopItem peepItem) const; void SetDestination(const CoordsXY& coords); void SetDestination(const CoordsXY& coords, int32_t tolerance); @@ -816,6 +807,17 @@ public: void HandleEasterEggName(); int32_t GetEasterEggNameId() const; void UpdateEasterEggInteractions(); + void InsertNewThought(PeepThoughtType thought_type, uint8_t thought_arguments); + static Guest* Generate(const CoordsXYZ& coords); + bool UpdateQueuePosition(PeepActionType previous_action); + void RemoveFromQueue(); + + uint64_t GetItemFlags() const; + void SetItemFlags(uint64_t itemFlags); + void RemoveAllItems(); + void RemoveItem(ShopItem item); + void GiveItem(ShopItem item); + bool HasItem(ShopItem peepItem) const; private: void UpdateRide(); @@ -1006,7 +1008,6 @@ extern uint32_t gNextGuestNumber; extern uint8_t gPeepWarningThrottle[16]; -Peep* try_get_guest(uint16_t spriteIndex); int32_t peep_get_staff_count(); void peep_update_all(); void peep_problem_warnings_update(); @@ -1015,8 +1016,8 @@ void peep_update_crowd_noise(); void peep_update_days_in_queue(); void peep_applause(); void peep_thought_set_format_args(const rct_peep_thought* thought, Formatter& ft); -int32_t get_peep_face_sprite_small(Peep* peep); -int32_t get_peep_face_sprite_large(Peep* peep); +int32_t get_peep_face_sprite_small(Guest* peep); +int32_t get_peep_face_sprite_large(Guest* peep); void peep_sprite_remove(Peep* peep); void peep_window_state_update(Peep* peep); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 05f7b47134..555fe23747 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1208,157 +1208,38 @@ private: dst->SetName(GetUserString(src->name_string_idx)); } - dst->OutsideOfPark = static_cast(src->outside_of_park); - dst->State = static_cast(src->state); dst->SubState = src->sub_state; dst->NextLoc = { src->next_x, src->next_y, src->next_z * RCT1_COORDS_Z_STEP }; dst->NextFlags = src->next_flags; dst->Var37 = src->var_37; - dst->TimeToConsume = src->time_to_consume; dst->StepProgress = src->step_progress; - dst->VandalismSeen = src->vandalism_seen; - dst->TshirtColour = RCT1::GetColour(src->tshirt_colour); dst->TrousersColour = RCT1::GetColour(src->trousers_colour); - dst->UmbrellaColour = RCT1::GetColour(src->umbrella_colour); - dst->HatColour = RCT1::GetColour(src->hat_colour); - - // Balloons were always blue in RCT1 without AA/LL - if (_gameVersion == FILE_VERSION_RCT1) - { - dst->BalloonColour = COLOUR_LIGHT_BLUE; - } - else - { - dst->BalloonColour = RCT1::GetColour(src->balloon_colour); - } - dst->DestinationX = src->destination_x; dst->DestinationY = src->destination_y; dst->DestinationTolerance = src->destination_tolerance; dst->PeepDirection = src->direction; - dst->Energy = src->energy; dst->EnergyTarget = src->energy_target; - dst->Happiness = src->happiness; - dst->HappinessTarget = src->happiness_target; - dst->Nausea = src->nausea; - dst->NauseaTarget = src->nausea_target; - dst->Hunger = src->hunger; - dst->Thirst = src->thirst; - dst->Toilet = src->toilet; dst->Mass = src->mass; - - dst->LitterCount = src->litter_count; - dst->DisgustingCount = src->disgusting_count; - - dst->Intensity = static_cast(src->intensity); - dst->NauseaTolerance = static_cast(src->nausea_tolerance); dst->WindowInvalidateFlags = 0; - dst->CurrentRide = RCT12RideIdToOpenRCT2RideId(src->current_ride); dst->CurrentRideStation = src->current_ride_station; dst->CurrentTrain = src->current_train; dst->CurrentCar = src->current_car; dst->CurrentSeat = src->current_seat; - dst->GuestTimeOnRide = src->time_on_ride; - dst->DaysInQueue = src->days_in_queue; - dst->InteractionRideIndex = RCT12RideIdToOpenRCT2RideId(src->interaction_ride_index); - dst->Id = src->id; - dst->CashInPocket = src->cash_in_pocket; - dst->CashSpent = src->cash_spent; - // This doubles as staff hire date - dst->ParkEntryTime = src->park_entry_time; - - // This doubles as staff type - dst->GuestNumRides = src->no_of_rides; - - dst->AmountOfDrinks = src->no_of_drinks; - dst->AmountOfFood = src->no_of_food; - dst->AmountOfSouvenirs = src->no_of_souvenirs; - - dst->PaidToEnter = src->paid_to_enter; - dst->PaidOnRides = src->paid_on_rides; - dst->PaidOnDrink = src->paid_on_drink; - dst->PaidOnFood = src->paid_on_food; - dst->PaidOnSouvenirs = src->paid_on_souvenirs; - - dst->VoucherRideId = RCT12RideIdToOpenRCT2RideId(src->voucher_arguments); - dst->VoucherType = src->voucher_type; - - dst->SurroundingsThoughtTimeout = src->surroundings_thought_timeout; - dst->Angriness = src->angriness; - dst->TimeLost = src->time_lost; - - for (size_t i = 0; i < 32; i++) - { - dst->RidesBeenOn[i] = src->rides_been_on[i]; - } - for (size_t i = 0; i < 16; i++) - { - dst->RideTypesBeenOn[i] = src->ride_types_been_on[i]; - } - - dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref); - - for (size_t i = 0; i < std::size(src->thoughts); i++) - { - auto srcThought = &src->thoughts[i]; - auto dstThought = &dst->Thoughts[i]; - dstThought->type = static_cast(srcThought->type); - dstThought->item = srcThought->item; - dstThought->freshness = srcThought->freshness; - dstThought->fresh_timeout = srcThought->fresh_timeout; - } - - dst->PreviousRide = RCT12RideIdToOpenRCT2RideId(src->previous_ride); - dst->PreviousRideTimeOut = src->previous_ride_time_out; - dst->PathCheckOptimisation = 0; - dst->GuestHeadingToRideId = RCT12RideIdToOpenRCT2RideId(src->guest_heading_to_ride_id); - // Doubles as staff orders - dst->GuestIsLostCountdown = src->peep_is_lost_countdown; - // The ID is fixed later - dst->GuestNextInQueue = src->next_in_queue; - dst->PeepFlags = 0; dst->PathfindGoal.x = 0xFF; dst->PathfindGoal.y = 0xFF; dst->PathfindGoal.z = 0xFF; dst->PathfindGoal.direction = INVALID_DIRECTION; - - // Guests' favourite ride was only saved in LL. - // Set it to N/A if the save comes from the original or AA. - if (_gameVersion == FILE_VERSION_RCT1_LL) - { - dst->FavouriteRide = RCT12RideIdToOpenRCT2RideId(src->favourite_ride); - dst->FavouriteRideRating = src->favourite_ride_rating; - } - else - { - dst->FavouriteRide = RIDE_ID_NULL; - dst->FavouriteRideRating = 0; - } - - dst->SetItemFlags(src->GetItemFlags()); - - if (dst->Is()) - { - if (dst->OutsideOfPark && dst->State != PeepState::LeavingPark) - { - increment_guests_heading_for_park(); - } - else - { - increment_guests_in_park(); - } - } } - void ImportStaffPatrolArea(Peep* staffmember) + void ImportStaffPatrolArea(Staff* staffmember) { // The patrol areas in RCT1 are encoded as follows, for coordinates x and y, separately for every staff member: // - Chop off the 7 lowest bits of the x and y coordinates, which leaves 5 bits per coordinate. @@ -2884,6 +2765,102 @@ template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) auto* dst = CreateEntityAt(srcBase.sprite_index); auto* src = static_cast(&srcBase); ImportPeep(dst, src); + + dst->OutsideOfPark = static_cast(src->outside_of_park); + dst->TimeToConsume = src->time_to_consume; + dst->VandalismSeen = src->vandalism_seen; + dst->UmbrellaColour = RCT1::GetColour(src->umbrella_colour); + dst->HatColour = RCT1::GetColour(src->hat_colour); + + // Balloons were always blue in RCT1 without AA/LL + if (_gameVersion == FILE_VERSION_RCT1) + { + dst->BalloonColour = COLOUR_LIGHT_BLUE; + } + else + { + dst->BalloonColour = RCT1::GetColour(src->balloon_colour); + } + dst->Happiness = src->happiness; + dst->HappinessTarget = src->happiness_target; + dst->Nausea = src->nausea; + dst->NauseaTarget = src->nausea_target; + dst->Hunger = src->hunger; + dst->Thirst = src->thirst; + dst->Toilet = src->toilet; + dst->LitterCount = src->litter_count; + dst->DisgustingCount = src->disgusting_count; + dst->Intensity = static_cast(src->intensity); + dst->NauseaTolerance = static_cast(src->nausea_tolerance); + dst->GuestTimeOnRide = src->time_on_ride; + dst->DaysInQueue = src->days_in_queue; + dst->CashInPocket = src->cash_in_pocket; + dst->CashSpent = src->cash_spent; + dst->ParkEntryTime = src->park_entry_time; + dst->GuestNumRides = src->no_of_rides; + dst->AmountOfDrinks = src->no_of_drinks; + dst->AmountOfFood = src->no_of_food; + dst->AmountOfSouvenirs = src->no_of_souvenirs; + dst->PaidToEnter = src->paid_to_enter; + dst->PaidOnRides = src->paid_on_rides; + dst->PaidOnDrink = src->paid_on_drink; + dst->PaidOnFood = src->paid_on_food; + dst->PaidOnSouvenirs = src->paid_on_souvenirs; + dst->VoucherRideId = RCT12RideIdToOpenRCT2RideId(src->voucher_arguments); + dst->VoucherType = src->voucher_type; + dst->SurroundingsThoughtTimeout = src->surroundings_thought_timeout; + dst->Angriness = src->angriness; + dst->TimeLost = src->time_lost; + + for (size_t i = 0; i < 32; i++) + { + dst->RidesBeenOn[i] = src->rides_been_on[i]; + } + for (size_t i = 0; i < 16; i++) + { + dst->RideTypesBeenOn[i] = src->ride_types_been_on[i]; + } + + dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref); + + for (size_t i = 0; i < std::size(src->thoughts); i++) + { + auto srcThought = &src->thoughts[i]; + auto dstThought = &dst->Thoughts[i]; + dstThought->type = static_cast(srcThought->type); + dstThought->item = srcThought->item; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; + } + + dst->PreviousRide = RCT12RideIdToOpenRCT2RideId(src->previous_ride); + dst->PreviousRideTimeOut = src->previous_ride_time_out; + dst->GuestHeadingToRideId = RCT12RideIdToOpenRCT2RideId(src->guest_heading_to_ride_id); + dst->GuestIsLostCountdown = src->peep_is_lost_countdown; + dst->GuestNextInQueue = src->next_in_queue; + // Guests' favourite ride was only saved in LL. + // Set it to N/A if the save comes from the original or AA. + if (_gameVersion == FILE_VERSION_RCT1_LL) + { + dst->FavouriteRide = RCT12RideIdToOpenRCT2RideId(src->favourite_ride); + dst->FavouriteRideRating = src->favourite_ride_rating; + } + else + { + dst->FavouriteRide = RIDE_ID_NULL; + dst->FavouriteRideRating = 0; + } + + dst->SetItemFlags(src->GetItemFlags()); + + if (dst->OutsideOfPark && dst->State != PeepState::LeavingPark) + { + increment_guests_heading_for_park(); + } + else + { + increment_guests_in_park(); + } } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) @@ -2891,6 +2868,16 @@ template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) auto* dst = CreateEntityAt(srcBase.sprite_index); auto* src = static_cast(&srcBase); ImportPeep(dst, src); + dst->AssignedStaffType = StaffType(src->staff_type); + dst->MechanicTimeSinceCall = src->mechanic_time_since_call; + dst->HireDate = src->park_entry_time; + dst->StaffId = src->staff_id; + dst->StaffOrders = src->staff_orders; + dst->StaffMowingTimeout = src->staff_mowing_timeout; + dst->StaffLawnsMown = src->paid_to_enter; + dst->StaffGardensWatered = src->paid_on_rides; + dst->StaffLitterSwept = src->paid_on_food; + dst->StaffBinsEmptied = src->paid_on_souvenirs; } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index c75e8d4fd6..093eb928cf 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -1173,10 +1173,88 @@ template<> void S6Exporter::ExportEntity(RCT2SpriteVehicle* dst, const Vehicle* template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Guest* src) { ExportEntityPeep(dst, src); + dst->outside_of_park = static_cast(src->OutsideOfPark); + dst->no_of_rides = src->GuestNumRides; + dst->happiness = src->Happiness; + dst->happiness_target = src->HappinessTarget; + dst->nausea = src->Nausea; + dst->nausea_target = src->NauseaTarget; + dst->hunger = src->Hunger; + dst->thirst = src->Thirst; + dst->toilet = src->Toilet; + dst->time_to_consume = src->TimeToConsume; + dst->intensity = static_cast(src->Intensity); + dst->nausea_tolerance = EnumValue(src->NauseaTolerance); + dst->paid_on_drink = src->PaidOnDrink; + for (size_t i = 0; i < std::size(src->RideTypesBeenOn); i++) + { + dst->ride_types_been_on[i] = src->RideTypesBeenOn[i]; + } + dst->item_extra_flags = static_cast(src->GetItemFlags() >> 32); + dst->photo1_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo1RideRef); + dst->photo2_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo2RideRef); + dst->photo3_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo3RideRef); + dst->photo4_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo4RideRef); + dst->next_in_queue = src->GuestNextInQueue; + dst->time_in_queue = src->TimeInQueue; + for (size_t i = 0; i < std::size(src->RidesBeenOn); i++) + { + dst->rides_been_on[i] = src->RidesBeenOn[i]; + } + dst->cash_in_pocket = src->CashInPocket; + dst->cash_spent = src->CashSpent; + dst->park_entry_time = src->ParkEntryTime; + dst->rejoin_queue_timeout = src->RejoinQueueTimeout; + dst->previous_ride = OpenRCT2RideIdToRCT12RideId(src->PreviousRide); + dst->previous_ride_time_out = src->PreviousRideTimeOut; + for (size_t i = 0; i < std::size(src->Thoughts); i++) + { + auto srcThought = &src->Thoughts[i]; + auto dstThought = &dst->thoughts[i]; + dstThought->type = static_cast(srcThought->type); + dstThought->item = srcThought->item; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; + } + dst->guest_heading_to_ride_id = OpenRCT2RideIdToRCT12RideId(src->GuestHeadingToRideId); + dst->peep_is_lost_countdown = src->GuestIsLostCountdown; + dst->litter_count = src->LitterCount; + dst->time_on_ride = src->GuestTimeOnRide; + dst->disgusting_count = src->DisgustingCount; + dst->paid_to_enter = src->PaidToEnter; + dst->paid_on_rides = src->PaidOnRides; + dst->paid_on_food = src->PaidOnFood; + dst->paid_on_souvenirs = src->PaidOnSouvenirs; + dst->no_of_food = src->AmountOfFood; + dst->no_of_drinks = src->AmountOfDrinks; + dst->no_of_souvenirs = src->AmountOfSouvenirs; + dst->vandalism_seen = src->VandalismSeen; + dst->voucher_type = src->VoucherType; + dst->voucher_arguments = OpenRCT2RideIdToRCT12RideId(src->VoucherRideId); + dst->surroundings_thought_timeout = src->SurroundingsThoughtTimeout; + dst->angriness = src->Angriness; + dst->time_lost = src->TimeLost; + dst->days_in_queue = src->DaysInQueue; + dst->balloon_colour = src->BalloonColour; + dst->umbrella_colour = src->UmbrellaColour; + dst->hat_colour = src->HatColour; + dst->favourite_ride = OpenRCT2RideIdToRCT12RideId(src->FavouriteRide); + dst->favourite_ride_rating = src->FavouriteRideRating; + dst->item_standard_flags = static_cast(src->GetItemFlags()); } template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Staff* src) { ExportEntityPeep(dst, src); + dst->staff_type = static_cast(src->AssignedStaffType); + dst->mechanic_time_since_call = src->MechanicTimeSinceCall; + dst->park_entry_time = src->HireDate; + dst->staff_id = src->StaffId; + dst->staff_orders = src->StaffOrders; + dst->staff_mowing_timeout = src->StaffMowingTimeout; + dst->paid_to_enter = src->StaffLawnsMown; + dst->paid_on_rides = src->StaffGardensWatered; + dst->paid_on_food = src->StaffLitterSwept; + dst->paid_on_souvenirs = src->StaffBinsEmptied; } void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) @@ -1201,7 +1279,8 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) } if (generateName) { - if (src->Is()) + auto* staff = src->As(); + if (staff != nullptr) { static constexpr const rct_string_id staffNames[] = { STR_HANDYMAN_X, @@ -1209,7 +1288,7 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) STR_SECURITY_GUARD_X, STR_ENTERTAINER_X, }; - dst->name_string_idx = staffNames[static_cast(src->AssignedStaffType) % sizeof(staffNames)]; + dst->name_string_idx = staffNames[static_cast(staff->AssignedStaffType) % sizeof(staffNames)]; } else if (gParkFlags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES) { @@ -1225,12 +1304,10 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) dst->next_y = src->NextLoc.y; dst->next_z = src->NextLoc.z / COORDS_Z_STEP; dst->next_flags = src->NextFlags; - dst->outside_of_park = static_cast(src->OutsideOfPark); dst->state = static_cast(src->State); dst->sub_state = src->SubState; dst->sprite_type = static_cast(src->SpriteType); dst->peep_type = static_cast(src->Type == EntityType::Staff ? RCT12PeepType::Staff : RCT12PeepType::Guest); - dst->no_of_rides = src->GuestNumRides; dst->tshirt_colour = src->TshirtColour; dst->trousers_colour = src->TrousersColour; dst->destination_x = src->DestinationX; @@ -1239,27 +1316,8 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) dst->var_37 = src->Var37; dst->energy = src->Energy; dst->energy_target = src->EnergyTarget; - dst->happiness = src->Happiness; - dst->happiness_target = src->HappinessTarget; - dst->nausea = src->Nausea; - dst->nausea_target = src->NauseaTarget; - dst->hunger = src->Hunger; - dst->thirst = src->Thirst; - dst->toilet = src->Toilet; dst->mass = src->Mass; - dst->time_to_consume = src->TimeToConsume; - dst->intensity = static_cast(src->Intensity); - dst->nausea_tolerance = EnumValue(src->NauseaTolerance); dst->window_invalidate_flags = src->WindowInvalidateFlags; - dst->paid_on_drink = src->PaidOnDrink; - for (size_t i = 0; i < std::size(src->RideTypesBeenOn); i++) - { - dst->ride_types_been_on[i] = src->RideTypesBeenOn[i]; - } - dst->item_extra_flags = static_cast(src->GetItemFlags() >> 32); - dst->photo2_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo2RideRef); - dst->photo3_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo3RideRef); - dst->photo4_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo4RideRef); dst->current_ride = OpenRCT2RideIdToRCT12RideId(src->CurrentRide); dst->current_ride_station = src->CurrentRideStation; dst->current_train = src->CurrentTrain; @@ -1271,34 +1329,10 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) dst->action = static_cast(src->Action); dst->action_frame = src->ActionFrame; dst->step_progress = src->StepProgress; - dst->next_in_queue = src->GuestNextInQueue; dst->direction = src->PeepDirection; dst->interaction_ride_index = OpenRCT2RideIdToRCT12RideId(src->InteractionRideIndex); - dst->time_in_queue = src->TimeInQueue; - for (size_t i = 0; i < std::size(src->RidesBeenOn); i++) - { - dst->rides_been_on[i] = src->RidesBeenOn[i]; - } dst->id = src->Id; - dst->cash_in_pocket = src->CashInPocket; - dst->cash_spent = src->CashSpent; - dst->park_entry_time = src->ParkEntryTime; - dst->rejoin_queue_timeout = src->RejoinQueueTimeout; - dst->previous_ride = OpenRCT2RideIdToRCT12RideId(src->PreviousRide); - dst->previous_ride_time_out = src->PreviousRideTimeOut; - for (size_t i = 0; i < std::size(src->Thoughts); i++) - { - auto srcThought = &src->Thoughts[i]; - auto dstThought = &dst->thoughts[i]; - dstThought->type = static_cast(srcThought->type); - dstThought->item = srcThought->item; - dstThought->freshness = srcThought->freshness; - dstThought->fresh_timeout = srcThought->fresh_timeout; - } dst->path_check_optimisation = src->PathCheckOptimisation; - dst->guest_heading_to_ride_id = OpenRCT2RideIdToRCT12RideId(src->GuestHeadingToRideId); - dst->peep_is_lost_countdown = src->GuestIsLostCountdown; - dst->photo1_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo1RideRef); dst->peep_flags = src->PeepFlags; dst->pathfind_goal = src->PathfindGoal; for (size_t i = 0; i < std::size(src->PathfindHistory); i++) @@ -1306,29 +1340,6 @@ void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src) dst->pathfind_history[i] = src->PathfindHistory[i]; } dst->no_action_frame_num = src->WalkingFrameNum; - dst->litter_count = src->LitterCount; - dst->time_on_ride = src->GuestTimeOnRide; - dst->disgusting_count = src->DisgustingCount; - dst->paid_to_enter = src->PaidToEnter; - dst->paid_on_rides = src->PaidOnRides; - dst->paid_on_food = src->PaidOnFood; - dst->paid_on_souvenirs = src->PaidOnSouvenirs; - dst->no_of_food = src->AmountOfFood; - dst->no_of_drinks = src->AmountOfDrinks; - dst->no_of_souvenirs = src->AmountOfSouvenirs; - dst->vandalism_seen = src->VandalismSeen; - dst->voucher_type = src->VoucherType; - dst->voucher_arguments = OpenRCT2RideIdToRCT12RideId(src->VoucherRideId); - dst->surroundings_thought_timeout = src->SurroundingsThoughtTimeout; - dst->angriness = src->Angriness; - dst->time_lost = src->TimeLost; - dst->days_in_queue = src->DaysInQueue; - dst->balloon_colour = src->BalloonColour; - dst->umbrella_colour = src->UmbrellaColour; - dst->hat_colour = src->HatColour; - dst->favourite_ride = OpenRCT2RideIdToRCT12RideId(src->FavouriteRide); - dst->favourite_ride_rating = src->FavouriteRideRating; - dst->item_standard_flags = static_cast(src->GetItemFlags()); } template<> void S6Exporter::ExportEntity(RCT12SpriteSteamParticle* dst, const SteamParticle* src) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index db710bbe12..acaf2f21cc 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1340,11 +1340,9 @@ public: } dst->NextLoc = { src->next_x, src->next_y, src->next_z * COORDS_Z_STEP }; dst->NextFlags = src->next_flags; - dst->OutsideOfPark = static_cast(src->outside_of_park); dst->State = static_cast(src->state); dst->SubState = src->sub_state; dst->SpriteType = static_cast(src->sprite_type); - dst->GuestNumRides = src->no_of_rides; dst->TshirtColour = src->tshirt_colour; dst->TrousersColour = src->trousers_colour; dst->DestinationX = src->destination_x; @@ -1353,27 +1351,8 @@ public: dst->Var37 = src->var_37; dst->Energy = src->energy; dst->EnergyTarget = src->energy_target; - dst->Happiness = src->happiness; - dst->HappinessTarget = src->happiness_target; - dst->Nausea = src->nausea; - dst->NauseaTarget = src->nausea_target; - dst->Hunger = src->hunger; - dst->Thirst = src->thirst; - dst->Toilet = src->toilet; dst->Mass = src->mass; - dst->TimeToConsume = src->time_to_consume; - dst->Intensity = static_cast(src->intensity); - dst->NauseaTolerance = static_cast(src->nausea_tolerance); dst->WindowInvalidateFlags = src->window_invalidate_flags; - dst->PaidOnDrink = src->paid_on_drink; - for (size_t i = 0; i < std::size(src->ride_types_been_on); i++) - { - dst->RideTypesBeenOn[i] = src->ride_types_been_on[i]; - } - dst->SetItemFlags(src->GetItemFlags()); - dst->Photo2RideRef = RCT12RideIdToOpenRCT2RideId(src->photo2_ride_ref); - dst->Photo3RideRef = RCT12RideIdToOpenRCT2RideId(src->photo3_ride_ref); - dst->Photo4RideRef = RCT12RideIdToOpenRCT2RideId(src->photo4_ride_ref); dst->CurrentRide = RCT12RideIdToOpenRCT2RideId(src->current_ride); dst->CurrentRideStation = src->current_ride_station; dst->CurrentTrain = src->current_train; @@ -1385,34 +1364,10 @@ public: dst->Action = static_cast(src->action); dst->ActionFrame = src->action_frame; dst->StepProgress = src->step_progress; - dst->GuestNextInQueue = src->next_in_queue; dst->PeepDirection = src->direction; dst->InteractionRideIndex = RCT12RideIdToOpenRCT2RideId(src->interaction_ride_index); - dst->TimeInQueue = src->time_in_queue; - for (size_t i = 0; i < std::size(src->rides_been_on); i++) - { - dst->RidesBeenOn[i] = src->rides_been_on[i]; - } dst->Id = src->id; - dst->CashInPocket = src->cash_in_pocket; - dst->CashSpent = src->cash_spent; - dst->ParkEntryTime = src->park_entry_time; - dst->RejoinQueueTimeout = src->rejoin_queue_timeout; - dst->PreviousRide = RCT12RideIdToOpenRCT2RideId(src->previous_ride); - dst->PreviousRideTimeOut = src->previous_ride_time_out; - for (size_t i = 0; i < std::size(src->thoughts); i++) - { - auto srcThought = &src->thoughts[i]; - auto dstThought = &dst->Thoughts[i]; - dstThought->type = static_cast(srcThought->type); - dstThought->item = srcThought->item; - dstThought->freshness = srcThought->freshness; - dstThought->fresh_timeout = srcThought->fresh_timeout; - } dst->PathCheckOptimisation = src->path_check_optimisation; - dst->GuestHeadingToRideId = RCT12RideIdToOpenRCT2RideId(src->guest_heading_to_ride_id); - dst->GuestIsLostCountdown = src->peep_is_lost_countdown; - dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref); dst->PeepFlags = src->peep_flags; dst->PathfindGoal = src->pathfind_goal; for (size_t i = 0; i < std::size(src->pathfind_history); i++) @@ -1420,28 +1375,6 @@ public: dst->PathfindHistory[i] = src->pathfind_history[i]; } dst->WalkingFrameNum = src->no_action_frame_num; - dst->LitterCount = src->litter_count; - dst->GuestTimeOnRide = src->time_on_ride; - dst->DisgustingCount = src->disgusting_count; - dst->PaidToEnter = src->paid_to_enter; - dst->PaidOnRides = src->paid_on_rides; - dst->PaidOnFood = src->paid_on_food; - dst->PaidOnSouvenirs = src->paid_on_souvenirs; - dst->AmountOfFood = src->no_of_food; - dst->AmountOfDrinks = src->no_of_drinks; - dst->AmountOfSouvenirs = src->no_of_souvenirs; - dst->VandalismSeen = src->vandalism_seen; - dst->VoucherType = src->voucher_type; - dst->VoucherRideId = RCT12RideIdToOpenRCT2RideId(src->voucher_arguments); - dst->SurroundingsThoughtTimeout = src->surroundings_thought_timeout; - dst->Angriness = src->angriness; - dst->TimeLost = src->time_lost; - dst->DaysInQueue = src->days_in_queue; - dst->BalloonColour = src->balloon_colour; - dst->UmbrellaColour = src->umbrella_colour; - dst->HatColour = src->hat_colour; - dst->FavouriteRide = RCT12RideIdToOpenRCT2RideId(src->favourite_ride); - dst->FavouriteRideRating = src->favourite_ride_rating; } constexpr EntityType GetEntityTypeFromRCT2Sprite(const RCT12SpriteBase* src) @@ -1673,6 +1606,74 @@ template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc) auto dst = CreateEntityAt(baseSrc.sprite_index); auto src = static_cast(&baseSrc); ImportEntityPeep(dst, src); + + dst->OutsideOfPark = static_cast(src->outside_of_park); + dst->GuestNumRides = src->no_of_rides; + dst->Happiness = src->happiness; + dst->HappinessTarget = src->happiness_target; + dst->Nausea = src->nausea; + dst->NauseaTarget = src->nausea_target; + dst->Hunger = src->hunger; + dst->Thirst = src->thirst; + dst->Toilet = src->toilet; + dst->TimeToConsume = src->time_to_consume; + dst->Intensity = static_cast(src->intensity); + dst->NauseaTolerance = static_cast(src->nausea_tolerance); + dst->PaidOnDrink = src->paid_on_drink; + for (size_t i = 0; i < std::size(src->ride_types_been_on); i++) + { + dst->RideTypesBeenOn[i] = src->ride_types_been_on[i]; + } + dst->SetItemFlags(src->GetItemFlags()); + dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref); + dst->Photo2RideRef = RCT12RideIdToOpenRCT2RideId(src->photo2_ride_ref); + dst->Photo3RideRef = RCT12RideIdToOpenRCT2RideId(src->photo3_ride_ref); + dst->Photo4RideRef = RCT12RideIdToOpenRCT2RideId(src->photo4_ride_ref); + dst->GuestNextInQueue = src->next_in_queue; + dst->TimeInQueue = src->time_in_queue; + for (size_t i = 0; i < std::size(src->rides_been_on); i++) + { + dst->RidesBeenOn[i] = src->rides_been_on[i]; + } + dst->CashInPocket = src->cash_in_pocket; + dst->CashSpent = src->cash_spent; + dst->ParkEntryTime = src->park_entry_time; + dst->RejoinQueueTimeout = src->rejoin_queue_timeout; + dst->PreviousRide = RCT12RideIdToOpenRCT2RideId(src->previous_ride); + dst->PreviousRideTimeOut = src->previous_ride_time_out; + for (size_t i = 0; i < std::size(src->thoughts); i++) + { + auto srcThought = &src->thoughts[i]; + auto dstThought = &dst->Thoughts[i]; + dstThought->type = static_cast(srcThought->type); + dstThought->item = srcThought->item; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; + } + dst->GuestHeadingToRideId = RCT12RideIdToOpenRCT2RideId(src->guest_heading_to_ride_id); + dst->GuestIsLostCountdown = src->peep_is_lost_countdown; + dst->LitterCount = src->litter_count; + dst->GuestTimeOnRide = src->time_on_ride; + dst->DisgustingCount = src->disgusting_count; + dst->PaidToEnter = src->paid_to_enter; + dst->PaidOnRides = src->paid_on_rides; + dst->PaidOnFood = src->paid_on_food; + dst->PaidOnSouvenirs = src->paid_on_souvenirs; + dst->AmountOfFood = src->no_of_food; + dst->AmountOfDrinks = src->no_of_drinks; + dst->AmountOfSouvenirs = src->no_of_souvenirs; + dst->VandalismSeen = src->vandalism_seen; + dst->VoucherType = src->voucher_type; + dst->VoucherRideId = RCT12RideIdToOpenRCT2RideId(src->voucher_arguments); + dst->SurroundingsThoughtTimeout = src->surroundings_thought_timeout; + dst->Angriness = src->angriness; + dst->TimeLost = src->time_lost; + dst->DaysInQueue = src->days_in_queue; + dst->BalloonColour = src->balloon_colour; + dst->UmbrellaColour = src->umbrella_colour; + dst->HatColour = src->hat_colour; + dst->FavouriteRide = RCT12RideIdToOpenRCT2RideId(src->favourite_ride); + dst->FavouriteRideRating = src->favourite_ride_rating; } template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc) @@ -1680,6 +1681,17 @@ template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc) auto dst = CreateEntityAt(baseSrc.sprite_index); auto src = static_cast(&baseSrc); ImportEntityPeep(dst, src); + + dst->AssignedStaffType = StaffType(src->staff_type); + dst->MechanicTimeSinceCall = src->mechanic_time_since_call; + dst->HireDate = src->park_entry_time; + dst->StaffId = src->staff_id; + dst->StaffOrders = src->staff_orders; + dst->StaffMowingTimeout = src->staff_mowing_timeout; + dst->StaffLawnsMown = src->paid_to_enter; + dst->StaffGardensWatered = src->paid_on_rides; + dst->StaffLitterSwept = src->paid_on_food; + dst->StaffBinsEmptied = src->paid_on_souvenirs; } template<> void S6Importer::ImportEntity(const RCT12SpriteBase& baseSrc) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 444cd3ab86..99b35d6368 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -131,7 +131,7 @@ Direction gRideEntranceExitPlaceDirection; uint8_t gLastEntranceStyle; // Static function declarations -Peep* find_closest_mechanic(const CoordsXY& entrancePosition, int32_t forInspection); +Staff* find_closest_mechanic(const CoordsXY& entrancePosition, int32_t forInspection); static void ride_breakdown_status_update(Ride* ride); static void ride_breakdown_update(Ride* ride); static void ride_call_closest_mechanic(Ride* ride); @@ -309,12 +309,12 @@ int32_t Ride::GetMaxQueueTime() const return static_cast(queueTime); } -Peep* Ride::GetQueueHeadGuest(StationIndex stationIndex) const +Guest* Ride::GetQueueHeadGuest(StationIndex stationIndex) const { - Peep* peep; - Peep* result = nullptr; + Guest* peep; + Guest* result = nullptr; uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; - while ((peep = try_get_guest(spriteIndex)) != nullptr) + while ((peep = TryGetEntity(spriteIndex)) != nullptr) { spriteIndex = peep->GuestNextInQueue; result = peep; @@ -325,9 +325,9 @@ Peep* Ride::GetQueueHeadGuest(StationIndex stationIndex) const void Ride::UpdateQueueLength(StationIndex stationIndex) { uint16_t count = 0; - Peep* peep; + Guest* peep; uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; - while ((peep = try_get_guest(spriteIndex)) != nullptr) + while ((peep = TryGetEntity(spriteIndex)) != nullptr) { spriteIndex = peep->GuestNextInQueue; count++; @@ -335,13 +335,13 @@ void Ride::UpdateQueueLength(StationIndex stationIndex) stations[stationIndex].QueueLength = count; } -void Ride::QueueInsertGuestAtFront(StationIndex stationIndex, Peep* peep) +void Ride::QueueInsertGuestAtFront(StationIndex stationIndex, Guest* peep) { assert(stationIndex < MAX_STATIONS); assert(peep != nullptr); peep->GuestNextInQueue = SPRITE_INDEX_NULL; - Peep* queueHeadGuest = GetQueueHeadGuest(peep->CurrentRideStation); + auto* queueHeadGuest = GetQueueHeadGuest(peep->CurrentRideStation); if (queueHeadGuest == nullptr) { stations[peep->CurrentRideStation].LastPeepInQueue = peep->sprite_index; @@ -2698,7 +2698,7 @@ static void ride_call_closest_mechanic(Ride* ride) ride_call_mechanic(ride, mechanic, forInspection); } -Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection) +Staff* ride_find_closest_mechanic(Ride* ride, int32_t forInspection) { // Get either exit position or entrance position if there is no exit auto stationIndex = ride->inspection_station; @@ -2727,9 +2727,9 @@ Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection) * rct2: 0x006B774B (forInspection = 0) * rct2: 0x006B78C3 (forInspection = 1) */ -Peep* find_closest_mechanic(const CoordsXY& entrancePosition, int32_t forInspection) +Staff* find_closest_mechanic(const CoordsXY& entrancePosition, int32_t forInspection) { - Peep* closestMechanic = nullptr; + Staff* closestMechanic = nullptr; uint32_t closestDistance = std::numeric_limits::max(); for (auto peep : EntityList()) diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 13c32587cc..0621cb9f89 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -26,9 +26,9 @@ struct IObjectManager; class Formatter; class StationObject; -struct Peep; struct Ride; struct RideTypeDescriptor; +struct Guest; struct Staff; struct Vehicle; @@ -437,8 +437,8 @@ public: int32_t GetTotalQueueLength() const; int32_t GetMaxQueueTime() const; - void QueueInsertGuestAtFront(StationIndex stationIndex, Peep* peep); - Peep* GetQueueHeadGuest(StationIndex stationIndex) const; + void QueueInsertGuestAtFront(StationIndex stationIndex, Guest* peep); + Guest* GetQueueHeadGuest(StationIndex stationIndex) const; void SetNameToDefault(); std::string GetName() const; @@ -1140,7 +1140,7 @@ int32_t ride_get_unused_preset_vehicle_colour(ObjectEntryIndex subType); void ride_set_vehicle_colours_to_random_preset(Ride* ride, uint8_t preset_index); void ride_measurements_update(); void ride_breakdown_add_news_item(Ride* ride); -Peep* ride_find_closest_mechanic(Ride* ride, int32_t forInspection); +Staff* ride_find_closest_mechanic(Ride* ride, int32_t forInspection); int32_t ride_initialise_construction_window(Ride* ride); void ride_construction_invalidate_current_track(); std::optional sub_6C683D( diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 794a2d4850..896f4205f0 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -699,7 +699,7 @@ void Park::GenerateGuests() } } -Peep* Park::GenerateGuestFromCampaign(int32_t campaign) +Guest* Park::GenerateGuestFromCampaign(int32_t campaign) { auto peep = GenerateGuest(); if (peep != nullptr) @@ -709,14 +709,14 @@ Peep* Park::GenerateGuestFromCampaign(int32_t campaign) return peep; } -Peep* Park::GenerateGuest() +Guest* Park::GenerateGuest() { - Peep* peep = nullptr; + Guest* peep = nullptr; const auto spawn = get_random_peep_spawn(); if (spawn != nullptr) { auto direction = direction_reverse(spawn->direction); - peep = Peep::Generate({ spawn->x, spawn->y, spawn->z }); + peep = Guest::Generate({ spawn->x, spawn->y, spawn->z }); if (peep != nullptr) { peep->sprite_direction = direction << 3; diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index 46f159089c..8340666370 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -18,8 +18,6 @@ #define MAX_ENTRANCE_FEE MONEY(200, 00) -struct Peep; - enum : uint32_t { PARK_FLAGS_PARK_OPEN = (1 << 0), @@ -43,7 +41,7 @@ enum : uint32_t PARK_FLAGS_UNLOCK_ALL_PRICES = (1u << 31), // OpenRCT2 only! }; -struct Peep; +struct Guest; struct rct_ride; namespace OpenRCT2 @@ -73,7 +71,7 @@ namespace OpenRCT2 money32 CalculateCompanyValue() const; static uint8_t CalculateGuestInitialHappiness(uint8_t percentage); - Peep* GenerateGuest(); + Guest* GenerateGuest(); void ResetHistories(); void UpdateHistories(); @@ -85,7 +83,7 @@ namespace OpenRCT2 uint32_t CalculateGuestGenerationProbability() const; void GenerateGuests(); - Peep* GenerateGuestFromCampaign(int32_t campaign); + Guest* GenerateGuestFromCampaign(int32_t campaign); }; } // namespace OpenRCT2 diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index 974f5c6136..4986ea0140 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->ToCoordsXYZ().ToTileCentre()); + auto* peep = Guest::Generate(pos->ToCoordsXYZ().ToTileCentre()); // Peeps that are outside of the park use specialized pathfinding which we don't want to // use here diff --git a/test/tests/S6ImportExportTests.cpp b/test/tests/S6ImportExportTests.cpp index bb2cee2455..9ff24f93ec 100644 --- a/test/tests/S6ImportExportTests.cpp +++ b/test/tests/S6ImportExportTests.cpp @@ -154,11 +154,9 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right) COMPARE_FIELD(NextLoc.y); COMPARE_FIELD(NextLoc.z); COMPARE_FIELD(NextFlags); - COMPARE_FIELD(OutsideOfPark); COMPARE_FIELD(State); COMPARE_FIELD(SubState); COMPARE_FIELD(SpriteType); - COMPARE_FIELD(GuestNumRides); COMPARE_FIELD(TshirtColour); COMPARE_FIELD(TrousersColour); COMPARE_FIELD(DestinationX); @@ -167,27 +165,8 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right) COMPARE_FIELD(Var37); COMPARE_FIELD(Energy); COMPARE_FIELD(EnergyTarget); - COMPARE_FIELD(Happiness); - COMPARE_FIELD(HappinessTarget); - COMPARE_FIELD(Nausea); - COMPARE_FIELD(NauseaTarget); - COMPARE_FIELD(Hunger); - COMPARE_FIELD(Thirst); - COMPARE_FIELD(Toilet); COMPARE_FIELD(Mass); - COMPARE_FIELD(TimeToConsume); - COMPARE_FIELD(Intensity); - COMPARE_FIELD(NauseaTolerance); COMPARE_FIELD(WindowInvalidateFlags); - COMPARE_FIELD(PaidOnDrink); - for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) - { - COMPARE_FIELD(RideTypesBeenOn[i]); - } - COMPARE_FIELD(ItemFlags); - COMPARE_FIELD(Photo2RideRef); - COMPARE_FIELD(Photo3RideRef); - COMPARE_FIELD(Photo4RideRef); COMPARE_FIELD(CurrentRide); COMPARE_FIELD(CurrentRideStation); COMPARE_FIELD(CurrentTrain); @@ -199,32 +178,10 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right) COMPARE_FIELD(Action); COMPARE_FIELD(ActionFrame); COMPARE_FIELD(StepProgress); - COMPARE_FIELD(GuestNextInQueue); COMPARE_FIELD(MazeLastEdge); COMPARE_FIELD(InteractionRideIndex); - COMPARE_FIELD(TimeInQueue); - for (int i = 0; i < 32; i++) - { - COMPARE_FIELD(RidesBeenOn[i]); - } COMPARE_FIELD(Id); - COMPARE_FIELD(CashInPocket); - COMPARE_FIELD(CashSpent); - COMPARE_FIELD(ParkEntryTime); - COMPARE_FIELD(RejoinQueueTimeout); - COMPARE_FIELD(PreviousRide); - COMPARE_FIELD(PreviousRideTimeOut); - for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) - { - COMPARE_FIELD(Thoughts[i].type); - COMPARE_FIELD(Thoughts[i].item); - COMPARE_FIELD(Thoughts[i].freshness); - COMPARE_FIELD(Thoughts[i].fresh_timeout); - } COMPARE_FIELD(PathCheckOptimisation); - COMPARE_FIELD(GuestHeadingToRideId); - COMPARE_FIELD(StaffOrders); - COMPARE_FIELD(Photo1RideRef); COMPARE_FIELD(PeepFlags); COMPARE_FIELD(PathfindGoal.x); COMPARE_FIELD(PathfindGoal.y); @@ -238,6 +195,54 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right) COMPARE_FIELD(PathfindHistory[i].direction); } COMPARE_FIELD(WalkingFrameNum); +} + +static void CompareSpriteDataGuest(const Guest& left, const Guest& right) +{ + CompareSpriteDataPeep(left, right); + COMPARE_FIELD(OutsideOfPark); + COMPARE_FIELD(GuestNumRides); + COMPARE_FIELD(Happiness); + COMPARE_FIELD(HappinessTarget); + COMPARE_FIELD(Nausea); + COMPARE_FIELD(NauseaTarget); + COMPARE_FIELD(Hunger); + COMPARE_FIELD(Thirst); + COMPARE_FIELD(Toilet); + COMPARE_FIELD(TimeToConsume); + COMPARE_FIELD(Intensity); + COMPARE_FIELD(NauseaTolerance); + COMPARE_FIELD(PaidOnDrink); + for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) + { + COMPARE_FIELD(RideTypesBeenOn[i]); + } + COMPARE_FIELD(ItemFlags); + COMPARE_FIELD(Photo2RideRef); + COMPARE_FIELD(Photo3RideRef); + COMPARE_FIELD(Photo4RideRef); + COMPARE_FIELD(GuestNextInQueue); + COMPARE_FIELD(TimeInQueue); + for (int i = 0; i < 32; i++) + { + COMPARE_FIELD(RidesBeenOn[i]); + } + COMPARE_FIELD(CashInPocket); + COMPARE_FIELD(CashSpent); + COMPARE_FIELD(ParkEntryTime); + COMPARE_FIELD(RejoinQueueTimeout); + COMPARE_FIELD(PreviousRide); + COMPARE_FIELD(PreviousRideTimeOut); + for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) + { + COMPARE_FIELD(Thoughts[i].type); + COMPARE_FIELD(Thoughts[i].item); + COMPARE_FIELD(Thoughts[i].freshness); + COMPARE_FIELD(Thoughts[i].fresh_timeout); + } + COMPARE_FIELD(GuestHeadingToRideId); + COMPARE_FIELD(GuestIsLostCountdown); + COMPARE_FIELD(Photo1RideRef); COMPARE_FIELD(LitterCount); COMPARE_FIELD(GuestTimeOnRide); COMPARE_FIELD(DisgustingCount); @@ -262,6 +267,22 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right) COMPARE_FIELD(FavouriteRideRating); } +static void CompareSpriteDataStaff(const Staff& left, const Staff& right) +{ + CompareSpriteDataPeep(left, right); + + COMPARE_FIELD(AssignedStaffType); + COMPARE_FIELD(MechanicTimeSinceCall); + COMPARE_FIELD(HireDate); + COMPARE_FIELD(StaffId); + COMPARE_FIELD(StaffOrders); + COMPARE_FIELD(StaffMowingTimeout); + COMPARE_FIELD(StaffRidesFixed); + COMPARE_FIELD(StaffRidesInspected); + COMPARE_FIELD(StaffLitterSwept); + COMPARE_FIELD(StaffBinsEmptied); +} + static void CompareSpriteDataVehicle(const Vehicle& left, const Vehicle& right) { COMPARE_FIELD(SubType); @@ -413,8 +434,10 @@ static void CompareSpriteData(const rct_sprite& left, const rct_sprite& right) switch (left.misc.Type) { case EntityType::Guest: + CompareSpriteDataGuest(static_cast(left.peep), static_cast(right.peep)); + break; case EntityType::Staff: - CompareSpriteDataPeep(left.peep, right.peep); + CompareSpriteDataStaff(static_cast(left.peep), static_cast(right.peep)); break; case EntityType::Vehicle: CompareSpriteDataVehicle(left.vehicle, right.vehicle); From 7525f5d5da23a0b5020ed8591b5e78a6b7709a0a Mon Sep 17 00:00:00 2001 From: Hielke Morsink Date: Mon, 19 Apr 2021 19:44:11 +0200 Subject: [PATCH 32/45] Fix #14493: isHidden broken for elements with baseheight > 32 (#14499) --- distribution/changelog.txt | 1 + src/openrct2/scripting/ScTile.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 4a2928af94..b86be353b9 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -8,6 +8,7 @@ - Fix: [#13894] Block brakes do not animate. - Fix: [#14315] Crash when trying to rename Air Powered Vertical Coaster in Korean. - Fix: [#14330] join_server uses default_port from config. +- Fix: [#14493] [Plugin] isHidden only works for tile elements up to the first element with a base height of over 32. 0.3.3 (2021-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2/scripting/ScTile.hpp b/src/openrct2/scripting/ScTile.hpp index e7305bd5d1..e4dad4855b 100644 --- a/src/openrct2/scripting/ScTile.hpp +++ b/src/openrct2/scripting/ScTile.hpp @@ -836,7 +836,7 @@ namespace OpenRCT2::Scripting // Insert corrupt element at the end of the list for this tile // Note: Z = MAX_ELEMENT_HEIGHT to guarantee this TileElement* insertedElement = tile_element_insert( - { _coords, MAX_ELEMENT_HEIGHT }, 0, TileElementType::Corrupt); + { _coords, MAX_ELEMENT_HEIGHT * COORDS_Z_STEP }, 0, TileElementType::Corrupt); if (insertedElement == nullptr) { // TODO: Show error From 10bc3da9b9e355a6ee03bfadabcb1884b6cfb41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 20 Apr 2021 08:10:23 +0200 Subject: [PATCH 33/45] Improve shader compatibility with GLES (#14489) --- data/shaders/drawline.vert | 8 ++++---- data/shaders/drawrect.vert | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/shaders/drawline.vert b/data/shaders/drawline.vert index 2faf19dc2a..dea6af7f47 100644 --- a/data/shaders/drawline.vert +++ b/data/shaders/drawline.vert @@ -16,12 +16,12 @@ flat out uint fColour; void main() { - vec2 pos = clamp(vVertMat * vBounds, vClip.xy, vClip.zw); + vec2 pos = clamp(vVertMat * vec4(vBounds), vec2(vClip.xy), vec2(vClip.zw)); // Transform screen coordinates to viewport coordinates - pos = (pos * (2.0 / uScreenSize)) - 1.0; - pos.y *= -1; - float depth = 1.0 - (vDepth + 1) * DEPTH_INCREMENT; + pos = (pos * (2.0 / vec2(uScreenSize))) - 1.0; + pos.y *= -1.0; + float depth = 1.0 - (float(vDepth) + 1.0) * DEPTH_INCREMENT; fColour = vColour; diff --git a/data/shaders/drawrect.vert b/data/shaders/drawrect.vert index b752f364dc..6c1e0a9be7 100644 --- a/data/shaders/drawrect.vert +++ b/data/shaders/drawrect.vert @@ -30,16 +30,16 @@ flat out vec3 fPalettes; void main() { // Clamp position by vClip, correcting interpolated values for the clipping - vec2 m = clamp(((vVertMat * vClip) - (vVertMat * vBounds))/(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0); - vec2 pos = mix(vBounds.xy, vBounds.zw, m); + vec2 m = clamp(((vVertMat * vec4(vClip)) - (vVertMat * vec4(vBounds)))/vec2(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0); + vec2 pos = mix(vec2(vBounds.xy), vec2(vBounds.zw), m); fTexColour = vec3(mix(vTexColourBounds.xy, vTexColourBounds.zw, m), vTexColourAtlas); fTexMask = vec3(mix(vTexMaskBounds.xy, vTexMaskBounds.zw, m), vTexMaskAtlas); fPosition = pos; // Transform screen coordinates to texture coordinates - float depth = 1.0 - (vDepth + 1) * DEPTH_INCREMENT; - pos = pos / uScreenSize; + float depth = 1.0 - (float(vDepth) + 1.0) * DEPTH_INCREMENT; + pos = pos / vec2(uScreenSize); pos.y = pos.y * -1.0 + 1.0; fPeelPos = vec3(pos, depth * 0.5 + 0.5); From 594b08c911a739070ee161359b559e7772db325c Mon Sep 17 00:00:00 2001 From: Basssiiie Date: Wed, 21 Apr 2021 15:32:55 +0200 Subject: [PATCH 34/45] Rename 'Object' to 'LoadedObject' --- distribution/changelog.txt | 1 + distribution/openrct2.d.ts | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b86be353b9..cc11962863 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,6 +3,7 @@ - Feature: [#13967] Track List window now displays the path to the design when debugging tools are on. - Feature: [#14071] “Vandals stopped” statistic for security guards. - Feature: [#14296] Allow using early scenario completion in multiplayer. +- Change: [#14496] [Plugin] Rename Object to LoadedObject to fix conflicts with Typescript's Object interface. - Fix: [#11829] Visual glitches and crashes when using RCT1 assets from mismatched or corrupt CSG1.DAT and CSG1i.DAT files. - Fix: [#13581] Opening the Options menu causes a noticeable drop in FPS. - Fix: [#13894] Block brakes do not animate. diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index ff19df3337..74486a37e0 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -186,11 +186,11 @@ declare global { * @param type The object type. * @param index The index. */ - getObject(type: ObjectType, index: number): Object; + getObject(type: ObjectType, index: number): LoadedObject; getObject(type: "ride", index: number): RideObject; getObject(type: "small_scenery", index: number): SmallSceneryObject; - getAllObjects(type: ObjectType): Object[]; + getAllObjects(type: ObjectType): LoadedObject[]; getAllObjects(type: "ride"): RideObject[]; /** @@ -724,7 +724,7 @@ declare global { /** * Represents the definition of a loaded object (.DAT or .json) such a ride type or scenery item. */ - interface Object { + interface LoadedObject { /** * The object type. */ @@ -757,7 +757,7 @@ declare global { /** * Represents the object definition of a ride or stall. */ - interface RideObject extends Object { + interface RideObject extends LoadedObject { /** * The description of the ride / stall in the player's current language. */ @@ -840,7 +840,7 @@ declare global { /** * Represents the object definition of a small scenery item such a tree. */ - interface SmallSceneryObject extends Object { + interface SmallSceneryObject extends LoadedObject { /** * Raw bit flags that describe characteristics of the scenery item. */ From c2f16a54aa65f3efc45725c0edadc2d96ba34a76 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:23:52 -1000 Subject: [PATCH 35/45] localisation.yml: Use working-directory --- .github/workflows/localisation.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/localisation.yml b/.github/workflows/localisation.yml index 99b47d587e..e41a110fa7 100644 --- a/.github/workflows/localisation.yml +++ b/.github/workflows/localisation.yml @@ -29,8 +29,8 @@ jobs: cp $f "./OpenRCT2/data/language/$filename" done - name: Commit and push + working-directory: OpenRCT2 run: | - pushd ./OpenRCT2 if [[ $(git status -s) ]]; then echo "Committing and pushing..." git add . @@ -42,4 +42,3 @@ jobs: else echo "No changes to merge." fi - popd From 55d7df32fdbd6f7ce09dd1aca12d16e077289d7e Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:24:30 -1000 Subject: [PATCH 36/45] localisation.yml: Use --depth 1 to speed up cloning --- .github/workflows/localisation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/localisation.yml b/.github/workflows/localisation.yml index e41a110fa7..624028fa09 100644 --- a/.github/workflows/localisation.yml +++ b/.github/workflows/localisation.yml @@ -18,7 +18,7 @@ jobs: - name: Clone repositories run: | echo "Cloning repositories..." - git clone -b master git@github.com:OpenRCT2/Localisation.git Localisation + git clone -b master --depth 1 git@github.com:OpenRCT2/Localisation.git Localisation git clone -b develop git@github.com:OpenRCT2/OpenRCT2.git OpenRCT2 - name: Copy over language files run: | From 08061d518b3412474eb365b510922a650d687ac2 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:24:51 -1000 Subject: [PATCH 37/45] localisation.yml: Remove whitespace after cron --- .github/workflows/localisation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/localisation.yml b/.github/workflows/localisation.yml index 624028fa09..6efae26592 100644 --- a/.github/workflows/localisation.yml +++ b/.github/workflows/localisation.yml @@ -1,7 +1,7 @@ name: Localisation Merge on: schedule: - - cron: '0 4 * * *' + - cron: '0 4 * * *' jobs: merge-localisation: name: Merge Localisation From bc5e8f7dd28ed417b822d3de07d78923f8a93864 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:32:14 -1000 Subject: [PATCH 38/45] ci.yml: job-wide bash --- .github/workflows/ci.yml | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94b673621f..1790e3052a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,8 @@ name: CI on: [push, pull_request] +defaults: + run: + shell: bash env: OPENRCT2_BUILD_SERVER: GitHub OPENRCT2_ORG_TOKEN: ${{ secrets.OPENRCT2_ORG_TOKEN }} @@ -47,10 +50,8 @@ jobs: - name: Checkout uses: actions/checkout@v1 - name: Build OpenRCT2 - shell: bash run: . scripts/setenv && build - name: Build artifacts - shell: bash run: | . scripts/setenv -q build-portable @@ -62,10 +63,8 @@ jobs: name: "OpenRCT2-Windows-${{ matrix.platform }}" path: artifacts/* - name: Run Tests - shell: bash run: . scripts/setenv -q && run-tests - name: Upload artifacts (openrct2.org) - shell: bash run: | . scripts/setenv -q if [[ "$OPENRCT2_PUSH" == "true" ]]; then @@ -164,10 +163,8 @@ jobs: brew install ninja . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=on - name: Run Tests - shell: bash run: . scripts/setenv -q && run-tests - name: Build artifacts - shell: bash run: | . scripts/setenv mkdir -p artifacts @@ -194,13 +191,10 @@ jobs: with: key: linux-portable - name: Get pre-reqs - shell: bash run: . scripts/setenv && get-discord-rpc - name: Build OpenRCT2 - shell: bash run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g -gz" - name: Build artifacts - shell: bash run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-x86_64.tar.gz bin/install/usr - name: Upload artifacts (CI) uses: actions/upload-artifact@v1 @@ -208,10 +202,8 @@ jobs: name: "OpenRCT2-Linux-x86_64" path: artifacts - name: Run Tests - shell: bash run: . scripts/setenv -q && run-tests - name: Upload artifacts (openrct2.org) - shell: bash run: | . scripts/setenv -q if [[ "$OPENRCT2_PUSH" == "true" ]]; then @@ -233,13 +225,10 @@ jobs: with: key: linux-portable-32 - name: Get pre-reqs - shell: bash run: . scripts/setenv && get-discord-rpc - name: Build OpenRCT2 - shell: bash - run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DFORCE32=ON -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g -gz -m32" + run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DFORCE32=ON -DENABLE_SCRIPTING=OFF -DCMAKE_CXX_FLAGS="-m32 -gz" - name: Build artifacts - shell: bash run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-i686.tar.gz bin/install/usr - name: Upload artifacts (CI) uses: actions/upload-artifact@v1 @@ -247,10 +236,8 @@ jobs: name: "OpenRCT2-Linux-i686" path: artifacts - name: Run Tests - shell: bash run: . scripts/setenv -q && run-tests - name: Upload artifacts (openrct2.org) - shell: bash run: | . scripts/setenv -q if [[ "$OPENRCT2_PUSH" == "true" ]]; then @@ -272,13 +259,10 @@ jobs: with: key: linux-appimage - name: Get pre-reqs - shell: bash run: . scripts/setenv -q && get-discord-rpc - name: Build OpenRCT2 - shell: bash run: . scripts/setenv -q && build -DCMAKE_BUILD_TYPE=Release -DAPPIMAGE=ON -DOPENRCT2_USE_CCACHE=on - name: Build AppImage - shell: bash run: . scripts/setenv -q && build-appimage - name: Upload artifacts (CI) uses: actions/upload-artifact@v1 @@ -334,7 +318,6 @@ jobs: with: key: linux-clang - name: Build OpenRCT2 - shell: bash run: . scripts/setenv && build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DDISABLE_NETWORK=ON -DDISABLE_HTTP=ON -DDISABLE_OPENGL=ON android: name: Android @@ -350,7 +333,6 @@ jobs: with: key: android - name: Build OpenRCT2 - shell: bash run: | . scripts/setenv pushd src/openrct2-android @@ -364,7 +346,6 @@ jobs: name: "OpenRCT2-Android" path: artifacts - name: Upload artifacts (openrct2.org) - shell: bash run: | . scripts/setenv -q if [[ "$OPENRCT2_PUSH" == "true" ]]; then From 839aa5c625855473772a37620c0ed55f87baf2fc Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:46:59 -1000 Subject: [PATCH 39/45] ci.yml: upload-artifact improvements Upgrade to v2. name: Remove unneeded quotation marks. Use runner.os when possible. if-no-files-found: error --- .github/workflows/ci.yml | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1790e3052a..8aa74c5377 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,10 +58,11 @@ jobs: build-symbols build-installer -i - name: Upload artifacts (CI) - uses: actions/upload-artifact@v2-preview + uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-Windows-${{ matrix.platform }}" - path: artifacts/* + name: OpenRCT2-${{ runner.os }}-${{ matrix.platform }} + path: artifacts + if-no-files-found: error - name: Run Tests run: . scripts/setenv -q && run-tests - name: Upload artifacts (openrct2.org) @@ -114,10 +115,11 @@ jobs: cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=MinSizeRel -DDISABLE_IPO=on -DDISABLE_HTTP=Off -DFORCE32=on -DENABLE_SCRIPTING=ON -DCMAKE_CXX_FLAGS="-Wno-error=cast-function-type -Wno-error=unused-function" -DSTATIC=on -DMINGW_TARGET_NT5_1=ON ninja -k0 - name: Upload artifacts (CI) - uses: actions/upload-artifact@v2-preview + uses: actions/upload-artifact@v2 with: name: "OpenRCT2-NT5.1" path: bin/openrct2.exe + if-no-files-found: error macos-xcode: name: macOS (x64) using Xcode runs-on: macos-latest @@ -135,10 +137,11 @@ jobs: cd artifacts zip -rq openrct2-macos.zip OpenRCT2.app - name: Upload artifacts (CI) - uses: actions/upload-artifact@v2-preview + uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-macOS-xcode" + name: OpenRCT2-${{ runner.os }}-xcode path: artifacts/openrct2-macos.zip + if-no-files-found: error - name: Upload artifacts (openrct2.org) run: | . scripts/setenv @@ -173,10 +176,11 @@ jobs: cd artifacts zip -rqy openrct2-macos.zip OpenRCT2.app - name: Upload artifacts (CI) - uses: actions/upload-artifact@v2-preview + uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-macOS-cmake" + name: OpenRCT2-${{ runner.os }}-cmake path: artifacts/openrct2-macos.zip + if-no-files-found: error linux-portable: name: Linux (x64, portable) runs-on: ubuntu-latest @@ -231,10 +235,11 @@ jobs: - name: Build artifacts run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-i686.tar.gz bin/install/usr - name: Upload artifacts (CI) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: "OpenRCT2-Linux-i686" path: artifacts + if-no-files-found: error - name: Run Tests run: . scripts/setenv -q && run-tests - name: Upload artifacts (openrct2.org) @@ -265,10 +270,11 @@ jobs: - name: Build AppImage run: . scripts/setenv -q && build-appimage - name: Upload artifacts (CI) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: OpenRCT2-AppImage path: artifacts + if-no-files-found: error linux-flathub-beta: name: Linux (Flathub beta channel) if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' && github.event_name == 'push' @@ -341,10 +347,11 @@ jobs: mkdir -p artifacts mv src/openrct2-android/app/build/outputs/apk/arm/pr/app-arm-pr.apk artifacts/openrct2-arm.apk - name: Upload artifacts (CI) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-Android" + name: OpenRCT2-Android path: artifacts + if-no-files-found: error - name: Upload artifacts (openrct2.org) run: | . scripts/setenv -q From 5308a2130567ea2e07e5d2c9d3f9a16f28a75691 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 14 Apr 2021 23:50:22 -1000 Subject: [PATCH 40/45] ci.yml: Checkout improvements Always use v2. Replace git clone with checkout. --- .github/workflows/ci.yml | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8aa74c5377..c05a22a5f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: image: openrct2/openrct2-build:0.3.1-format steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Run clang-format shell: sh run: scripts/check-code-formatting @@ -48,7 +48,7 @@ jobs: PLATFORM: ${{ matrix.platform }} steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Build OpenRCT2 run: . scripts/setenv && build - name: Build artifacts @@ -126,7 +126,7 @@ jobs: needs: [check-code-formatting] steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Build OpenRCT2 run: | . scripts/setenv @@ -156,7 +156,7 @@ jobs: needs: [check-code-formatting] steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: @@ -223,7 +223,7 @@ jobs: image: openrct2/openrct2-build:0.3.1-bionic32 steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: @@ -258,7 +258,7 @@ jobs: image: openrct2/openrct2-build:0.3.1-bionic steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: @@ -293,10 +293,12 @@ jobs: if: github.repository == 'OpenRCT2/OpenRCT2' runs-on: ubuntu-latest steps: + - name: Checkout image + uses: actions/checkout@v2 + with: + repository: OpenRCT2/openrct2-docker - name: Build image - run: | - git clone --depth 1 https://github.com/OpenRCT2/openrct2-docker . - docker build -t openrct2/openrct2-cli:develop develop/cli + run: docker build -t openrct2/openrct2-cli:develop develop/cli - name: Push image env: OPENRCT2_DOCKER_USER: ${{ secrets.OPENRCT2_DOCKER_USER }} @@ -318,7 +320,7 @@ jobs: image: openrct2/openrct2-build:0.3.1-bionic steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: @@ -333,7 +335,7 @@ jobs: image: openrct2/openrct2-build:0.3.1-android steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: From 87de1971d94fff991e005db6e9a8bb9d59ab5b85 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Thu, 15 Apr 2021 00:00:59 -1000 Subject: [PATCH 41/45] ci.yml: Remove brackets around check-code-formatting They're unneeded since it's one item. --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c05a22a5f4..a98aca6602 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: windows: name: Windows runs-on: windows-latest - needs: [check-code-formatting] + needs: check-code-formatting strategy: fail-fast: false matrix: @@ -98,7 +98,7 @@ jobs: windows-mingw-nt51: name: Windows (win32, WinNT5.1) using mingw runs-on: ubuntu-latest - needs: [check-code-formatting] + needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-mingw steps: @@ -123,7 +123,7 @@ jobs: macos-xcode: name: macOS (x64) using Xcode runs-on: macos-latest - needs: [check-code-formatting] + needs: check-code-formatting steps: - name: Checkout uses: actions/checkout@v2 @@ -153,7 +153,7 @@ jobs: macos-cmake: name: macOS (x64) using CMake runs-on: macos-latest - needs: [check-code-formatting] + needs: check-code-formatting steps: - name: Checkout uses: actions/checkout@v2 @@ -184,7 +184,7 @@ jobs: linux-portable: name: Linux (x64, portable) runs-on: ubuntu-latest - needs: [check-code-formatting] + needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-bionic steps: @@ -253,7 +253,7 @@ jobs: linux-appimage: name: Linux (x64, AppImage) runs-on: ubuntu-latest - needs: [check-code-formatting] + needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-bionic steps: @@ -289,7 +289,7 @@ jobs: client-payload: '{ "commit": "${{ github.sha }}" }' linux-docker: name: Linux (docker) - needs: [check-code-formatting] + needs: check-code-formatting if: github.repository == 'OpenRCT2/OpenRCT2' runs-on: ubuntu-latest steps: @@ -315,7 +315,7 @@ jobs: linux-clang: name: Linux (Debug, [http, network, OpenGL] disabled) using clang runs-on: ubuntu-latest - needs: [check-code-formatting] + needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-bionic steps: @@ -330,7 +330,7 @@ jobs: android: name: Android runs-on: ubuntu-latest - needs: [check-code-formatting] + needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-android steps: From 58cd2e2609cd9bc01185976b655a6a320e1207ba Mon Sep 17 00:00:00 2001 From: Margen67 Date: Thu, 15 Apr 2021 00:43:39 -1000 Subject: [PATCH 42/45] ci.yml: Make windows-mingw and linux-portable into matrix Artifact name improvements had to be bunched in here. Change build configuration to Release. --- .github/workflows/ci.yml | 102 +++++++++++++++------------------------ 1 file changed, 38 insertions(+), 64 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a98aca6602..478277b111 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,47 +77,42 @@ jobs: echo 'Not going to push build' fi windows-mingw: - name: Windows (win32) using mingw - runs-on: ubuntu-latest - needs: [check-code-formatting] - container: - image: openrct2/openrct2-build:0.3.1-mingw - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: ccache - uses: hendrikmuhs/ccache-action@v1 - with: - key: windows-mingw - - name: Build OpenRCT2 - run: | - sudo su - mkdir bin && cd bin - cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=MinSizeRel -DDISABLE_IPO=on -DFORCE32=on -DBUILD_SHARED_LIBS=ON -DENABLE_SCRIPTING=OFF - ninja -k0 - windows-mingw-nt51: - name: Windows (win32, WinNT5.1) using mingw + name: Windows (${{ matrix.platform_name }}) using mingw runs-on: ubuntu-latest needs: check-code-formatting container: image: openrct2/openrct2-build:0.3.1-mingw + strategy: + fail-fast: false + matrix: + platform: [win32, NT5.1] + include: + - platform: win32 + platform_name: win32 + cache_key: windows-mingw + build_flags: -DBUILD_SHARED_LIBS=ON -DENABLE_SCRIPTING=OFF + - platform: NT5.1 + platform_name: win32, NT5.1 + cache_key: windows-mingw-nt51 + build_flags: -DDISABLE_HTTP=Off -DENABLE_SCRIPTING=ON -DCMAKE_CXX_FLAGS="-Wno-error=cast-function-type -Wno-error=unused-function" -DSTATIC=on -DMINGW_TARGET_NT5_1=ON steps: - name: Checkout uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: - key: windows-mingw-nt51 + key: ${{ matrix.cache_key }} - name: Build OpenRCT2 run: | sudo su mkdir bin && cd bin - cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=MinSizeRel -DDISABLE_IPO=on -DDISABLE_HTTP=Off -DFORCE32=on -DENABLE_SCRIPTING=ON -DCMAKE_CXX_FLAGS="-Wno-error=cast-function-type -Wno-error=unused-function" -DSTATIC=on -DMINGW_TARGET_NT5_1=ON + cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=Release -DDISABLE_IPO=on -DFORCE32=on ${{ matrix.build_flags }} ninja -k0 - name: Upload artifacts (CI) + if: matrix.platform == 'NT5.1' uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-NT5.1" + name: OpenRCT2-${{ matrix.platform }} path: bin/openrct2.exe if-no-files-found: error macos-xcode: @@ -182,62 +177,41 @@ jobs: path: artifacts/openrct2-macos.zip if-no-files-found: error linux-portable: - name: Linux (x64, portable) + name: Linux (${{ matrix.platform }}, portable) runs-on: ubuntu-latest needs: check-code-formatting container: - image: openrct2/openrct2-build:0.3.1-bionic - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: ccache - uses: hendrikmuhs/ccache-action@v1 - with: - key: linux-portable - - name: Get pre-reqs - run: . scripts/setenv && get-discord-rpc - - name: Build OpenRCT2 - run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g -gz" - - name: Build artifacts - run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-x86_64.tar.gz bin/install/usr - - name: Upload artifacts (CI) - uses: actions/upload-artifact@v1 - with: - name: "OpenRCT2-Linux-x86_64" - path: artifacts - - name: Run Tests - run: . scripts/setenv -q && run-tests - - name: Upload artifacts (openrct2.org) - run: | - . scripts/setenv -q - if [[ "$OPENRCT2_PUSH" == "true" ]]; then - upload-build artifacts/OpenRCT2-Linux-x86_64.tar.gz linux-x86_64 $OPENRCT2_VERSION $OPENRCT2_SHA1 $OPENRCT2_BRANCH - else - echo 'Not going to push build' - fi - linux-portable-32: - name: Linux (i686, portable) - runs-on: ubuntu-latest - needs: [check-code-formatting] - container: - image: openrct2/openrct2-build:0.3.1-bionic32 + image: ${{ matrix.image }} + strategy: + fail-fast: false + matrix: + platform: [x86_64, i686] + include: + - platform: x86_64 + image: openrct2/openrct2-build:0.3.1-bionic + cache_key: linux-portable + build_flags: -DCMAKE_POSITION_INDEPENDENT_CODE=on -DCMAKE_CXX_FLAGS="-g -gz" + - platform: i686 + image: openrct2/openrct2-build:0.3.1-bionic32 + cache_key: linux-portable-32 + build_flags: -DFORCE32=ON -DENABLE_SCRIPTING=OFF -DCMAKE_CXX_FLAGS="-m32 -gz" steps: - name: Checkout uses: actions/checkout@v2 - name: ccache uses: hendrikmuhs/ccache-action@v1 with: - key: linux-portable-32 + key: ${{ matrix.cache_key }} - name: Get pre-reqs run: . scripts/setenv && get-discord-rpc - name: Build OpenRCT2 - run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON -DFORCE32=ON -DENABLE_SCRIPTING=OFF -DCMAKE_CXX_FLAGS="-m32 -gz" + run: . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DPORTABLE=ON ${{ matrix.build_flags }} - name: Build artifacts - run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-Linux-i686.tar.gz bin/install/usr + run: . scripts/setenv -q && build-portable artifacts/OpenRCT2-${{ runner.os }}-${{ matrix.platform }}.tar.gz bin/install/usr - name: Upload artifacts (CI) uses: actions/upload-artifact@v2 with: - name: "OpenRCT2-Linux-i686" + name: OpenRCT2-${{ runner.os }}-${{ matrix.platform }} path: artifacts if-no-files-found: error - name: Run Tests @@ -246,7 +220,7 @@ jobs: run: | . scripts/setenv -q if [[ "$OPENRCT2_PUSH" == "true" ]]; then - upload-build artifacts/OpenRCT2-Linux-i686.tar.gz linux-i686 $OPENRCT2_VERSION $OPENRCT2_SHA1 $OPENRCT2_BRANCH + upload-build artifacts/OpenRCT2-${{ runner.os }}-${{ matrix.platform }}.tar.gz linux-${{ matrix.platform }} $OPENRCT2_VERSION $OPENRCT2_SHA1 $OPENRCT2_BRANCH else echo 'Not going to push build' fi From d195a3edd64a49540fcaf29ec1b530ae04452c1b Mon Sep 17 00:00:00 2001 From: Margen67 Date: Thu, 15 Apr 2021 00:44:36 -1000 Subject: [PATCH 43/45] ci.yml: Change macOS configuration to Release --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 478277b111..80b3330902 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -159,7 +159,7 @@ jobs: - name: Build OpenRCT2 run: | brew install ninja - . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=on + . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=on - name: Run Tests run: . scripts/setenv -q && run-tests - name: Build artifacts From 2f74a4648477b696f5fa9b853edcef0aaae50374 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Thu, 15 Apr 2021 00:45:05 -1000 Subject: [PATCH 44/45] ci.yml: HOMEBREW_NO_ANALYTICS=1 Opts out of analytics. See https://docs.brew.sh/Analytics --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80b3330902..66f8c3d038 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -158,7 +158,7 @@ jobs: key: macos - name: Build OpenRCT2 run: | - brew install ninja + HOMEBREW_NO_ANALYTICS=1 brew install ninja . scripts/setenv -q && build -DWITH_TESTS=on -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=on - name: Run Tests run: . scripts/setenv -q && run-tests From 4933b9ee4037fa0b57547037f220bfd1cd3d6411 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Thu, 15 Apr 2021 00:45:22 -1000 Subject: [PATCH 45/45] ci.yml: Upgrade commitlint-github-action to v3 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66f8c3d038..0e84ff1e7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: with: fetch-depth: 0 - name: Lint Commit Messages - uses: wagoid/commitlint-github-action@v1 + uses: wagoid/commitlint-github-action@v3 with: configFile: .commitlint.json check-code-formatting: