diff --git a/contributors.md b/contributors.md index 0a04899ff0..0a8a3039d1 100644 --- a/contributors.md +++ b/contributors.md @@ -92,6 +92,7 @@ The following people are not part of the development team, but have been contrib * Helio Batimarqui (batimarqui) - Misc. * Keith Stellyes (keithstellyes) - Misc. * Bas Cantrijn (Basssiiie) - Misc. +* Adrian Zdanowicz (CookiePLMonster) - Misc. ## Bug fixes * (halfbro) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 32b136b9c7..ebdd4ba6e6 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3679,14 +3679,15 @@ STR_6436 :Toggle invisibility STR_6437 :Invisible STR_6438 :I STR_6439 :Tile Inspector: Toggle invisibility -STR_6440 :At least one non-queue footpath surface object must be selected. -STR_6441 :At least one queue footpath surface object must be selected. -STR_6442 :At least one footpath railing object must be selected. -STR_6443 :Footpath Surfaces -STR_6444 :Footpath Railings -STR_6445 :{WINDOW_COLOUR_2}Surface name: {BLACK}{STRINGID} -STR_6446 :{WINDOW_COLOUR_2}Railing name: {BLACK}{STRINGID} -STR_6447 :Unsupported object format +STR_6440 :Transparent water +STR_6441 :At least one non-queue footpath surface object must be selected. +STR_6442 :At least one queue footpath surface object must be selected. +STR_6443 :At least one footpath railing object must be selected. +STR_6444 :Footpath Surfaces +STR_6445 :Footpath Railings +STR_6446 :{WINDOW_COLOUR_2}Surface name: {BLACK}{STRINGID} +STR_6447 :{WINDOW_COLOUR_2}Railing name: {BLACK}{STRINGID} +STR_6448 :Unsupported object format ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f0c2a3da24..f7cd4c99cf 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Feature: [#14538] [Plugin] Add property for getting current plugin api version. - Feature: [#14620] [Plugin] Add properties related to guest generation. - Feature: [#14636] [Plugin] Add properties related to climate and weather. +- Feature: [#14731] Opaque water (like in RCT1). - Change: [#14496] [Plugin] Rename Object to LoadedObject to fix conflicts with Typescript's Object interface. - Change: [#14536] [Plugin] Rename ListView to ListViewWidget to make it consistent with names of other widgets. - Fix: [#11829] Visual glitches and crashes when using RCT1 assets from mismatched or corrupt CSG1.DAT and CSG1i.DAT files. @@ -14,12 +15,17 @@ - Fix: [#13986] OpenGL: Track preview window, flip/rotate button do not update the thumbnail. - Fix: [#14315] Crash when trying to rename Air Powered Vertical Coaster in Korean. - Fix: [#14330] join_server uses default_port from config. +- Fix: [#14415] Entrances/exits are removed when built on top of each other. - Fix: [#14449] Surface smoothing at extra zoom levels not working. - Fix: [#14468] Cannot close Options window on Android. - Fix: [#14493] [Plugin] isHidden only works for tile elements up to the first element with a base height of over 32. - Fix: [#14587] Confusing message when joining server with mismatched network version. - Fix: [#14604] American-style Steam Trains are not imported correctly from RCT1 saves. - Fix: [#14638] The “About OpenRCT2” window cannot be themed. +- Fix: [#14682] Crash when painting Swinging Ships with invalid subtype. +- Fix: [#14707] Crash when window is closed during text input. +- Fix: [#14710] Ride/Track Design preview does not show if it costs more money than available. +- Improved: [#14712, #14716]: Improve startup times. 0.3.3 (2021-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2-ui/input/ShortcutIds.h b/src/openrct2-ui/input/ShortcutIds.h index 1cba3a2616..a2a3228868 100644 --- a/src/openrct2-ui/input/ShortcutIds.h +++ b/src/openrct2-ui/input/ShortcutIds.h @@ -69,6 +69,7 @@ namespace OpenRCT2::Ui::ShortcutId // View / toggle constexpr std::string_view ViewToggleUnderground = "view.toggle.show_underground"; + constexpr std::string_view ViewToggleTransparentWater = "view.toggle.transparent_water"; constexpr std::string_view ViewToggleBaseLand = "view.toggle.hide_base_land"; constexpr std::string_view ViewToggleVerticalLand = "view.toggle.hide_vertical_land"; constexpr std::string_view ViewToggleRides = "view.toggle.transparent_rides"; diff --git a/src/openrct2-ui/input/Shortcuts.cpp b/src/openrct2-ui/input/Shortcuts.cpp index df260eade1..6222fc528c 100644 --- a/src/openrct2-ui/input/Shortcuts.cpp +++ b/src/openrct2-ui/input/Shortcuts.cpp @@ -698,6 +698,15 @@ static void ShortcutConstructionDemolishCurrent() } } +static void ShortcutToggleTransparentWater() +{ + if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) + return; + + gConfigGeneral.transparent_water ^= 1; + config_save_default(); +} + #pragma endregion using namespace OpenRCT2::Ui; @@ -811,6 +820,7 @@ void ShortcutManager::RegisterDefaultShortcuts() RegisterShortcut(ShortcutId::ViewScrollDown, STR_SHORTCUT_SCROLL_MAP_DOWN, "DOWN", []() { }); RegisterShortcut(ShortcutId::ViewToggleUnderground, STR_SHORTCUT_UNDERGROUND_VIEW_TOGGLE, "1", []() { ToggleViewFlag(VIEWPORT_FLAG_UNDERGROUND_INSIDE); }); + RegisterShortcut(ShortcutId::ViewToggleTransparentWater, STR_VIEWPORT_TRANSPARENT_WATER, "2", []() { ShortcutToggleTransparentWater(); }); RegisterShortcut(ShortcutId::ViewToggleBaseLand, STR_SHORTCUT_REMOVE_BASE_LAND_TOGGLE, "H", []() { ToggleViewFlag(VIEWPORT_FLAG_HIDE_BASE); }); RegisterShortcut(ShortcutId::ViewToggleVerticalLand, STR_SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE, "V", []() { ToggleViewFlag(VIEWPORT_FLAG_HIDE_VERTICAL); }); RegisterShortcut(ShortcutId::ViewToggleRides, STR_SHORTCUT_SEE_THROUGH_RIDES_TOGGLE, "3", []() { ToggleViewFlag(VIEWPORT_FLAG_SEETHROUGH_RIDES); }); diff --git a/src/openrct2-ui/interface/Theme.cpp b/src/openrct2-ui/interface/Theme.cpp index 5af3632d10..192d04d23a 100644 --- a/src/openrct2-ui/interface/Theme.cpp +++ b/src/openrct2-ui/interface/Theme.cpp @@ -536,7 +536,7 @@ namespace ThemeManager } auto themesPattern = Path::Combine(GetThemePath(), "*.json"); - auto scanner = std::unique_ptr(Path::ScanDirectory(themesPattern, true)); + auto scanner = Path::ScanDirectory(themesPattern, true); while (scanner->Next()) { auto fileInfo = scanner->GetFileInfo(); diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 4aa65c10b8..15254b1f11 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -913,7 +913,7 @@ static void window_loadsave_populate_list(rct_window* w, int32_t includeNewItem, safe_strcat_path(filter, "*", std::size(filter)); path_append_extension(filter, extToken, std::size(filter)); - auto scanner = std::unique_ptr(Path::ScanDirectory(filter, false)); + auto scanner = Path::ScanDirectory(filter, false); while (scanner->Next()) { LoadSaveListItem newListItem; diff --git a/src/openrct2-ui/windows/TextInput.cpp b/src/openrct2-ui/windows/TextInput.cpp index 956252064c..dd5fd1336b 100644 --- a/src/openrct2-ui/windows/TextInput.cpp +++ b/src/openrct2-ui/windows/TextInput.cpp @@ -408,6 +408,9 @@ void window_text_input_open( void window_text_input_key(rct_window* w, char keychar) { + const auto wndNumber = w->number; + const auto wndClass = w->classification; + // If the return button is pressed stop text input if (keychar == '\r') { @@ -417,5 +420,9 @@ void window_text_input_key(rct_window* w, char keychar) textInputWindow->OnReturnPressed(); } } - w->Invalidate(); + + // The window can be potentially closed within a callback, we need to check if its still alive. + w = window_find_by_number(wndClass, wndNumber); + if (w != nullptr) + w->Invalidate(); } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 07bf9c0f56..2516d70c5e 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -127,19 +127,22 @@ enum FILE_MENU_DDIDX { enum TOP_TOOLBAR_VIEW_MENU_DDIDX { DDIDX_UNDERGROUND_INSIDE = 0, - DDIDX_HIDE_BASE = 1, - DDIDX_HIDE_VERTICAL = 2, - DDIDX_SEETHROUGH_RIDES = 4, - DDIDX_SEETHROUGH_SCENARY = 5, - DDIDX_SEETHROUGH_PATHS = 6, - DDIDX_INVISIBLE_SUPPORTS = 7, - DDIDX_INVISIBLE_PEEPS = 8, - DDIDX_LAND_HEIGHTS = 10, - DDIDX_TRACK_HEIGHTS = 11, - DDIDX_PATH_HEIGHTS = 12, - // 13 is a separator - DDIDX_VIEW_CLIPPING = 14, - DDIDX_HIGHLIGHT_PATH_ISSUES = 15, + DDIDX_TRANSPARENT_WATER = 1, + DDIDX_HIDE_BASE = 2, + DDIDX_HIDE_VERTICAL = 3, + // separator + DDIDX_SEETHROUGH_RIDES = 5, + DDIDX_SEETHROUGH_SCENERY = 6, + DDIDX_SEETHROUGH_PATHS = 7, + DDIDX_INVISIBLE_SUPPORTS = 8, + DDIDX_INVISIBLE_PEEPS = 9, + // separator + DDIDX_LAND_HEIGHTS = 11, + DDIDX_TRACK_HEIGHTS = 12, + DDIDX_PATH_HEIGHTS = 13, + // separator + DDIDX_VIEW_CLIPPING = 15, + DDIDX_HIGHLIGHT_PATH_ISSUES = 16, TOP_TOOLBAR_VIEW_MENU_COUNT }; @@ -3598,14 +3601,14 @@ static void top_toolbar_network_menu_dropdown(int16_t dropdownIndex) static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) { using namespace Dropdown; - constexpr Item items[] = { ToggleOption(DDIDX_UNDERGROUND_INSIDE, STR_UNDERGROUND_VIEW), + ToggleOption(DDIDX_TRANSPARENT_WATER, STR_VIEWPORT_TRANSPARENT_WATER), ToggleOption(DDIDX_HIDE_BASE, STR_REMOVE_BASE_LAND), ToggleOption(DDIDX_HIDE_VERTICAL, STR_REMOVE_VERTICAL_FACES), Separator(), ToggleOption(DDIDX_SEETHROUGH_RIDES, STR_SEE_THROUGH_RIDES), - ToggleOption(DDIDX_SEETHROUGH_SCENARY, STR_SEE_THROUGH_SCENERY), + ToggleOption(DDIDX_SEETHROUGH_SCENERY, STR_SEE_THROUGH_SCENERY), ToggleOption(DDIDX_SEETHROUGH_PATHS, STR_SEE_THROUGH_PATHS), ToggleOption(DDIDX_INVISIBLE_SUPPORTS, STR_INVISIBLE_SUPPORTS), ToggleOption(DDIDX_INVISIBLE_PEEPS, STR_INVISIBLE_PEOPLE), @@ -3617,6 +3620,7 @@ static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) ToggleOption(DDIDX_VIEW_CLIPPING, STR_VIEW_CLIPPING_MENU), ToggleOption(DDIDX_HIGHLIGHT_PATH_ISSUES, STR_HIGHLIGHT_PATH_ISSUES_MENU), }; + static_assert(ItemIDsMatchIndices(items)); SetItems(items); @@ -3628,33 +3632,41 @@ static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) // Set checkmarks rct_viewport* mainViewport = window_get_main()->viewport; if (mainViewport->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) - Dropdown::SetChecked(0, true); + Dropdown::SetChecked(DDIDX_UNDERGROUND_INSIDE, true); + if (gConfigGeneral.transparent_water) + Dropdown::SetChecked(DDIDX_TRANSPARENT_WATER, true); if (mainViewport->flags & VIEWPORT_FLAG_HIDE_BASE) - Dropdown::SetChecked(1, true); + Dropdown::SetChecked(DDIDX_HIDE_BASE, true); if (mainViewport->flags & VIEWPORT_FLAG_HIDE_VERTICAL) - Dropdown::SetChecked(2, true); + Dropdown::SetChecked(DDIDX_HIDE_VERTICAL, true); if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_RIDES) - Dropdown::SetChecked(4, true); + Dropdown::SetChecked(DDIDX_SEETHROUGH_RIDES, true); if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) - Dropdown::SetChecked(5, true); + Dropdown::SetChecked(DDIDX_SEETHROUGH_SCENERY, true); if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_PATHS) - Dropdown::SetChecked(6, true); + Dropdown::SetChecked(DDIDX_SEETHROUGH_PATHS, true); if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) - Dropdown::SetChecked(7, true); + Dropdown::SetChecked(DDIDX_INVISIBLE_SUPPORTS, true); if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_PEEPS) - Dropdown::SetChecked(8, true); + Dropdown::SetChecked(DDIDX_INVISIBLE_PEEPS, true); if (mainViewport->flags & VIEWPORT_FLAG_LAND_HEIGHTS) - Dropdown::SetChecked(10, true); + Dropdown::SetChecked(DDIDX_LAND_HEIGHTS, true); if (mainViewport->flags & VIEWPORT_FLAG_TRACK_HEIGHTS) - Dropdown::SetChecked(11, true); + Dropdown::SetChecked(DDIDX_TRACK_HEIGHTS, true); if (mainViewport->flags & VIEWPORT_FLAG_PATH_HEIGHTS) - Dropdown::SetChecked(12, true); + Dropdown::SetChecked(DDIDX_PATH_HEIGHTS, true); if (mainViewport->flags & VIEWPORT_FLAG_CLIP_VIEW) Dropdown::SetChecked(DDIDX_VIEW_CLIPPING, true); if (mainViewport->flags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES) Dropdown::SetChecked(DDIDX_HIGHLIGHT_PATH_ISSUES, true); gDropdownDefaultIndex = DDIDX_UNDERGROUND_INSIDE; + + // Opaque water relies on RCT1 sprites. + if (!is_csg_loaded()) + { + Dropdown::SetDisabled(DDIDX_TRANSPARENT_WATER, true); + } } /** @@ -3671,6 +3683,10 @@ static void top_toolbar_view_menu_dropdown(int16_t dropdownIndex) case DDIDX_UNDERGROUND_INSIDE: w->viewport->flags ^= VIEWPORT_FLAG_UNDERGROUND_INSIDE; break; + case DDIDX_TRANSPARENT_WATER: + gConfigGeneral.transparent_water ^= 1; + config_save_default(); + break; case DDIDX_HIDE_BASE: w->viewport->flags ^= VIEWPORT_FLAG_HIDE_BASE; break; @@ -3680,7 +3696,7 @@ static void top_toolbar_view_menu_dropdown(int16_t dropdownIndex) case DDIDX_SEETHROUGH_RIDES: w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_RIDES; break; - case DDIDX_SEETHROUGH_SCENARY: + case DDIDX_SEETHROUGH_SCENERY: w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_SCENERY; break; case DDIDX_SEETHROUGH_PATHS: diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 0228593a29..20e75e587f 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -1195,7 +1195,6 @@ namespace OpenRCT2 } } } - delete scanner; } #ifndef DISABLE_HTTP diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index a70e6b2e86..ed0394ee26 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -680,7 +680,7 @@ static void limit_autosave_count(const size_t numberOfFilesToKeep, bool processL // At first, count how many autosaves there are { - auto scanner = std::unique_ptr(Path::ScanDirectory(filter, false)); + auto scanner = Path::ScanDirectory(filter, false); while (scanner->Next()) { autosavesCount++; @@ -695,7 +695,7 @@ static void limit_autosave_count(const size_t numberOfFilesToKeep, bool processL auto autosaveFiles = std::vector(autosavesCount); { - auto scanner = std::unique_ptr(Path::ScanDirectory(filter, false)); + auto scanner = Path::ScanDirectory(filter, false); for (size_t i = 0; i < autosavesCount; i++) { autosaveFiles[i].resize(MAX_PATH, 0); diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index caa390779f..583fe18589 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -227,6 +227,7 @@ namespace Config model->show_real_names_of_guests = reader->GetBoolean("show_real_names_of_guests", true); model->allow_early_completion = reader->GetBoolean("allow_early_completion", false); model->transparent_screenshot = reader->GetBoolean("transparent_screenshot", true); + model->transparent_water = reader->GetBoolean("transparent_water", true); model->last_version_check_time = reader->GetInt64("last_version_check_time", 0); } } @@ -304,6 +305,7 @@ namespace Config writer->WriteBoolean("allow_early_completion", model->allow_early_completion); writer->WriteEnum("virtual_floor_style", model->virtual_floor_style, Enum_VirtualFloorStyle); writer->WriteBoolean("transparent_screenshot", model->transparent_screenshot); + writer->WriteBoolean("transparent_water", model->transparent_water); writer->WriteInt64("last_version_check_time", model->last_version_check_time); } diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index badf2b1fdf..083b2f029e 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -58,6 +58,7 @@ struct GeneralConfiguration bool disable_lightning_effect; bool show_guest_purchases; bool transparent_screenshot; + bool transparent_water; // Localisation int32_t language; diff --git a/src/openrct2/core/File.cpp b/src/openrct2/core/File.cpp index df722e1196..4e7eba3fea 100644 --- a/src/openrct2/core/File.cpp +++ b/src/openrct2/core/File.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -57,8 +57,7 @@ namespace File } std::vector result; - fs.seekg(0, std::ios::end); - auto fsize = static_cast(fs.tellg()); + auto fsize = Platform::GetFileSize(path); if (fsize > SIZE_MAX) { std::string message = String::StdFormat( @@ -68,7 +67,6 @@ namespace File else { result.resize(fsize); - fs.seekg(0); fs.read(reinterpret_cast(result.data()), result.size()); fs.exceptions(fs.failbit); } @@ -123,6 +121,11 @@ namespace File { return Platform::GetLastModified(path); } + + uint64_t GetSize(std::string_view path) + { + return Platform::GetFileSize(path); + } } // namespace File bool writeentirefile(const utf8* path, const void* buffer, size_t length) diff --git a/src/openrct2/core/File.h b/src/openrct2/core/File.h index 9dc216042e..cdd6179fa7 100644 --- a/src/openrct2/core/File.h +++ b/src/openrct2/core/File.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -26,4 +26,5 @@ namespace File std::vector ReadAllLines(std::string_view path); void WriteAllBytes(const std::string& path, const void* buffer, size_t length); uint64_t GetLastModified(const std::string& path); + uint64_t GetSize(std::string_view path); } // namespace File diff --git a/src/openrct2/core/FileIndex.hpp b/src/openrct2/core/FileIndex.hpp index 033a286b14..0e5d570a47 100644 --- a/src/openrct2/core/FileIndex.hpp +++ b/src/openrct2/core/FileIndex.hpp @@ -161,7 +161,6 @@ private: files.push_back(std::move(path)); } - delete scanner; } return ScanResult(stats, files); } diff --git a/src/openrct2/core/FileScanner.cpp b/src/openrct2/core/FileScanner.cpp index 56a435c986..9c79c500f7 100644 --- a/src/openrct2/core/FileScanner.cpp +++ b/src/openrct2/core/FileScanner.cpp @@ -342,18 +342,18 @@ private: #endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -IFileScanner* Path::ScanDirectory(const std::string& pattern, bool recurse) +std::unique_ptr Path::ScanDirectory(const std::string& pattern, bool recurse) { #ifdef _WIN32 - return new FileScannerWindows(pattern, recurse); + return std::make_unique(pattern, recurse); #elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - return new FileScannerUnix(pattern, recurse); + return std::make_unique(pattern, recurse); #endif } void Path::QueryDirectory(QueryDirectoryResult* result, const std::string& pattern) { - IFileScanner* scanner = Path::ScanDirectory(pattern, true); + auto scanner = Path::ScanDirectory(pattern, true); while (scanner->Next()) { const FileInfo* fileInfo = scanner->GetFileInfo(); @@ -366,12 +366,11 @@ void Path::QueryDirectory(QueryDirectoryResult* result, const std::string& patte result->FileDateModifiedChecksum = ror32(result->FileDateModifiedChecksum, 5); result->PathChecksum += GetPathChecksum(path); } - delete scanner; } std::vector Path::GetDirectories(const std::string& path) { - auto scanner = std::unique_ptr(ScanDirectory(path, false)); + auto scanner = ScanDirectory(path, false); auto baseScanner = static_cast(scanner.get()); std::vector children; diff --git a/src/openrct2/core/FileScanner.h b/src/openrct2/core/FileScanner.h index f3136e48f4..1e6c63d230 100644 --- a/src/openrct2/core/FileScanner.h +++ b/src/openrct2/core/FileScanner.h @@ -11,6 +11,7 @@ #include "../common.h" +#include #include #include @@ -50,7 +51,7 @@ namespace Path * @param recurse Whether to scan sub directories or not. * @returns A new FileScanner, this must be deleted when no longer needed. */ - IFileScanner* ScanDirectory(const std::string& pattern, bool recurse); + std::unique_ptr ScanDirectory(const std::string& pattern, bool recurse); /** * Scans a directory and all sub directories diff --git a/src/openrct2/core/FileStream.cpp b/src/openrct2/core/FileStream.cpp index dd5473d0cd..b95b220fe5 100644 --- a/src/openrct2/core/FileStream.cpp +++ b/src/openrct2/core/FileStream.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -17,6 +17,8 @@ #ifndef _WIN32 # include +#else +# include #endif #if defined(__linux__) && !defined(__ANDROID__) @@ -104,9 +106,12 @@ namespace OpenRCT2 throw IOException(String::StdFormat("Unable to open '%s'", path)); } - Seek(0, STREAM_SEEK_END); - _fileSize = GetPosition(); - Seek(0, STREAM_SEEK_BEGIN); +#ifdef _WIN32 + _fileSize = _filelengthi64(_fileno(_file)); +#else + std::error_code ec; + _fileSize = fs::file_size(fs::u8path(path), ec); +#endif _ownsFilePtr = true; } @@ -166,13 +171,9 @@ namespace OpenRCT2 void FileStream::Read(void* buffer, uint64_t length) { - uint64_t remainingBytes = GetLength() - GetPosition(); - if (length <= remainingBytes) + if (fread(buffer, 1, static_cast(length), _file) == length) { - if (fread(buffer, static_cast(length), 1, _file) == 1) - { - return; - } + return; } throw IOException("Attempted to read past end of file."); } diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index e81d444477..5a6b43e2cd 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3938,15 +3938,17 @@ enum STR_TILE_INSPECTOR_INVISIBLE_SHORT = 6438, STR_SHORTCUT_TOGGLE_INVISIBILITY = 6439, - STR_AT_LEAST_ONE_FOOTPATH_NON_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6440, - STR_AT_LEAST_ONE_FOOTPATH_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6441, - STR_AT_LEAST_ONE_FOOTPATH_RAILING_OBJECT_MUST_BE_SELECTED = 6442, - STR_OBJECT_SELECTION_FOOTPATH_SURFACES = 6443, - STR_OBJECT_SELECTION_FOOTPATH_RAILINGS = 6444, - STR_TILE_INSPECTOR_FOOTPATH_SURFACE_NAME = 6445, - STR_TILE_INSPECTOR_FOOTPATH_RAILINGS_NAME = 6446, + STR_VIEWPORT_TRANSPARENT_WATER = 6440, - STR_UNSUPPORTED_OBJECT_FORMAT = 6447, + STR_AT_LEAST_ONE_FOOTPATH_NON_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6441, + STR_AT_LEAST_ONE_FOOTPATH_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6442, + STR_AT_LEAST_ONE_FOOTPATH_RAILING_OBJECT_MUST_BE_SELECTED = 6443, + STR_OBJECT_SELECTION_FOOTPATH_SURFACES = 6444, + STR_OBJECT_SELECTION_FOOTPATH_RAILINGS = 6445, + STR_TILE_INSPECTOR_FOOTPATH_SURFACE_NAME = 6446, + STR_TILE_INSPECTOR_FOOTPATH_RAILINGS_NAME = 6447, + + STR_UNSUPPORTED_OBJECT_FORMAT = 6448, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index 0788b21ca5..38b3086142 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -75,7 +75,7 @@ bool finance_check_money_required(uint32_t flags) */ bool finance_check_affordability(money32 cost, uint32_t flags) { - return cost <= 0 || !finance_check_money_required(flags) || cost <= gCash; + return !finance_check_money_required(flags) || cost <= 0 || cost <= gCash; } /** diff --git a/src/openrct2/object/ImageTable.cpp b/src/openrct2/object/ImageTable.cpp index 736b5e3968..d5bbf897c8 100644 --- a/src/openrct2/object/ImageTable.cpp +++ b/src/openrct2/object/ImageTable.cpp @@ -274,7 +274,7 @@ std::string ImageTable::FindLegacyObject(const std::string& name) { // Search recursively for any file with the target name (case insensitive) auto filter = Path::Combine(objectsPath, "*.dat"); - auto scanner = std::unique_ptr(Path::ScanDirectory(filter, true)); + auto scanner = Path::ScanDirectory(filter, true); while (scanner->Next()) { auto currentName = Path::GetFileName(scanner->GetPathRelative()); @@ -315,7 +315,7 @@ void ImageTable::Read(IReadObjectContext* context, OpenRCT2::IStream* stream) uint64_t remainingBytes = stream->GetLength() - stream->GetPosition() - headerTableSize; if (remainingBytes > imageDataSize) { - context->LogWarning(ObjectError::BadImageTable, "Image table size longer than expected."); + context->LogVerbose(ObjectError::BadImageTable, "Image table size longer than expected."); imageDataSize = static_cast(remainingBytes); } diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 1752b84c07..94e851647b 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -372,18 +372,11 @@ bool ObjectAsset::IsAvailable() const } } -size_t ObjectAsset::GetSize() const +uint64_t ObjectAsset::GetSize() const { if (_zipPath.empty()) { - try - { - return File::ReadAllBytes(_path).size(); - } - catch (...) - { - return 0; - } + return File::GetSize(_path); } else { diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index ee2568d593..f63f969a74 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -226,7 +226,7 @@ public: } bool IsAvailable() const; - size_t GetSize() const; + uint64_t GetSize() const; std::unique_ptr GetStream() const; }; @@ -240,6 +240,7 @@ struct IReadObjectContext virtual std::vector GetData(std::string_view path) abstract; virtual ObjectAsset GetAsset(std::string_view path) abstract; + virtual void LogVerbose(ObjectError code, const utf8* text) abstract; virtual void LogWarning(ObjectError code, const utf8* text) abstract; virtual void LogError(ObjectError code, const utf8* text) abstract; }; diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index 064bc0d6e6..bb011d0884 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -107,10 +107,15 @@ private: std::string _identifier; bool _loadImages; std::string _basePath; + bool _wasVerbose = false; bool _wasWarning = false; bool _wasError = false; public: + bool WasVerbose() const + { + return _wasVerbose; + } bool WasWarning() const { return _wasWarning; @@ -163,6 +168,16 @@ public: return {}; } + void LogVerbose(ObjectError code, const utf8* text) override + { + _wasVerbose = true; + + if (!String::IsNullOrEmpty(text)) + { + log_verbose("[%s] Info (%d): %s", _identifier.c_str(), code, text); + } + } + void LogWarning(ObjectError code, const utf8* text) override { _wasWarning = true; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 22a4202c9c..7e3984b229 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1315,7 +1315,9 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c | EnumValue(FilterPaletteID::PaletteWater) << 19; PaintAddImageAsParent(session, image_id, 0, 0, 32, 32, -1, waterHeight); - PaintAttachToPreviousPS(session, SPR_WATER_OVERLAY + image_offset, 0, 0); + const bool transparent = gConfigGeneral.transparent_water || (session->ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE); + const uint32_t overlayStart = transparent ? SPR_WATER_OVERLAY : SPR_RCT1_WATER_OVERLAY; + PaintAttachToPreviousPS(session, overlayStart + image_offset, 0, 0); if (!(session->ViewFlags & VIEWPORT_FLAG_HIDE_VERTICAL)) { diff --git a/src/openrct2/paint/tile_element/Paint.Surface.h b/src/openrct2/paint/tile_element/Paint.Surface.h index 6b774390f8..15a7a6793e 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.h +++ b/src/openrct2/paint/tile_element/Paint.Surface.h @@ -100,6 +100,9 @@ enum SPR_TERRAIN_PATTERN_MARTIAN = 28995, SPR_TERRAIN_PATTERN_GRASS_CLUMPS = 29001, SPR_TERRAIN_PATTERN_ICE = 29007, + + SPR_RCT1_WATER_MASK = SPR_CSG_BEGIN + 46787, + SPR_RCT1_WATER_OVERLAY = SPR_CSG_BEGIN + 46792, }; #endif //_PAINT_SURFACE_H diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index 8889749720..dc1184564d 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -177,6 +177,19 @@ namespace Platform return lastModified; } + uint64_t GetFileSize(std::string_view path) + { + uint64_t size = 0; + struct stat statInfo + { + }; + if (stat(std::string(path).c_str(), &statInfo) == 0) + { + size = statInfo.st_size; + } + return size; + } + bool ShouldIgnoreCase() { return false; diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index d7d22fbbea..4a7f203e96 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -554,6 +554,21 @@ namespace Platform return lastModified; } + uint64_t GetFileSize(std::string_view path) + { + uint64_t size = 0; + auto pathW = String::ToWideChar(path); + WIN32_FILE_ATTRIBUTE_DATA attributes; + if (GetFileAttributesExW(pathW.c_str(), GetFileExInfoStandard, &attributes) != FALSE) + { + ULARGE_INTEGER fileSize; + fileSize.LowPart = attributes.nFileSizeLow; + fileSize.HighPart = attributes.nFileSizeHigh; + size = fileSize.QuadPart; + } + return size; + } + bool ShouldIgnoreCase() { return true; diff --git a/src/openrct2/platform/Platform2.h b/src/openrct2/platform/Platform2.h index 6189f21b96..98d886d282 100644 --- a/src/openrct2/platform/Platform2.h +++ b/src/openrct2/platform/Platform2.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -39,6 +39,7 @@ namespace Platform bool IsPathSeparator(char c); utf8* GetAbsolutePath(utf8* buffer, size_t bufferSize, const utf8* relativePath); uint64_t GetLastModified(const std::string& path); + uint64_t GetFileSize(std::string_view path); std::string ResolveCasing(const std::string& path, bool fileExists); rct2_time GetTimeLocal(); rct2_date GetDateLocal(); diff --git a/src/openrct2/rct12/SawyerChunk.cpp b/src/openrct2/rct12/SawyerChunk.cpp index b5db22a579..6873c94924 100644 --- a/src/openrct2/rct12/SawyerChunk.cpp +++ b/src/openrct2/rct12/SawyerChunk.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -10,6 +10,7 @@ #include "SawyerChunk.h" #include "../core/Memory.hpp" +#include "SawyerChunkReader.h" SawyerChunk::SawyerChunk(SAWYER_ENCODING encoding, void* data, size_t length) { @@ -20,5 +21,5 @@ SawyerChunk::SawyerChunk(SAWYER_ENCODING encoding, void* data, size_t length) SawyerChunk::~SawyerChunk() { - Memory::Free(_data); + SawyerChunkReader::FreeChunk(_data); } diff --git a/src/openrct2/rct12/SawyerChunkReader.cpp b/src/openrct2/rct12/SawyerChunkReader.cpp index f1bf44933f..cf03dfdc5b 100644 --- a/src/openrct2/rct12/SawyerChunkReader.cpp +++ b/src/openrct2/rct12/SawyerChunkReader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -27,8 +27,9 @@ constexpr const char* EXCEPTION_MSG_DESTINATION_TOO_SMALL = "Chunk data larger t constexpr const char* EXCEPTION_MSG_INVALID_CHUNK_ENCODING = "Invalid chunk encoding."; constexpr const char* EXCEPTION_MSG_ZERO_SIZED_CHUNK = "Encountered zero-sized chunk."; -SawyerChunkReader::SawyerChunkReader(OpenRCT2::IStream* stream) +SawyerChunkReader::SawyerChunkReader(OpenRCT2::IStream* stream, bool persistentChunks) : _stream(stream) + , _createsPersistentChunks(persistentChunks) { } @@ -78,7 +79,10 @@ std::shared_ptr SawyerChunkReader::ReadChunk() { throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK); } - buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + if (_createsPersistentChunks) + { + buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + } return std::make_shared( static_cast(header.encoding), buffer, uncompressedLength); } @@ -126,7 +130,10 @@ std::shared_ptr SawyerChunkReader::ReadChunkTrack() { throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK); } - buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + if (_createsPersistentChunks) + { + buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + } return std::make_shared(SAWYER_ENCODING::RLE, buffer, uncompressedLength); } catch (const std::exception&) @@ -158,6 +165,11 @@ void SawyerChunkReader::ReadChunk(void* dst, size_t length) } } +void SawyerChunkReader::FreeChunk(void* data) +{ + FreeLargeTempBuffer(data); +} + size_t SawyerChunkReader::DecodeChunk(void* dst, size_t dstCapacity, const void* src, const sawyercoding_chunk_header& header) { size_t resultLength; @@ -315,9 +327,7 @@ void* SawyerChunkReader::AllocateLargeTempBuffer() void* SawyerChunkReader::FinaliseLargeTempBuffer(void* buffer, size_t len) { #ifdef __USE_HEAP_ALLOC__ - auto finalBuffer = std::malloc(len); - std::memcpy(finalBuffer, buffer, len); - HeapFree(GetProcessHeap(), 0, buffer); + auto finalBuffer = HeapReAlloc(GetProcessHeap(), 0, buffer, len); #else auto finalBuffer = static_cast(std::realloc(buffer, len)); #endif diff --git a/src/openrct2/rct12/SawyerChunkReader.h b/src/openrct2/rct12/SawyerChunkReader.h index 8fb370b25e..0873c8b845 100644 --- a/src/openrct2/rct12/SawyerChunkReader.h +++ b/src/openrct2/rct12/SawyerChunkReader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -36,15 +36,17 @@ namespace OpenRCT2 /** * Reads sawyer encoding chunks from a data stream. This can be used to read - * SC6, SV6 and RCT2 objects. + * SC6, SV6 and RCT2 objects. persistentChunks is a hint to the reader that the chunk will be preserved, + * and thus the chunk memory should be shrunk. */ class SawyerChunkReader final { private: OpenRCT2::IStream* const _stream = nullptr; + const bool _createsPersistentChunks = false; public: - explicit SawyerChunkReader(OpenRCT2::IStream* stream); + explicit SawyerChunkReader(OpenRCT2::IStream* stream, bool persistentChunks = false); /** * Skips the next chunk in the stream without decoding or reading its data @@ -84,6 +86,11 @@ public: return result; } + /** + * Frees the chunk data, to be used when destructing SawyerChunks + */ + static void FreeChunk(void* data); + private: static size_t DecodeChunk(void* dst, size_t dstCapacity, const void* src, const sawyercoding_chunk_header& header); static size_t DecodeChunkRLERepeat(void* dst, size_t dstCapacity, const void* src, size_t srcLength); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 4e8ef0f408..00e1e102ee 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -6671,6 +6671,8 @@ void sub_6CB945(Ride* ride) { if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) continue; + if (tileElement->base_height != locationCoords.z) + continue; if (tileElement->AsEntrance()->GetRideIndex() != ride->id) continue; if (tileElement->AsEntrance()->GetEntranceType() > ENTRANCE_TYPE_RIDE_EXIT) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 93910e8a3f..e61e0a65cf 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1636,7 +1636,7 @@ static bool track_design_place_ride(TrackDesign* td6, const CoordsXYZ& origin, R } else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY) { - flags = 0; + flags = GAME_COMMAND_FLAG_NO_SPEND; } if (_trackDesignPlaceIsReplay) { diff --git a/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp b/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp index 69e8180c98..f7c74c023d 100644 --- a/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/WoodenRollerCoaster.cpp @@ -7,10 +7,12 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "../../config/Config.h" #include "../../drawing/Drawing.h" #include "../../interface/Viewport.h" #include "../../paint/Paint.h" #include "../../paint/Supports.h" +#include "../../paint/tile_element/Paint.Surface.h" #include "../../paint/tile_element/Paint.TileElement.h" #include "../../sprites.h" #include "../../world/Map.h" @@ -6082,6 +6084,9 @@ static void wooden_rc_track_water_splash( paint_session* session, ride_id_t rideIndex, uint8_t trackSequence, uint8_t direction, int32_t height, const TileElement* tileElement) { + const bool transparent = gConfigGeneral.transparent_water || (session->ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE); + const uint32_t waterOverlay = transparent ? SPR_WATER_OVERLAY : SPR_RCT1_WATER_OVERLAY; + switch (trackSequence) { case 0: @@ -6093,9 +6098,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24855, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23997, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6113,9 +6118,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24856, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23998, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6133,9 +6138,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24853, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23995, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6153,9 +6158,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24854, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23996, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6182,9 +6187,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24843, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23985, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6202,9 +6207,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24844, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23986, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6222,9 +6227,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24841, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23983, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6242,9 +6247,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24842, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23984, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6271,9 +6276,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24865, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 24003, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6292,9 +6297,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24866, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 24004, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6320,9 +6325,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24841, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23983, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6340,9 +6345,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24842, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23984, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6360,9 +6365,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24843, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23985, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6380,9 +6385,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24844, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23986, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6408,9 +6413,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24853, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23995, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6428,9 +6433,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24854, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23996, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6448,9 +6453,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24855, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23997, 0, 0, 32, 25, 2, height, 0, 3, height); @@ -6468,9 +6473,9 @@ static void wooden_rc_track_water_splash( PaintAddImageAsChildRotated( session, direction, wooden_rc_get_rails_colour(session) | 24856, 0, 0, 32, 25, 2, height, 0, 3, height); PaintAddImageAsChildRotated( - session, direction, 0x61000000 | 5048, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x61000000 | SPR_WATER_MASK, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( - session, direction, 0x00000000 | 5053, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); + session, direction, 0x00000000 | waterOverlay, 0, 0, 32, 25, 2, height + 16, 0, 3, height + 16); PaintAddImageAsChildRotated( session, direction, session->TrackColours[SCHEME_SUPPORTS] | 23998, 0, 0, 32, 25, 2, height, 0, 3, height); diff --git a/src/openrct2/ride/thrill/SwingingShip.cpp b/src/openrct2/ride/thrill/SwingingShip.cpp index 35c4216739..9726fca15e 100644 --- a/src/openrct2/ride/thrill/SwingingShip.cpp +++ b/src/openrct2/ride/thrill/SwingingShip.cpp @@ -63,6 +63,11 @@ static void paint_swinging_ship_structure( const TileElement* savedTileElement = static_cast(session->CurrentlyDrawnItem); rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); + if (rideEntry == nullptr) + { + return; + } + Vehicle* vehicle = nullptr; int8_t xOffset = !(direction & 1) ? axisOffset : 0; diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index d1a1ff3217..db2f1a1801 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -443,7 +443,7 @@ void ScriptEngine::LoadPlugins() if (Path::DirectoryExists(base)) { auto pattern = Path::Combine(base, "*.js"); - auto scanner = std::unique_ptr(Path::ScanDirectory(pattern, true)); + auto scanner = Path::ScanDirectory(pattern, true); while (scanner->Next()) { auto path = std::string(scanner->GetPath()); diff --git a/src/openrct2/title/TitleSequence.cpp b/src/openrct2/title/TitleSequence.cpp index 87d513ae4f..c5e47ca72a 100644 --- a/src/openrct2/title/TitleSequence.cpp +++ b/src/openrct2/title/TitleSequence.cpp @@ -292,7 +292,7 @@ static std::vector GetSaves(const std::string& directory) std::vector saves; auto pattern = Path::Combine(directory, "*.sc6;*.sv6"); - IFileScanner* scanner = Path::ScanDirectory(pattern, true); + auto scanner = Path::ScanDirectory(pattern, true); while (scanner->Next()) { const utf8* path = scanner->GetPathRelative(); diff --git a/src/openrct2/title/TitleSequenceManager.cpp b/src/openrct2/title/TitleSequenceManager.cpp index 02c8c381f0..553c061596 100644 --- a/src/openrct2/title/TitleSequenceManager.cpp +++ b/src/openrct2/title/TitleSequenceManager.cpp @@ -209,12 +209,11 @@ namespace TitleSequenceManager static void Scan(const std::string& directory) { auto pattern = Path::Combine(directory, "script.txt;*.parkseq"); - IFileScanner* fileScanner = Path::ScanDirectory(pattern, true); + auto fileScanner = Path::ScanDirectory(pattern, true); while (fileScanner->Next()) { AddSequence(fileScanner->GetPath()); } - delete fileScanner; } static void AddSequence(const std::string& scanPath) diff --git a/test/tests/ReplayTests.cpp b/test/tests/ReplayTests.cpp index d7c96aa675..c245d81dd6 100644 --- a/test/tests/ReplayTests.cpp +++ b/test/tests/ReplayTests.cpp @@ -53,7 +53,7 @@ static std::vector GetReplayFiles() std::string replayPathPattern = Path::Combine(replayPath, "*.parkrep"); std::vector files; - std::unique_ptr scanner = std::unique_ptr(Path::ScanDirectory(replayPathPattern, true)); + auto scanner = Path::ScanDirectory(replayPathPattern, true); while (scanner->Next()) { ReplayTestData test;