Merge remote-tracking branch 'upstream/develop' into new-save-format

Some conflicts intentionally unresolved
This commit is contained in:
Gymnasiast 2021-09-17 10:15:09 +02:00
commit c390e9f521
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
199 changed files with 3481 additions and 2610 deletions

View File

@ -50,9 +50,9 @@ set(OBJECTS_VERSION "1.2.1")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip")
set(OBJECTS_SHA1 "540e004abc683b3fe22211f5234e3d78ab023c5f")
set(REPLAYS_VERSION "0.0.49")
set(REPLAYS_VERSION "0.0.52")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip")
set(REPLAYS_SHA1 "004AE4D38D1326913AF5DE7A90E8AF31DD31BF94")
set(REPLAYS_SHA1 "3A1A6B5B25ACA3B8AADC618A9D2BE44F8A23A7BB")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")

View File

@ -802,6 +802,7 @@
258C212125F84FA2B4C3BCAE /* RideUseSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58DEACC694664E7C8DACB93D /* RideUseSystem.cpp */; };
E6C71B6165224F65AA87E65B /* RideUseSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DA720D496604387806AC168 /* RideUseSystem.h */; };
C8D612EB56BD4214BEC0F7FF /* GroupVector.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F4D523B8782E4C458AF1490D /* GroupVector.hpp */; };
B2F44E535BD14A03BE8B9D14 /* ZipStream.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F28A181D311D4E078FDB090C /* ZipStream.hpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -1688,7 +1689,6 @@
F76C838B1EC4E7CC00FA49E2 /* Memory.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Memory.hpp; sourceTree = "<group>"; };
F76C838C1EC4E7CC00FA49E2 /* MemoryStream.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStream.cpp; sourceTree = "<group>"; };
F76C838D1EC4E7CC00FA49E2 /* MemoryStream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MemoryStream.h; sourceTree = "<group>"; };
F76C838E1EC4E7CC00FA49E2 /* Nullable.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Nullable.hpp; sourceTree = "<group>"; };
F76C838F1EC4E7CC00FA49E2 /* Path.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Path.cpp; sourceTree = "<group>"; };
F76C83901EC4E7CC00FA49E2 /* Path.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Path.hpp; sourceTree = "<group>"; };
F76C83921EC4E7CC00FA49E2 /* String.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = String.cpp; sourceTree = "<group>"; };
@ -1908,6 +1908,7 @@
58DEACC694664E7C8DACB93D /* RideUseSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RideUseSystem.cpp; path = src/openrct2/peep/RideUseSystem.cpp; sourceTree = SOURCE_ROOT; };
2DA720D496604387806AC168 /* RideUseSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RideUseSystem.h; path = src/openrct2/peep/RideUseSystem.h; sourceTree = SOURCE_ROOT; };
F4D523B8782E4C458AF1490D /* GroupVector.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = GroupVector.hpp; path = src/openrct2/core/GroupVector.hpp; sourceTree = SOURCE_ROOT; };
F28A181D311D4E078FDB090C /* ZipStream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ZipStream.hpp; path = src/openrct2/core/ZipStream.hpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -2581,6 +2582,7 @@
F76C839A1EC4E7CC00FA49E2 /* Zip.h */,
BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */,
F4D523B8782E4C458AF1490D /* GroupVector.hpp */,
F28A181D311D4E078FDB090C /* ZipStream.hpp */,
);
path = core;
sourceTree = "<group>";
@ -3662,6 +3664,7 @@
DEC539DE402F4B8993E4C357 /* ScTileElement.hpp in Headers */,
E6C71B6165224F65AA87E65B /* RideUseSystem.h in Headers */,
C8D612EB56BD4214BEC0F7FF /* GroupVector.hpp in Headers */,
B2F44E535BD14A03BE8B9D14 /* ZipStream.hpp in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -176,6 +176,7 @@ The following people are not part of the development team, but have been contrib
* Kane Shaw (seifer7)
* Saad Rehman (SaadRehmanCS)
* (ocalhoun6)
* Sean Payne (seanmajorpayne)
## Toolchain
* (Balletie) - macOS

View File

@ -3651,6 +3651,8 @@ STR_6453 :Copy version info
STR_6454 :Cant rename banner…
STR_6455 :Cant rename sign…
STR_6456 :Giant Screenshot
STR_6457 :Report a bug on GitHub
STR_6458 :Follow this on Main View
#############
# Scenarios #

View File

@ -3654,6 +3654,7 @@ STR_6453 :Kopii informojn de versio
STR_6454 :Ne povas renomi rubandon…
STR_6455 :Ne povas renomi surskribaĵon…
STR_6456 :Giganta Ekrankopio
STR_6457 :Raporti cimon sur GitHub
#############
# Scenarios #

View File

@ -3660,6 +3660,8 @@ STR_6452 :{WINDOW_COLOUR_2}Myy: {BLACK}{STRING}
STR_6453 :Kopioi versiotiedot
STR_6454 :Banneria ei voi uudelleennimetä…
STR_6455 :Kylttiä ei voi uudelleennimetä…
STR_6456 :Jättiruudunkaappaus
STR_6457 :Ilmoita viasta GitHubissa
#############
# Scenarios #

View File

@ -3661,6 +3661,7 @@ STR_6453 :Copier les informations de version
STR_6454 :Impossible de renommer la bannière…
STR_6455 :Impossible de renommer le panneau…
STR_6456 :Capture décran géante
STR_6457 :Signaler un bug sur GitHub
#############
# Scenarios #

View File

@ -412,7 +412,7 @@ STR_1023 :1대당 차량 {POP16}{POP16}{POP16}{COMMA16}개
STR_1024 :1대당 차량 {COMMA16}개
STR_1025 :1대당 차량 {COMMA16}개
STR_1026 :탑승장이 너무 깁니다!
STR_1027 :여기로 이동합니다
STR_1027 :이동
STR_1028 :지도 끝을 벗어납니다!
STR_1029 :일부분만 수면 위로 나오도록 건설할 수 없습니다!
STR_1030 :수중에만 건설할 수 있습니다!
@ -3657,6 +3657,8 @@ STR_6453 :버전 정보 복사
STR_6454 :팻말 이름을 변경할 수 없습니다…
STR_6455 :팻말 이름을 변경할 수 없습니다…
STR_6456 :초대형 스크린 샷
STR_6457 :GitHub에 버그 제보
STR_6458 :따라가기
#############
# Scenarios #
@ -3963,8 +3965,8 @@ STR_DTLS :파라다이스 부두는 바다 위의 산책로를 확장했습
<Dragon's Cove>
STR_SCNR :Dragons Cove
STR_PARK :용의 동굴
STR_DTLS :이번 롤러코스터 건설 도전에서는 해안 동굴이 무대가 됩니다.
STR_PARK :용의
STR_DTLS :이번 롤러코스터 건설 도전에서는 바닷가 근처의 만이 무대가 됩니다.
<Good Knight Park>
STR_SCNR :Good Knight Park

View File

@ -809,7 +809,7 @@ STR_1423 :Wachtrijpad
STR_1424 :Voetpad
STR_1425 :Voetpad
STR_1426 :Wachtrij
STR_1427 :{WINDOW_COLOUR_2}Passagiers: {BLACK}{COMMA32} per uur
STR_1427 :{WINDOW_COLOUR_2}Bezoekers: {BLACK}{COMMA32} per uur
STR_1428 :{WINDOW_COLOUR_2}Toegangsprijs:
STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP}
STR_1430 :Gratis
@ -2969,9 +2969,9 @@ STR_5731 :Lineair
STR_5734 :Rendering
STR_5735 :Netwerkstatus
STR_5736 :Speler
STR_5737 :Gesloten, nog {COMMA16} passagier
STR_5738 :Gesloten, nog {COMMA16} passagiers
STR_5739 :{WINDOW_COLOUR_2}Huidig aantal passagiers: {BLACK}{COMMA16}
STR_5737 :Gesloten, nog {COMMA16} bezoeker
STR_5738 :Gesloten, nog {COMMA16} bezoekers
STR_5739 :{WINDOW_COLOUR_2}Huidig aantal bezoekers: {BLACK}{COMMA16}
STR_5740 :Oneindige marketingcampagnes
STR_5741 :Marketingcampagnes verlopen nooit
STR_5742 :Authenticeren…

View File

@ -3654,6 +3654,8 @@ STR_6453 :Copiar informações da versão
STR_6454 :Não é possível renomear o banner…
STR_6455 :Não é possível renomear a placa…
STR_6456 :Captura Gigante de Tela
STR_6457 :Relatar um problema pelo GitHub
STR_6458 :Seguir isto na Visão Principal
#############
# Scenarios #

View File

@ -1,14 +1,19 @@
0.3.4.1+ (in development)
------------------------------------------------------------------------
- Feature: [#3868] Initial support for using TTF in OpenGL mode (still contains bugs).
- Feature: [#7682] Follow ride/guest/staff in main window viewport.
- Feature: [#13407] Allow building chain lifts on enclosed dinghy slide pieces when cheats are on.
- Feature: [#15084] [Plugin] Add "vehicle.crash" hook.
- Feature: [#15143] Added a shortcut key for Giant Screenshot.
- Feature: [#15164] Highlight elements selected by the Tile Inspector, tracks are currently not supported.
- Feature: [#15165] [Plugin] Add the ability to create entities using "map.createEntity".
- Feature: [#15194] [Plugin] Add guest properties, ride downtime and park casualty penalty.
- Feature: [#15294] New vehicle animation type: flying animal
- Feature: [#15195] Added a bug-report item in file dropdown menu.
- Feature: [#15294] New vehicle animation type: flying animal.
- Fix: [#13465] Creating a scenario based on a won save game results in a scenario thats instantly won.
- Fix: [#13912] “Dome park” no longer renders dome correctly.
- Fix: [#14316] Closing the Track Designs Manager window causes broken state.
- Fix: [#14649] ImageImporter incorrectly remaps colours outside the RCT2 palette.
- Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).
- Fix: [#15096] Crash when placing entrances in the scenario editor near the map corner.
- Fix: [#15142] ToonTowner's mine roofs were moved into the pirate theme scenery group instead of the mine theme scenery group.
@ -18,6 +23,7 @@
- Fix: [#15193] Crash when rides/stalls are demolished.
- Fix: [#15199] Construction window is not closed when a ride gets demolished.
- Fix: [#15255] Tile Inspector shows banner information on walls that do not contain one.
- Fix: [#15257] Chat icon shows in scenario/track editor. Other icons don't disable when deactivated in options menu.
- Fix: [#15289] Unexpected behavior with duplicated banners which also caused desyncs in multiplayer.
- Improved: [#3417] Crash dumps are now placed in their own folder.
- Change: [#8601] Revert ToonTower base block fix to re-enable support blocking.

View File

@ -74,6 +74,7 @@
<RuntimeLibrary Condition="'$(UseSharedLibs)'!='true'">MultiThreadedDebug</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseSharedLibs)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
@ -90,6 +91,7 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>

View File

@ -48,8 +48,8 @@
<TitleSequencesSha1>304d13a126c15bf2c86ff13b81a2f2cc1856ac8d</TitleSequencesSha1>
<ObjectsUrl>https://github.com/OpenRCT2/objects/releases/download/v1.2.1/objects.zip</ObjectsUrl>
<ObjectsSha1>540e004abc683b3fe22211f5234e3d78ab023c5f</ObjectsSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.49/replays.zip</ReplaysUrl>
<ReplaysSha1>004AE4D38D1326913AF5DE7A90E8AF31DD31BF94</ReplaysSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.52/replays.zip</ReplaysUrl>
<ReplaysSha1>3A1A6B5B25ACA3B8AADC618A9D2BE44F8A23A7BB</ReplaysSha1>
</PropertyGroup>
<ItemGroup>

View File

@ -184,9 +184,9 @@ public:
case WD_BANNER:
return window_banner_open(id);
case WD_DEMOLISH_RIDE:
return window_ride_demolish_prompt_open(get_ride(id));
return window_ride_demolish_prompt_open(get_ride(static_cast<ride_id_t>(id)));
case WD_REFURBISH_RIDE:
return window_ride_refurbish_prompt_open(get_ride(id));
return window_ride_refurbish_prompt_open(get_ride(static_cast<ride_id_t>(id)));
case WD_NEW_CAMPAIGN:
return window_new_campaign_open(id);
case WD_SIGN:
@ -264,7 +264,8 @@ public:
}
case WC_RIDE:
{
auto ride = get_ride(intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
const auto rideId = static_cast<ride_id_t>(intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID));
auto ride = get_ride(rideId);
return ride == nullptr ? nullptr : window_ride_main_open(ride);
}
case WC_TRACK_DESIGN_PLACE:
@ -343,13 +344,13 @@ public:
if (w == nullptr || w->number != rideIndex)
{
window_close_construction_windows();
_currentRideIndex = rideIndex;
_currentRideIndex = static_cast<ride_id_t>(rideIndex);
w = OpenWindow(WC_RIDE_CONSTRUCTION);
}
else
{
ride_construction_invalidate_current_track();
_currentRideIndex = rideIndex;
_currentRideIndex = static_cast<ride_id_t>(rideIndex);
}
break;
}
@ -395,7 +396,7 @@ public:
case INTENT_ACTION_INVALIDATE_VEHICLE_WINDOW:
{
auto vehicle = static_cast<Vehicle*>(intent.GetPointerExtra(INTENT_EXTRA_VEHICLE));
auto w = window_find_by_number(WC_RIDE, vehicle->ride);
auto w = window_find_by_number(WC_RIDE, EnumValue(vehicle->ride));
if (w == nullptr)
return;

View File

@ -221,10 +221,10 @@ void TextureCache::GeneratePaletteTexture()
GLint y = PaletteToY(static_cast<FilterPaletteID>(i));
auto g1Index = GetPaletteG1Index(i);
if (g1Index)
if (g1Index.has_value())
{
auto element = gfx_get_g1_element(*g1Index);
gfx_draw_sprite_software(&dpi, ImageId(*g1Index), { -element->x_offset, y - element->y_offset });
auto element = gfx_get_g1_element(g1Index.value());
gfx_draw_sprite_software(&dpi, ImageId(g1Index.value()), { -element->x_offset, y - element->y_offset });
}
}

View File

@ -152,11 +152,11 @@ ShortcutInput::ShortcutInput(std::string_view value)
else
{
auto number = String::Parse<int32_t>(rem);
if (number)
if (number.has_value())
{
Kind = InputDeviceKind::JoyButton;
Modifiers = modifiers;
Button = *number - 1;
Button = number.value() - 1;
}
}
}

View File

@ -167,10 +167,10 @@ void ShortcutManager::ProcessEvent(const InputEvent& e)
if (shortcut != nullptr && shortcut->IsSuitableInputEvent(e))
{
auto shortcutInput = ShortcutInput::FromInputEvent(e);
if (shortcutInput)
if (shortcutInput.has_value())
{
shortcut->Current.clear();
shortcut->Current.push_back(std::move(*shortcutInput));
shortcut->Current.push_back(std::move(shortcutInput.value()));
}
_pendingShortcutChange.clear();
window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
@ -234,23 +234,21 @@ std::optional<ShortcutInput> ShortcutManager::ConvertLegacyBinding(uint16_t bind
if (binding == nullBinding)
{
return {};
}
else
{
ShortcutInput result;
result.Kind = InputDeviceKind::Keyboard;
if (binding & shift)
result.Modifiers |= KMOD_SHIFT;
if (binding & ctrl)
result.Modifiers |= KMOD_CTRL;
if (binding & alt)
result.Modifiers |= KMOD_ALT;
if (binding & cmd)
result.Modifiers |= KMOD_GUI;
result.Button = SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(binding & 0xFF));
return result;
return std::nullopt;
}
ShortcutInput result;
result.Kind = InputDeviceKind::Keyboard;
if (binding & shift)
result.Modifiers |= KMOD_SHIFT;
if (binding & ctrl)
result.Modifiers |= KMOD_CTRL;
if (binding & alt)
result.Modifiers |= KMOD_ALT;
if (binding & cmd)
result.Modifiers |= KMOD_GUI;
result.Button = SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(binding & 0xFF));
return result;
}
void ShortcutManager::LoadLegacyBindings(const fs::path& path)
@ -273,9 +271,9 @@ void ShortcutManager::LoadLegacyBindings(const fs::path& path)
{
shortcut->Current.clear();
auto input = ConvertLegacyBinding(value);
if (input)
if (input.has_value())
{
shortcut->Current.push_back(std::move(*input));
shortcut->Current.push_back(std::move(input.value()));
}
}
}

View File

@ -375,7 +375,7 @@ InteractionInfo ViewportInteractionGetItemRight(const ScreenCoordsXY& screenCoor
stationIndex = tileElement->AsTrack()->GetStationIndex();
for (i = stationIndex; i >= 0; i--)
if (ride->stations[i].Start.isNull())
if (ride->stations[i].Start.IsNull())
stationIndex--;
stationIndex++;
ft.Add<uint16_t>(stationIndex);
@ -761,7 +761,7 @@ CoordsXY ViewportInteractionGetTileStartAtCursor(const ScreenCoordsXY& screenCoo
if (window == nullptr || window->viewport == nullptr)
{
CoordsXY ret{};
ret.setNull();
ret.SetNull();
return ret;
}
auto viewport = window->viewport;
@ -771,7 +771,7 @@ CoordsXY ViewportInteractionGetTileStartAtCursor(const ScreenCoordsXY& screenCoo
if (info.SpriteType == ViewportInteractionItem::None)
{
initialPos.setNull();
initialPos.SetNull();
return initialPos;
}

View File

@ -139,7 +139,6 @@ namespace OpenRCT2::Scripting
private:
static std::optional<CoordsXY> GetCoordsXY(const DukValue& dukCoords)
{
std::optional<CoordsXY> result;
if (dukCoords.type() == DukValue::Type::OBJECT)
{
auto dukX = dukCoords["x"];
@ -148,16 +147,15 @@ namespace OpenRCT2::Scripting
auto dukY = dukCoords["y"];
if (dukY.type() == DukValue::Type::NUMBER)
{
result = { dukX.as_int(), dukY.as_int() };
return CoordsXY(dukX.as_int(), dukY.as_int());
}
}
}
return result;
return std::nullopt;
}
static std::optional<MapRange> GetMapRange(const DukValue& dukMapRange)
{
std::optional<MapRange> result;
if (dukMapRange.type() == DukValue::Type::OBJECT)
{
auto leftTop = GetCoordsXY(dukMapRange["leftTop"]);
@ -166,11 +164,11 @@ namespace OpenRCT2::Scripting
auto rightBottom = GetCoordsXY(dukMapRange["rightBottom"]);
if (rightBottom.has_value())
{
result = MapRange(leftTop->x, leftTop->y, rightBottom->x, rightBottom->y);
return MapRange(leftTop->x, leftTop->y, rightBottom->x, rightBottom->y);
}
}
}
return result;
return std::nullopt;
}
};
} // namespace OpenRCT2::Scripting

View File

@ -248,7 +248,7 @@ namespace OpenRCT2::Scripting
return i;
}
}
return {};
return std::nullopt;
}
};
@ -489,7 +489,7 @@ namespace OpenRCT2::Scripting
return i;
}
}
return {};
return std::nullopt;
}
const TitleSequenceManagerItem* GetItem() const

View File

@ -84,7 +84,7 @@ rct_window* window_ride_demolish_prompt_open(Ride* ride)
w->widgets = window_ride_demolish_widgets;
w->enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_CANCEL) | (1ULL << WIDX_DEMOLISH);
WindowInitScrollWidgets(w);
w->number = ride->id;
w->rideId = ride->id;
_demolishRideCost = -ride_get_refund_price(ride);
return w;
@ -109,7 +109,7 @@ rct_window* window_ride_refurbish_prompt_open(Ride* ride)
w->widgets = window_ride_refurbish_widgets;
w->enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_CANCEL) | (1ULL << WIDX_REFURBISH);
WindowInitScrollWidgets(w);
w->number = ride->id;
w->rideId = ride->id;
_demolishRideCost = -ride_get_refund_price(ride);
return w;
@ -125,7 +125,7 @@ static void window_ride_demolish_mouseup(rct_window* w, rct_widgetindex widgetIn
{
case WIDX_DEMOLISH:
{
auto ride = get_ride(w->number);
auto ride = get_ride(w->rideId);
ride_action_modify(ride, RIDE_MODIFY_DEMOLISH, GAME_COMMAND_FLAG_APPLY);
break;
}
@ -142,7 +142,7 @@ static void window_ride_refurbish_mouseup(rct_window* w, rct_widgetindex widgetI
{
case WIDX_REFURBISH:
{
auto ride = get_ride(w->number);
auto ride = get_ride(w->rideId);
ride_action_modify(ride, RIDE_MODIFY_RENEW, GAME_COMMAND_FLAG_APPLY);
break;
}
@ -161,7 +161,7 @@ static void window_ride_demolish_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
WindowDrawWidgets(w, dpi);
auto ride = get_ride(w->number);
auto ride = get_ride(w->rideId);
if (ride != nullptr)
{
auto stringId = (gParkFlags & PARK_FLAGS_NO_MONEY) ? STR_DEMOLISH_RIDE_ID : STR_DEMOLISH_RIDE_ID_MONEY;
@ -178,7 +178,7 @@ static void window_ride_refurbish_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
WindowDrawWidgets(w, dpi);
auto ride = get_ride(w->number);
auto ride = get_ride(w->rideId);
if (ride != nullptr)
{
auto stringId = (gParkFlags & PARK_FLAGS_NO_MONEY) ? STR_REFURBISH_RIDE_ID_NO_MONEY : STR_REFURBISH_RIDE_ID_MONEY;

View File

@ -47,7 +47,7 @@ rct_window* window_editor_main_open()
gShowGridLinesRefCount = 0;
gShowLandRightsRefCount = 0;
gShowConstuctionRightsRefCount = 0;
window_footpath_reset_selected_path();
WindowFootpathResetSelectedPath();
context_open_window(WC_TOP_TOOLBAR);
context_open_window_view(WV_EDITOR_BOTTOM_TOOLBAR);

View File

@ -972,7 +972,7 @@ static void window_editor_objective_options_rides_update(rct_window* w)
{
if (ride.IsRide())
{
w->list_item_positions[numItems] = ride.id;
w->list_item_positions[numItems] = EnumValue(ride.id);
numItems++;
}
}
@ -1005,7 +1005,8 @@ static void window_editor_objective_options_rides_scrollmousedown(
if (i < 0 || i >= w->no_list_items)
return;
auto ride = get_ride(w->list_item_positions[i]);
const auto rideId = static_cast<ride_id_t>(w->list_item_positions[i]);
auto ride = get_ride(rideId);
if (ride != nullptr)
{
ride->lifecycle_flags ^= RIDE_LIFECYCLE_INDESTRUCTIBLE;
@ -1098,7 +1099,8 @@ static void window_editor_objective_options_rides_scrollpaint(rct_window* w, rct
}
// Checkbox mark
auto ride = get_ride(w->list_item_positions[i]);
const auto rideId = static_cast<ride_id_t>(w->list_item_positions[i]);
auto ride = get_ride(rideId);
if (ride != nullptr)
{
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE)

View File

@ -41,6 +41,8 @@ static uint8_t _footpathConstructionMode;
static std::vector<std::pair<ObjectType, ObjectEntryIndex>> _dropdownEntries;
static PathConstructFlags FootpathCreateConstructFlags(ObjectEntryIndex& type);
// clang-format off
enum
{
@ -49,12 +51,6 @@ enum
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL
};
enum
{
SELECTED_PATH_TYPE_NORMAL,
SELECTED_PATH_TYPE_QUEUE
};
enum WINDOW_FOOTPATH_WIDGET_IDX
{
WIDX_BACKGROUND,
@ -187,7 +183,7 @@ static void window_footpath_construct();
static void window_footpath_remove();
static void window_footpath_set_enabled_and_pressed_widgets();
static void footpath_get_next_path_info(ObjectEntryIndex* type, CoordsXYZ& footpathLoc, int32_t* slope);
static bool footpath_select_default();
static bool FootpathSelectDefault();
/**
*
@ -195,7 +191,7 @@ static bool footpath_select_default();
*/
rct_window* window_footpath_open()
{
if (!footpath_select_default())
if (!FootpathSelectDefault())
{
// No path objects to select from, don't open window
return nullptr;
@ -451,8 +447,6 @@ static void window_footpath_toolup(rct_window* w, rct_widgetindex widgetIndex, c
*/
static void window_footpath_update_provisional_path_for_bridge_mode(rct_window* w)
{
int32_t slope;
if (_footpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
{
return;
@ -472,15 +466,9 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window*
ObjectEntryIndex railings = gFootpathSelection.Railings;
CoordsXYZ footpathLoc;
int32_t slope;
footpath_get_next_path_info(&type, footpathLoc, &slope);
PathConstructFlags pathConstructFlags = 0;
if (gFootpathSelection.IsQueueSelected)
pathConstructFlags |= PathConstructFlag::IsQueue;
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
pathConstructFlags |= PathConstructFlag::IsPathObject;
type = gFootpathSelection.LegacyPath;
}
auto pathConstructFlags = FootpathCreateConstructFlags(type);
_window_footpath_cost = footpath_provisional_set(type, railings, footpathLoc, slope, pathConstructFlags);
widget_invalidate(w, WIDX_CONSTRUCT);
@ -495,6 +483,7 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window*
gProvisionalFootpath.Flags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW;
CoordsXYZ footpathLoc;
int32_t slope;
footpath_get_next_path_info(nullptr, footpathLoc, &slope);
gMapSelectArrowPosition = footpathLoc;
gMapSelectArrowDirection = _footpathConstructDirection;
@ -581,13 +570,13 @@ static void window_footpath_invalidate(rct_window* w)
// Set footpath and queue type button images
auto pathImage = static_cast<uint32_t>(SPR_NONE);
auto queueImage = static_cast<uint32_t>(SPR_NONE);
auto pathEntry = get_path_surface_entry(gFootpathSelection.NormalSurface);
auto pathEntry = GetPathSurfaceEntry(gFootpathSelection.NormalSurface);
if (pathEntry != nullptr)
{
pathImage = pathEntry->PreviewImageId;
}
pathEntry = get_path_surface_entry(gFootpathSelection.QueueSurface);
pathEntry = GetPathSurfaceEntry(gFootpathSelection.QueueSurface);
if (pathEntry != nullptr)
{
queueImage = pathEntry->PreviewImageId;
@ -598,7 +587,7 @@ static void window_footpath_invalidate(rct_window* w)
// Set railing
auto railingsImage = static_cast<uint32_t>(SPR_NONE);
auto railingsEntry = get_path_railings_entry(gFootpathSelection.Railings);
auto railingsEntry = GetPathRailingsEntry(gFootpathSelection.Railings);
if (railingsEntry != nullptr)
{
railingsImage = railingsEntry->PreviewImageId;
@ -657,7 +646,7 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (gFootpathSelection.LegacyPath == OBJECT_ENTRY_INDEX_NULL)
{
auto selectedPath = gFootpathSelection.GetSelectedSurface();
const auto* pathType = get_path_surface_entry(selectedPath);
const auto* pathType = GetPathSurfaceEntry(selectedPath);
if (pathType != nullptr)
{
baseImage = pathType->BaseImageId;
@ -793,7 +782,7 @@ static void window_footpath_show_railings_types_dialog(rct_window* w, rct_widget
std::optional<size_t> defaultIndex;
for (int32_t i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++)
{
const auto* railingsEntry = get_path_railings_entry(i);
const auto* railingsEntry = GetPathRailingsEntry(i);
if (railingsEntry == nullptr)
{
continue;
@ -911,17 +900,8 @@ static void window_footpath_set_provisional_path_at_point(const ScreenCoordsXY&
z += PATH_HEIGHT_STEP;
}
PathConstructFlags constructFlags = 0;
auto pathType = gFootpathSelection.GetSelectedSurface();
if (gFootpathSelection.IsQueueSelected)
{
constructFlags |= PathConstructFlag::IsQueue;
}
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
constructFlags |= PathConstructFlag::IsPathObject;
pathType = gFootpathSelection.LegacyPath;
}
auto constructFlags = FootpathCreateConstructFlags(pathType);
_window_footpath_cost = footpath_provisional_set(
pathType, gFootpathSelection.Railings, { info.Loc, z }, slope, constructFlags);
window_invalidate_by_class(WC_FOOTPATH);
@ -942,7 +922,7 @@ static void window_footpath_set_selection_start_bridge_at_point(const ScreenCoor
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
auto mapCoords = footpath_bridge_get_info_from_pos(screenCoords, &direction, &tileElement);
if (mapCoords.isNull())
if (mapCoords.IsNull())
{
return;
}
@ -1020,16 +1000,8 @@ static void window_footpath_place_path_at_point(const ScreenCoordsXY& screenCoor
// Try and place path
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
auto selectedType = gFootpathSelection.GetSelectedSurface();
PathConstructFlags constructFlags = 0;
if (gFootpathSelection.IsQueueSelected)
{
constructFlags |= PathConstructFlag::IsQueue;
}
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
constructFlags |= PathConstructFlag::IsPathObject;
selectedType = gFootpathSelection.LegacyPath;
}
PathConstructFlags constructFlags = FootpathCreateConstructFlags(selectedType);
auto footpathPlaceAction = FootpathPlaceAction(
{ info.Loc, z }, slope, selectedType, gFootpathSelection.Railings, INVALID_DIRECTION, constructFlags);
footpathPlaceAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
@ -1059,7 +1031,7 @@ static void window_footpath_start_bridge_at_point(const ScreenCoordsXY& screenCo
TileElement* tileElement;
auto mapCoords = footpath_bridge_get_info_from_pos(screenCoords, &direction, &tileElement);
if (mapCoords.isNull())
if (mapCoords.IsNull())
{
return;
}
@ -1121,14 +1093,8 @@ static void window_footpath_construct()
footpath_get_next_path_info(&type, footpathLoc, &slope);
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
PathConstructFlags constructFlags = 0;
if (gFootpathSelection.IsQueueSelected)
constructFlags |= PathConstructFlag::IsQueue;
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
constructFlags |= PathConstructFlag::IsPathObject;
type = gFootpathSelection.LegacyPath;
}
PathConstructFlags constructFlags = FootpathCreateConstructFlags(type);
auto footpathPlaceAction = FootpathPlaceAction(
footpathLoc, slope, type, gFootpathSelection.Railings, _footpathConstructDirection, constructFlags);
footpathPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
@ -1388,12 +1354,12 @@ static void footpath_get_next_path_info(ObjectEntryIndex* type, CoordsXYZ& footp
}
}
static ObjectEntryIndex footpath_get_default_surface(bool queue)
static ObjectEntryIndex FootpathGetDefaultSurface(bool queue)
{
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
{
auto pathEntry = get_path_surface_entry(i);
auto pathEntry = GetPathSurfaceEntry(i);
if (pathEntry != nullptr)
{
if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
@ -1409,11 +1375,11 @@ static ObjectEntryIndex footpath_get_default_surface(bool queue)
return OBJECT_ENTRY_INDEX_NULL;
}
static ObjectEntryIndex footpath_get_default_railing()
static ObjectEntryIndex FootpathGetDefaultRailings()
{
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++)
{
const auto* railingEntry = get_path_railings_entry(i);
const auto* railingEntry = GetPathRailingsEntry(i);
if (railingEntry != nullptr)
{
return i;
@ -1422,9 +1388,9 @@ static ObjectEntryIndex footpath_get_default_railing()
return OBJECT_ENTRY_INDEX_NULL;
}
static bool footpath_is_surface_okay(ObjectEntryIndex index, bool queue)
static bool FootpathIsSurfaceEntryOkay(ObjectEntryIndex index, bool queue)
{
auto pathEntry = get_path_surface_entry(index);
auto pathEntry = GetPathSurfaceEntry(index);
if (pathEntry != nullptr)
{
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
@ -1440,7 +1406,7 @@ static bool footpath_is_surface_okay(ObjectEntryIndex index, bool queue)
return false;
}
static bool footpath_is_legacy_path_okay(ObjectEntryIndex index)
static bool FootpathIsLegacyPathEntryOkay(ObjectEntryIndex index)
{
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
@ -1453,11 +1419,11 @@ static bool footpath_is_legacy_path_okay(ObjectEntryIndex index)
return false;
}
static ObjectEntryIndex footpath_get_default_legacy_path()
static ObjectEntryIndex FootpathGetDefaultLegacyPath()
{
for (ObjectEntryIndex i = 0; i < MAX_PATH_OBJECTS; i++)
{
if (footpath_is_legacy_path_okay(i))
if (FootpathIsLegacyPathEntryOkay(i))
{
return i;
}
@ -1465,35 +1431,35 @@ static ObjectEntryIndex footpath_get_default_legacy_path()
return OBJECT_ENTRY_INDEX_NULL;
}
static bool footpath_select_default()
static bool FootpathSelectDefault()
{
// Select default footpath
auto surfaceIndex = footpath_get_default_surface(false);
if (footpath_is_surface_okay(gFootpathSelection.NormalSurface, false))
auto surfaceIndex = FootpathGetDefaultSurface(false);
if (FootpathIsSurfaceEntryOkay(gFootpathSelection.NormalSurface, false))
{
surfaceIndex = gFootpathSelection.NormalSurface;
}
// Select default queue
auto queueIndex = footpath_get_default_surface(true);
if (footpath_is_surface_okay(gFootpathSelection.QueueSurface, true))
auto queueIndex = FootpathGetDefaultSurface(true);
if (FootpathIsSurfaceEntryOkay(gFootpathSelection.QueueSurface, true))
{
queueIndex = gFootpathSelection.QueueSurface;
}
// Select default railing
auto railingIndex = footpath_get_default_railing();
const auto* railingEntry = get_path_railings_entry(gFootpathSelection.Railings);
auto railingIndex = FootpathGetDefaultRailings();
const auto* railingEntry = GetPathRailingsEntry(gFootpathSelection.Railings);
if (railingEntry != nullptr)
{
railingIndex = gFootpathSelection.Railings;
}
// Select default legacy path
auto legacyPathIndex = footpath_get_default_legacy_path();
auto legacyPathIndex = FootpathGetDefaultLegacyPath();
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
if (footpath_is_legacy_path_okay(gFootpathSelection.LegacyPath))
if (FootpathIsLegacyPathEntryOkay(gFootpathSelection.LegacyPath))
{
// Keep legacy path selected
legacyPathIndex = gFootpathSelection.LegacyPath;
@ -1525,6 +1491,19 @@ static bool footpath_select_default()
return true;
}
static PathConstructFlags FootpathCreateConstructFlags(ObjectEntryIndex& type)
{
PathConstructFlags pathConstructFlags = 0;
if (gFootpathSelection.IsQueueSelected)
pathConstructFlags |= PathConstructFlag::IsQueue;
if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL)
{
pathConstructFlags |= PathConstructFlag::IsLegacyPathObject;
type = gFootpathSelection.LegacyPath;
}
return pathConstructFlags;
}
void window_footpath_keyboard_shortcut_turn_left()
{
rct_window* w = window_find_by_class(WC_FOOTPATH);
@ -1620,7 +1599,7 @@ void window_footpath_keyboard_shortcut_build_current()
window_event_mouse_up_call(w, WIDX_CONSTRUCT);
}
void window_footpath_reset_selected_path()
void WindowFootpathResetSelectedPath()
{
gFootpathSelection = {};
}

View File

@ -174,12 +174,12 @@ static void window_game_bottom_toolbar_mouseup(rct_window* w, rct_widgetindex wi
auto subjectLoc = News::GetSubjectLocation(newsItem->Type, newsItem->Assoc);
if (subjectLoc == std::nullopt)
if (!subjectLoc.has_value())
break;
rct_window* mainWindow = window_get_main();
if (mainWindow != nullptr)
window_scroll_to_location(mainWindow, *subjectLoc);
window_scroll_to_location(mainWindow, subjectLoc.value());
}
break;
case WIDX_RIGHT_OUTSET:
@ -315,7 +315,7 @@ static void window_game_bottom_toolbar_invalidate(rct_window* w)
// Find out if the news item is no longer valid
auto subjectLoc = News::GetSubjectLocation(newsItem->Type, newsItem->Assoc);
if (subjectLoc == std::nullopt)
if (!subjectLoc.has_value())
w->disabled_widgets |= (1ULL << WIDX_NEWS_LOCATE);
if (!(newsItem->TypeHasSubject()))

View File

@ -7,6 +7,7 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <openrct2-ui/interface/Dropdown.h>
#include <openrct2-ui/interface/Viewport.h>
#include <openrct2-ui/interface/Widget.h>
#include <openrct2-ui/windows/Window.h>
@ -148,6 +149,8 @@ static void window_guest_common_invalidate(rct_window* w);
static void window_guest_overview_close(rct_window *w);
static void window_guest_overview_resize(rct_window *w);
static void window_guest_overview_mouse_up(rct_window *w, rct_widgetindex widgetIndex);
static void window_guest_overview_mouse_down(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
static void window_guest_overview_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
static void window_guest_overview_paint(rct_window *w, rct_drawpixelinfo *dpi);
static void window_guest_overview_invalidate(rct_window *w);
static void window_guest_overview_viewport_rotate(rct_window *w);
@ -156,6 +159,8 @@ static void window_guest_overview_text_input(rct_window *w, rct_widgetindex widg
static void window_guest_overview_tool_update(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
static void window_guest_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
static void window_guest_overview_tool_abort(rct_window *w, rct_widgetindex widgetIndex);
static void window_guest_follow(rct_window *w);
static void window_guest_show_locate_dropdown(rct_window* w, rct_widget* widget);
static void window_guest_mouse_up(rct_window *w, rct_widgetindex widgetIndex);
@ -186,6 +191,8 @@ static rct_window_event_list window_guest_overview_events([](auto& events)
{
events.close = &window_guest_overview_close;
events.mouse_up = &window_guest_overview_mouse_up;
events.mouse_down = &window_guest_overview_mouse_down;
events.dropdown = &window_guest_overview_dropdown;
events.resize = &window_guest_overview_resize;
events.update = &window_guest_overview_update;
events.tool_update = &window_guest_overview_tool_update;
@ -585,7 +592,7 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex)
}
w->picked_peep_old_x = peep->x;
CoordsXYZ nullLoc{};
nullLoc.setNull();
nullLoc.SetNull();
PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, nullLoc, network_get_current_player_id() };
pickupAction.SetCallback([peepnum = w->number](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
@ -606,9 +613,6 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex)
w, widgetIndex, STR_GUEST_RENAME_TITLE, STR_GUEST_RENAME_PROMPT, {}, peepName.c_str(), 32);
break;
}
case WIDX_LOCATE:
w->ScrollToViewport();
break;
case WIDX_TRACK:
{
uint32_t flags = peep->PeepFlags ^ PEEP_FLAGS_TRACKING;
@ -620,6 +624,51 @@ void window_guest_overview_mouse_up(rct_window* w, rct_widgetindex widgetIndex)
}
}
static void window_guest_overview_mouse_down(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
{
switch (widgetIndex)
{
case WIDX_LOCATE:
window_guest_show_locate_dropdown(w, widget);
break;
}
}
static void window_guest_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
{
switch (widgetIndex)
{
case WIDX_LOCATE:
{
if (dropdownIndex == 0)
{
w->ScrollToViewport();
}
else if (dropdownIndex == 1)
{
window_guest_follow(w);
}
break;
}
}
}
static void window_guest_show_locate_dropdown(rct_window* w, rct_widget* widget)
{
gDropdownItemsFormat[0] = STR_LOCATE_SUBJECT_TIP;
gDropdownItemsFormat[1] = STR_FOLLOW_SUBJECT_TIP;
WindowDropdownShowText(
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[1], 0, 2);
gDropdownDefaultIndex = 0;
}
static void window_guest_follow(rct_window* w)
{
rct_window* w_main = window_get_main();
window_follow_sprite(w_main, w->number);
}
/**
*
* rct2: 0x696AA0
@ -1130,7 +1179,7 @@ void window_guest_overview_tool_update(rct_window* w, rct_widgetindex widgetInde
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
auto mapCoords = footpath_get_coordinates_from_pos({ screenCoords.x, screenCoords.y + 16 }, nullptr, nullptr);
if (!mapCoords.isNull())
if (!mapCoords.IsNull())
{
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
gMapSelectType = MAP_SELECT_TYPE_FULL;
@ -1178,7 +1227,7 @@ void window_guest_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex,
TileElement* tileElement;
auto destCoords = footpath_get_coordinates_from_pos({ screenCoords.x, screenCoords.y + 16 }, nullptr, &tileElement);
if (destCoords.isNull())
if (destCoords.IsNull())
return;
PeepPickupAction pickupAction{
@ -1454,7 +1503,7 @@ void window_guest_rides_update(rct_window* w)
{
if (ride.IsRide() && guest->HasRidden(&ride))
{
w->list_item_positions[curr_list_position] = ride.id;
w->list_item_positions[curr_list_position] = EnumValue(ride.id);
curr_list_position++;
}
}
@ -1605,7 +1654,8 @@ void window_guest_rides_scroll_paint(rct_window* w, rct_drawpixelinfo* dpi, int3
stringId = STR_WINDOW_COLOUR_2_STRINGID;
}
auto ride = get_ride(w->list_item_positions[list_index]);
const auto rideId = static_cast<ride_id_t>(w->list_item_positions[list_index]);
auto ride = get_ride(rideId);
if (ride != nullptr)
{
auto ft = Formatter();

View File

@ -182,7 +182,7 @@ public:
{
case GuestListFilterType::GuestsOnRide:
{
auto guestRide = get_ride(index);
auto guestRide = get_ride(static_cast<ride_id_t>(index));
if (guestRide != nullptr)
{
ft.Add<rct_string_id>(
@ -198,7 +198,7 @@ public:
}
case GuestListFilterType::GuestsInQueue:
{
auto guestRide = get_ride(index);
auto guestRide = get_ride(static_cast<ride_id_t>(index));
if (guestRide != nullptr)
{
ft.Add<rct_string_id>(STR_QUEUING_FOR);
@ -213,7 +213,7 @@ public:
}
case GuestListFilterType::GuestsThinkingAboutRide:
{
auto guestRide = get_ride(index);
auto guestRide = get_ride(static_cast<ride_id_t>(index));
if (guestRide != nullptr)
{
ft.Add<rct_string_id>(STR_NONE);

View File

@ -286,7 +286,7 @@ static void window_land_rights_tool_update_land_rights(const ScreenCoordsXY& scr
auto mapTile = screen_get_map_xy(screenCoords, nullptr);
if (!mapTile)
if (!mapTile.has_value())
{
if (_landRightsCost != MONEY32_UNDEFINED)
{

View File

@ -47,7 +47,7 @@ rct_window* window_main_open()
gShowGridLinesRefCount = 0;
gShowLandRightsRefCount = 0;
gShowConstuctionRightsRefCount = 0;
window_footpath_reset_selected_path();
WindowFootpathResetSelectedPath();
return window;
}

View File

@ -1187,7 +1187,7 @@ static void window_map_set_land_rights_tool_update(const ScreenCoordsXY& screenC
map_invalidate_selection_rect();
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
auto mapCoords = screen_get_map_xy(screenCoords, &viewport);
if (!mapCoords)
if (!mapCoords.has_value())
return;
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
@ -1216,13 +1216,13 @@ static CoordsXYZD place_park_entrance_get_map_position(const ScreenCoordsXY& scr
CoordsXYZD parkEntranceMapPosition{ 0, 0, 0, INVALID_DIRECTION };
const CoordsXY mapCoords = ViewportInteractionGetTileStartAtCursor(screenCoords);
parkEntranceMapPosition = { mapCoords.x, mapCoords.y, 0, INVALID_DIRECTION };
if (parkEntranceMapPosition.isNull())
if (parkEntranceMapPosition.IsNull())
return parkEntranceMapPosition;
auto surfaceElement = map_get_surface_element_at(mapCoords);
if (surfaceElement == nullptr)
{
parkEntranceMapPosition.setNull();
parkEntranceMapPosition.SetNull();
return parkEntranceMapPosition;
}
@ -1257,7 +1257,7 @@ static void window_map_place_park_entrance_tool_update(const ScreenCoordsXY& scr
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT;
CoordsXYZD parkEntrancePosition = place_park_entrance_get_map_position(screenCoords);
if (parkEntrancePosition.isNull())
if (parkEntrancePosition.IsNull())
{
park_entrance_remove_ghost();
return;
@ -1298,7 +1298,7 @@ static void window_map_set_peep_spawn_tool_update(const ScreenCoordsXY& screenCo
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
auto mapCoords = footpath_bridge_get_info_from_pos(screenCoords, &direction, &tileElement);
if (mapCoords.isNull())
if (mapCoords.IsNull())
return;
mapZ = tileElement->GetBaseZ();
@ -1329,7 +1329,7 @@ static void window_map_place_park_entrance_tool_down(const ScreenCoordsXY& scree
park_entrance_remove_ghost();
CoordsXYZD parkEntrancePosition = place_park_entrance_get_map_position(screenCoords);
if (!parkEntrancePosition.isNull())
if (!parkEntrancePosition.IsNull())
{
auto gameAction = PlaceParkEntranceAction(parkEntrancePosition, gFootpathSelectedId);
auto result = GameActions::Execute(&gameAction);
@ -1351,7 +1351,7 @@ static void window_map_set_peep_spawn_tool_down(const ScreenCoordsXY& screenCoor
// Verify footpath exists at location, and retrieve coordinates
auto mapCoords = footpath_get_coordinates_from_pos(screenCoords, &direction, &tileElement);
if (mapCoords.isNull())
if (mapCoords.IsNull())
return;
mapZ = tileElement->GetBaseZ();

View File

@ -130,7 +130,7 @@ rct_window* window_maze_construction_open()
WindowInitScrollWidgets(w);
w->number = _currentRideIndex;
w->rideId = _currentRideIndex;
window_push_others_right(w);
show_gridlines();
@ -159,7 +159,7 @@ static void window_maze_construction_close(rct_window* w)
auto ride = get_ride(_currentRideIndex);
if (ride != nullptr)
{
if (ride->overall_view.isNull())
if (ride->overall_view.IsNull())
{
int32_t savedPausedState = gGamePaused;
gGamePaused = 0;
@ -169,7 +169,7 @@ static void window_maze_construction_close(rct_window* w)
else
{
auto intent = Intent(WC_RIDE);
intent.putExtra(INTENT_EXTRA_RIDE_ID, ride->id);
intent.putExtra(INTENT_EXTRA_RIDE_ID, EnumValue(ride->id));
context_open_intent(&intent);
}
}
@ -181,7 +181,7 @@ static void window_maze_construction_entrance_mouseup(rct_window* w, rct_widgeti
return;
gRideEntranceExitPlaceType = widgetIndex == WIDX_MAZE_ENTRANCE ? ENTRANCE_TYPE_RIDE_ENTRANCE : ENTRANCE_TYPE_RIDE_EXIT;
gRideEntranceExitPlaceRideIndex = static_cast<uint8_t>(w->number);
gRideEntranceExitPlaceRideIndex = w->rideId;
gRideEntranceExitPlaceStationIndex = 0;
input_set_flag(INPUT_FLAG_6, true);
@ -331,7 +331,7 @@ static void window_maze_construction_update(rct_window* w)
default:
break;
}
sub_6C94D8();
UpdateGhostTrackAndArrow();
}
/**
@ -366,7 +366,7 @@ static void window_maze_construction_entrance_tooldown(const ScreenCoordsXY& scr
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
CoordsXYZD entranceOrExitCoords = ride_get_entrance_or_exit_position_from_screen_position(screenCoords);
if (entranceOrExitCoords.isNull())
if (entranceOrExitCoords.IsNull())
return;
if (gRideEntranceExitPlaceDirection == INVALID_DIRECTION)

View File

@ -22,7 +22,9 @@
static constexpr const rct_string_id WINDOW_TITLE = STR_NONE;
static constexpr const int32_t WH = 109;
static constexpr const int32_t WW = 350;
constexpr uint16_t SELECTED_RIDE_UNDEFINED = 0xFFFF;
constexpr auto SELECTED_RIDE_UNDEFINED = RIDE_ID_NULL;
constexpr uint16_t SELECTED_ITEM_UNDEFINED = 0xFFFF;
// clang-format off
enum WINDOW_NEW_CAMPAIGN_WIDGET_IDX {
@ -205,9 +207,9 @@ public:
else
{
int32_t numItems = 0;
for (auto rideId : RideList)
for (auto rideIndex : RideList)
{
auto curRide = get_ride(rideId);
auto curRide = get_ride(rideIndex);
if (curRide != nullptr)
{
// HACK until dropdown items have longer argument buffers
@ -252,7 +254,8 @@ public:
break;
case WIDX_START_BUTTON:
{
auto gameAction = ParkMarketingAction(campaign.campaign_type, campaign.RideId, campaign.no_weeks);
auto gameAction = ParkMarketingAction(
campaign.campaign_type, static_cast<int32_t>(campaign.RideId), campaign.no_weeks);
gameAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
if (result->Error == GameActions::Status::Ok)
{
@ -322,7 +325,7 @@ public:
widgets[WIDX_RIDE_DROPDOWN].type = WindowWidgetType::DropdownMenu;
widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_ITEM;
if (campaign.ShopItemId != SELECTED_RIDE_UNDEFINED)
if (campaign.ShopItemId != SELECTED_ITEM_UNDEFINED)
{
widgets[WIDX_RIDE_DROPDOWN].text = GetShopItemDescriptor(ShopItem(campaign.ShopItemId)).Naming.Plural;
}

View File

@ -110,9 +110,9 @@ public:
{
static rct_window* _mainWindow;
auto subjectLoc = News::GetSubjectLocation(newsItem.Type, newsItem.Assoc);
if (subjectLoc != std::nullopt && (_mainWindow = window_get_main()) != nullptr)
if (subjectLoc.has_value() && (_mainWindow = window_get_main()) != nullptr)
{
window_scroll_to_location(_mainWindow, *subjectLoc);
window_scroll_to_location(_mainWindow, subjectLoc.value());
}
}
}

View File

@ -285,6 +285,10 @@ static rct_widget window_object_load_error_widgets[] = {
{ WIDGETS_END },
};
<<<<<<< HEAD
=======
static rct_string_id get_object_type_string(ObjectType type);
>>>>>>> upstream/develop
static void window_object_load_error_close(rct_window *w);
static void window_object_load_error_update(rct_window *w);
static void window_object_load_error_mouseup(rct_window *w, rct_widgetindex widgetIndex);
@ -372,6 +376,7 @@ static rct_string_id get_object_type_string(ObjectType type)
*/
static void copy_object_names_to_clipboard(rct_window* w)
{
<<<<<<< HEAD
std::stringstream ss;
for (uint16_t i = 0; i < w->no_list_items; i++)
{
@ -381,6 +386,17 @@ static void copy_object_names_to_clipboard(rct_window* w)
}
auto clip = ss.str();
=======
std::stringstream stream;
for (uint16_t i = 0; i < w->no_list_items; i++)
{
const auto& entry = _invalid_entries[i];
stream << entry.GetName();
stream << PLATFORM_NEWLINE;
}
auto clip = stream.str();
>>>>>>> upstream/develop
OpenRCT2::GetContext()->GetUiContext()->SetClipboardText(clip.c_str());
}

View File

@ -610,7 +610,7 @@ static void window_player_update_viewport(rct_window* w, bool scroll)
if (coord.x != 0 || coord.y != 0 || coord.z != 0)
{
auto centreLoc = centre_2d_coordinates(coord, viewport);
if (!centreLoc)
if (!centreLoc.has_value())
{
return;
}
@ -620,13 +620,13 @@ static void window_player_update_viewport(rct_window* w, bool scroll)
scroll = false;
}
if (!scroll || w->savedViewPos != centreLoc)
if (!scroll || w->savedViewPos != centreLoc.value())
{
w->flags |= WF_SCROLLING_TO_LOCATION;
w->savedViewPos = *centreLoc;
w->savedViewPos = centreLoc.value();
if (!scroll)
{
w->viewport->viewPos = *centreLoc;
w->viewport->viewPos = centreLoc.value();
}
widget_invalidate(w, WIDX_VIEWPORT);
}

File diff suppressed because it is too large Load Diff

View File

@ -466,7 +466,7 @@ static void window_ride_construction_select_map_tiles(
Ride* ride, int32_t trackType, int32_t trackDirection, const CoordsXY& tileCoords);
static void window_ride_construction_show_special_track_dropdown(rct_window* w, rct_widget* widget);
static void ride_selected_track_set_seat_rotation(int32_t seatRotation);
static void loc_6C7502(int32_t al);
static void UpdateLiftHillSelected(int32_t slope);
static void ride_construction_set_brakes_speed(int32_t brakesSpeed);
static void ride_construction_tooldown_entrance_exit(const ScreenCoordsXY& screenCoords);
@ -495,9 +495,9 @@ static int32_t ride_get_alternative_type(Ride* ride)
}
/* move to ride.c */
static void close_ride_window_for_construction(rct_windownumber number)
static void close_ride_window_for_construction(ride_id_t rideId)
{
rct_window* w = window_find_by_number(WC_RIDE, number);
rct_window* w = window_find_by_number(WC_RIDE, EnumValue(rideId));
if (w != nullptr && w->page == 1)
window_close(w);
}
@ -543,7 +543,7 @@ rct_window* window_ride_construction_open()
w->colours[1] = COLOUR_DARK_BROWN;
w->colours[2] = COLOUR_DARK_BROWN;
w->number = rideIndex;
w->rideId = rideIndex;
window_push_others_right(w);
show_gridlines();
@ -620,7 +620,7 @@ static void window_ride_construction_close(rct_window* w)
ride->SetToDefaultInspectionInterval();
auto intent = Intent(WC_RIDE);
intent.putExtra(INTENT_EXTRA_RIDE_ID, ride->id);
intent.putExtra(INTENT_EXTRA_RIDE_ID, EnumValue(ride->id));
context_open_intent(&intent);
}
else
@ -1376,11 +1376,11 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
}
if (w->widgets[WIDX_SLOPE_DOWN_STEEP].tooltip == STR_RIDE_CONSTRUCTION_STEEP_SLOPE_DOWN_TIP)
{
loc_6C7502(8);
UpdateLiftHillSelected(TRACK_SLOPE_DOWN_60);
}
else
{
loc_6C7502(10);
UpdateLiftHillSelected(TRACK_SLOPE_UP_90);
}
break;
case WIDX_SLOPE_DOWN:
@ -1389,7 +1389,7 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
{
_currentTrackBankEnd = TRACK_BANK_NONE;
}
loc_6C7502(6);
UpdateLiftHillSelected(TRACK_SLOPE_DOWN_25);
break;
case WIDX_LEVEL:
ride_construction_invalidate_current_track();
@ -1415,7 +1415,7 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
_currentTrackBankEnd = TRACK_BANK_RIGHT;
}
}
loc_6C7502(0);
UpdateLiftHillSelected(TRACK_SLOPE_NONE);
break;
case WIDX_SLOPE_UP:
ride_construction_invalidate_current_track();
@ -1433,7 +1433,7 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
}
else
{
loc_6C7502(2);
UpdateLiftHillSelected(TRACK_SLOPE_UP_25);
}
break;
case WIDX_SLOPE_UP_STEEP:
@ -1508,20 +1508,18 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
}
if (w->widgets[WIDX_SLOPE_UP_STEEP].tooltip == STR_RIDE_CONSTRUCTION_STEEP_SLOPE_UP_TIP)
{
loc_6C7502(4);
UpdateLiftHillSelected(TRACK_SLOPE_UP_60);
}
else
{
loc_6C7502(18);
UpdateLiftHillSelected(TRACK_SLOPE_DOWN_90);
}
break;
case WIDX_CHAIN_LIFT:
ride_construction_invalidate_current_track();
_currentTrackLiftHill ^= CONSTRUCTION_LIFT_HILL_SELECTED;
if (_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED)
{
if ((_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED) && !gCheatsEnableChainLiftOnAllTrack)
_currentTrackAlternative &= ~RIDE_TYPE_ALTERNATIVE_TRACK_PIECES;
}
_currentTrackPrice = MONEY32_UNDEFINED;
window_ride_construction_update_active_elements();
break;
@ -1599,7 +1597,8 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
case WIDX_O_TRACK:
ride_construction_invalidate_current_track();
_currentTrackAlternative |= RIDE_TYPE_ALTERNATIVE_TRACK_PIECES;
_currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
if (!gCheatsEnableChainLiftOnAllTrack)
_currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
_currentTrackPrice = MONEY32_UNDEFINED;
window_ride_construction_update_active_elements();
break;
@ -1888,8 +1887,9 @@ static void window_ride_construction_mouseup_demolish(rct_window* w)
// Invalidate the selected track element or make sure it's at origin???
direction = _currentTrackPieceDirection;
track_type_t type = _currentTrackPieceType;
auto newCoords = sub_6C683D({ _currentTrackBegin, static_cast<Direction>(direction & 3) }, type, 0, &tileElement, 0);
if (newCoords == std::nullopt)
auto newCoords = GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(direction & 3) }, type, 0, &tileElement, 0);
if (!newCoords.has_value())
{
window_ride_construction_update_active_elements();
return;
@ -1918,9 +1918,10 @@ static void window_ride_construction_mouseup_demolish(rct_window* w)
{
direction = _currentTrackPieceDirection;
type = _currentTrackPieceType;
newCoords = sub_6C683D({ _currentTrackBegin, static_cast<Direction>(direction & 3) }, type, 0, &tileElement, 0);
newCoords = GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(direction & 3) }, type, 0, &tileElement, 0);
if (newCoords == std::nullopt)
if (!newCoords.has_value())
{
window_ride_construction_update_active_elements();
return;
@ -1936,7 +1937,7 @@ static void window_ride_construction_mouseup_demolish(rct_window* w)
_currentTrackPieceType, 0,
{ _currentTrackBegin.x, _currentTrackBegin.y, _currentTrackBegin.z, _currentTrackPieceDirection });
const auto rideId = w->number;
const auto rideId = w->rideId;
trackRemoveAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
{
@ -1986,7 +1987,7 @@ static void window_ride_construction_entrance_click(rct_window* w)
else
{
gRideEntranceExitPlaceType = ENTRANCE_TYPE_RIDE_ENTRANCE;
gRideEntranceExitPlaceRideIndex = static_cast<ride_id_t>(w->number);
gRideEntranceExitPlaceRideIndex = w->rideId;
gRideEntranceExitPlaceStationIndex = 0;
input_set_flag(INPUT_FLAG_6, true);
ride_construction_invalidate_current_track();
@ -2016,7 +2017,7 @@ static void window_ride_construction_exit_click(rct_window* w)
else
{
gRideEntranceExitPlaceType = ENTRANCE_TYPE_RIDE_EXIT;
gRideEntranceExitPlaceRideIndex = w->number & 0xFF;
gRideEntranceExitPlaceRideIndex = w->rideId;
gRideEntranceExitPlaceStationIndex = 0;
input_set_flag(INPUT_FLAG_6, true);
ride_construction_invalidate_current_track();
@ -2089,7 +2090,7 @@ static void window_ride_construction_update(rct_window* w)
break;
}
sub_6C94D8();
UpdateGhostTrackAndArrow();
}
/**
@ -2158,7 +2159,7 @@ static std::optional<CoordsXY> ride_get_place_position_from_screen_position(Scre
if (!_trackPlaceCtrlState)
{
mapCoords = ViewportInteractionGetTileStartAtCursor(screenCoords);
if (mapCoords.isNull())
if (mapCoords.IsNull())
return std::nullopt;
_trackPlaceZ = 0;
@ -2177,9 +2178,9 @@ static std::optional<CoordsXY> ride_get_place_position_from_screen_position(Scre
{
auto mapZ = _trackPlaceCtrlZ;
auto mapXYCoords = screen_get_map_xy_with_z(screenCoords, mapZ);
if (mapXYCoords)
if (mapXYCoords.has_value())
{
mapCoords = *mapXYCoords;
mapCoords = mapXYCoords.value();
}
else
{
@ -2367,7 +2368,7 @@ static void window_ride_construction_draw_track_piece(
mapCoords.y = 4112 + (rotatedMapCoords.y / 2);
mapCoords.z = 1024 + mapCoords.z;
int16_t previewZOffset = TrackDefinitions[trackType].preview_z_offset;
int16_t previewZOffset = ted.Definition.preview_z_offset;
mapCoords.z -= previewZOffset;
const ScreenCoordsXY rotatedScreenCoords = translate_3d_to_2d_with_z(get_current_rotation(), mapCoords);
@ -2489,7 +2490,7 @@ void window_ride_construction_update_active_elements_impl()
_selectedTrackType = TrackElemType::None;
if (_rideConstructionState == RideConstructionState::Selected)
{
if (sub_6C683D(
if (GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, 0,
&tileElement, 0)
!= std::nullopt)
@ -2527,7 +2528,7 @@ void window_ride_construction_update_enabled_track_pieces()
*
* rct2: 0x006C94D8
*/
void sub_6C94D8()
void UpdateGhostTrackAndArrow()
{
ride_id_t rideIndex;
int32_t direction, type, liftHillAndAlternativeState;
@ -2551,6 +2552,7 @@ void sub_6C94D8()
case RideConstructionState::Front:
case RideConstructionState::Back:
{
// place ghost piece
if (!(_currentTrackSelectionFlags & TRACK_SELECTION_FLAG_TRACK))
{
if (window_ride_construction_update_state(
@ -2565,7 +2567,7 @@ void sub_6C94D8()
window_ride_construction_update_active_elements();
}
}
// update flashing arrow
auto curTime = platform_get_ticks();
if (_rideConstructionNextArrowPulse >= curTime)
break;
@ -2575,6 +2577,7 @@ void sub_6C94D8()
trackPos = _currentTrackBegin;
direction = _currentTrackPieceDirection;
type = _currentTrackPieceType;
// diagonal pieces trigger this
if (direction >= 4)
direction += 4;
if (_rideConstructionState == RideConstructionState::Back)
@ -2599,8 +2602,9 @@ void sub_6C94D8()
type = _currentTrackPieceType;
uint16_t flags = _currentTrackSelectionFlags & TRACK_SELECTION_FLAG_ARROW ? TRACK_ELEMENT_SET_HIGHLIGHT_TRUE
: TRACK_ELEMENT_SET_HIGHLIGHT_FALSE;
auto newCoords = sub_6C683D({ _currentTrackBegin, static_cast<Direction>(direction) }, type, 0, nullptr, flags);
if (newCoords == std::nullopt)
auto newCoords = GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(direction) }, type, 0, nullptr, flags);
if (!newCoords.has_value())
{
ride_construction_remove_ghosts();
_rideConstructionState = RideConstructionState::State0;
@ -2705,7 +2709,8 @@ static void window_ride_construction_update_possible_ride_configurations()
_numCurrentPossibleSpecialTrackPieces = 0;
for (trackType = 0; trackType < TrackElemType::Count; trackType++)
{
int32_t trackTypeCategory = TrackDefinitions[trackType].type;
const auto& ted = GetTrackElementDescriptor(trackType);
int32_t trackTypeCategory = ted.Definition.type;
if (trackTypeCategory == TRACK_NONE)
continue;
@ -2718,13 +2723,13 @@ static void window_ride_construction_update_possible_ride_configurations()
int32_t slope, bank;
if (_rideConstructionState == RideConstructionState::Front || _rideConstructionState == RideConstructionState::Place)
{
slope = TrackDefinitions[trackType].vangle_start;
bank = TrackDefinitions[trackType].bank_start;
slope = ted.Definition.vangle_start;
bank = ted.Definition.bank_start;
}
else if (_rideConstructionState == RideConstructionState::Back)
{
slope = TrackDefinitions[trackType].vangle_end;
bank = TrackDefinitions[trackType].bank_end;
slope = ted.Definition.vangle_end;
bank = ted.Definition.bank_end;
}
else
{
@ -2733,7 +2738,7 @@ static void window_ride_construction_update_possible_ride_configurations()
if (!ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE))
{
if (TrackDefinitions[trackType].type == TRACK_HELIX_SMALL || TrackDefinitions[trackType].type == TRACK_HELIX_LARGE)
if (ted.Definition.type == TRACK_HELIX_SMALL || ted.Definition.type == TRACK_HELIX_LARGE)
{
if (bank != _previousTrackBankEnd)
{
@ -3356,7 +3361,7 @@ static void window_ride_construction_show_special_track_dropdown(rct_window* w,
*/
static void ride_selected_track_set_seat_rotation(int32_t seatRotation)
{
sub_6C683D(
GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, seatRotation,
nullptr, TRACK_ELEMENT_SET_SEAT_ROTATION);
window_ride_construction_update_active_elements();
@ -3366,15 +3371,21 @@ static void ride_selected_track_set_seat_rotation(int32_t seatRotation)
*
* rct2: 0x006C7502
*/
static void loc_6C7502(int32_t al)
static void UpdateLiftHillSelected(int32_t slope)
{
_currentTrackSlopeEnd = al;
_currentTrackSlopeEnd = slope;
_currentTrackPrice = MONEY32_UNDEFINED;
if (_rideConstructionState == RideConstructionState::Front)
{
if (al != 2 && al != 4 && al != 0)
switch (slope)
{
_currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
case TRACK_SLOPE_NONE:
case TRACK_SLOPE_UP_25:
case TRACK_SLOPE_UP_60:
break;
default:
_currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
break;
}
}
window_ride_construction_update_active_elements();
@ -3388,7 +3399,7 @@ static void ride_construction_set_brakes_speed(int32_t brakesSpeed)
{
TileElement* tileElement;
if (sub_6C683D(
if (GetTrackElementOriginAndApplyChanges(
{ _currentTrackBegin, static_cast<Direction>(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, 0,
&tileElement, 0)
!= std::nullopt)

View File

@ -443,7 +443,7 @@ static void window_ride_list_scrollmousedown(rct_window* w, int32_t scrollIndex,
else
{
auto intent = Intent(WC_RIDE);
intent.putExtra(INTENT_EXTRA_RIDE_ID, rideIndex);
intent.putExtra(INTENT_EXTRA_RIDE_ID, EnumValue(rideIndex));
context_open_intent(&intent);
}
}

View File

@ -134,6 +134,8 @@ static void window_staff_overview_tool_up(rct_window* w, rct_widgetindex widgetI
static void window_staff_overview_tool_abort(rct_window *w, rct_widgetindex widgetIndex);
static void window_staff_overview_text_input(rct_window *w, rct_widgetindex widgetIndex, char *text);
static void window_staff_overview_viewport_rotate(rct_window *w);
static void window_staff_follow(rct_window *w);
static void window_staff_show_locate_dropdown(rct_window* w, rct_widget* widget);
static void window_staff_options_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_staff_options_update(rct_window* w);
@ -408,14 +410,11 @@ void window_staff_overview_mouseup(rct_window* w, rct_widgetindex widgetIndex)
case WIDX_TAB_3:
window_staff_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_LOCATE:
w->ScrollToViewport();
break;
case WIDX_PICKUP:
{
w->picked_peep_old_x = peep->x;
CoordsXYZ nullLoc{};
nullLoc.setNull();
nullLoc.SetNull();
PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, nullLoc, network_get_current_player_id() };
pickupAction.SetCallback([peepnum = w->number](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
@ -509,30 +508,34 @@ void window_staff_overview_resize(rct_window* w)
*/
void window_staff_overview_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
{
if (widgetIndex != WIDX_PATROL)
switch (widgetIndex)
{
return;
}
case WIDX_LOCATE:
window_staff_show_locate_dropdown(w, widget);
break;
case WIDX_PATROL:
{
// Dropdown names
gDropdownItemsFormat[0] = STR_SET_PATROL_AREA;
gDropdownItemsFormat[1] = STR_CLEAR_PATROL_AREA;
// Dropdown names
gDropdownItemsFormat[0] = STR_SET_PATROL_AREA;
gDropdownItemsFormat[1] = STR_CLEAR_PATROL_AREA;
auto dropdownPos = ScreenCoordsXY{ widget->left + w->windowPos.x, widget->top + w->windowPos.y };
int32_t extray = widget->height() + 1;
WindowDropdownShowText(dropdownPos, extray, w->colours[1], 0, 2);
gDropdownDefaultIndex = 0;
auto dropdownPos = ScreenCoordsXY{ widget->left + w->windowPos.x, widget->top + w->windowPos.y };
int32_t extray = widget->height() + 1;
WindowDropdownShowText(dropdownPos, extray, w->colours[1], 0, 2);
gDropdownDefaultIndex = 0;
const auto peep = GetStaff(w);
if (peep == nullptr)
{
return;
}
const auto peep = GetStaff(w);
if (peep == nullptr)
{
return;
}
// Disable clear patrol area if no area is set.
if (!peep->HasPatrolArea())
{
Dropdown::SetDisabled(1, true);
// Disable clear patrol area if no area is set.
if (!peep->HasPatrolArea())
{
Dropdown::SetDisabled(1, true);
}
}
}
}
@ -542,31 +545,61 @@ void window_staff_overview_mousedown(rct_window* w, rct_widgetindex widgetIndex,
*/
void window_staff_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
{
if (widgetIndex != WIDX_PATROL)
switch (widgetIndex)
{
return;
case WIDX_LOCATE:
{
if (dropdownIndex == 0)
{
w->ScrollToViewport();
}
else if (dropdownIndex == 1)
{
window_staff_follow(w);
}
break;
}
case WIDX_PATROL:
{
// Clear patrol
if (dropdownIndex == 1)
{
const auto staff = GetStaff(w);
if (staff != nullptr)
{
staff->ClearPatrolArea();
gfx_invalidate_screen();
staff_update_greyed_patrol_areas();
}
}
else
{
if (!tool_set(w, widgetIndex, Tool::WalkDown))
{
show_gridlines();
gStaffDrawPatrolAreas = w->number;
gfx_invalidate_screen();
}
}
break;
}
}
}
// Clear patrol
if (dropdownIndex == 1)
{
const auto staff = GetStaff(w);
if (staff != nullptr)
{
staff->ClearPatrolArea();
gfx_invalidate_screen();
staff_update_greyed_patrol_areas();
}
}
else
{
if (!tool_set(w, widgetIndex, Tool::WalkDown))
{
show_gridlines();
gStaffDrawPatrolAreas = w->number;
gfx_invalidate_screen();
}
}
static void window_staff_show_locate_dropdown(rct_window* w, rct_widget* widget)
{
gDropdownItemsFormat[0] = STR_LOCATE_SUBJECT_TIP;
gDropdownItemsFormat[1] = STR_FOLLOW_SUBJECT_TIP;
WindowDropdownShowText(
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[1], 0, 2);
gDropdownDefaultIndex = 0;
}
static void window_staff_follow(rct_window* w)
{
rct_window* w_main = window_get_main();
window_follow_sprite(w_main, w->number);
}
/**
@ -1131,7 +1164,7 @@ void window_staff_overview_tool_update(rct_window* w, rct_widgetindex widgetInde
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
auto mapCoords = footpath_get_coordinates_from_pos({ screenCoords.x, screenCoords.y + 16 }, nullptr, nullptr);
if (!mapCoords.isNull())
if (!mapCoords.IsNull())
{
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
gMapSelectType = MAP_SELECT_TYPE_FULL;
@ -1178,7 +1211,7 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex,
TileElement* tileElement;
auto destCoords = footpath_get_coordinates_from_pos({ screenCoords.x, screenCoords.y + 16 }, nullptr, &tileElement);
if (destCoords.isNull())
if (destCoords.IsNull())
return;
PeepPickupAction pickupAction{
@ -1196,7 +1229,7 @@ void window_staff_overview_tool_down(rct_window* w, rct_widgetindex widgetIndex,
{
auto destCoords = footpath_get_coordinates_from_pos(screenCoords, nullptr, nullptr);
if (destCoords.isNull())
if (destCoords.IsNull())
return;
auto staff = TryGetEntity<Staff>(w->number);
@ -1232,7 +1265,7 @@ void window_staff_overview_tool_drag(rct_window* w, rct_widgetindex widgetIndex,
auto destCoords = footpath_get_coordinates_from_pos(screenCoords, nullptr, nullptr);
if (destCoords.isNull())
if (destCoords.IsNull())
return;
auto staff = TryGetEntity<Staff>(w->number);

View File

@ -552,7 +552,7 @@ private:
int32_t direction{};
TileElement* tileElement{};
auto footpathCoords = footpath_get_coordinates_from_pos(screenCoords, &direction, &tileElement);
if (footpathCoords.isNull())
if (footpathCoords.IsNull())
return nullptr;
auto isPatrolAreaSet = staff_is_patrol_area_set_for_type(GetSelectedStaffType(), footpathCoords);

View File

@ -1192,10 +1192,10 @@ static void window_tile_inspector_tool_update(rct_window* w, rct_widgetindex wid
if (clickedElement == nullptr)
{
auto mouseCoords = screen_pos_to_map_pos(screenCoords, nullptr);
if (mouseCoords)
if (mouseCoords.has_value())
{
mouseOnViewport = true;
mapCoords = *mouseCoords;
mapCoords = mouseCoords.value();
}
}
@ -1245,12 +1245,12 @@ static void window_tile_inspector_update_selected_tile(rct_window* w, const Scre
{
auto mouseCoords = screen_pos_to_map_pos(screenCoords, nullptr);
if (!mouseCoords)
if (!mouseCoords.has_value())
{
return;
}
mapCoords = *mouseCoords;
mapCoords = mouseCoords.value();
// Tile is already selected
if (windowTileInspectorTileSelected && mapCoords.x == windowTileInspectorToolMap.x
&& mapCoords.y == windowTileInspectorToolMap.y)
@ -1915,7 +1915,7 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Details
// Ride
auto trackElement = tileElement->AsTrack();
int16_t rideId = trackElement->GetRideIndex();
ride_id_t rideId = trackElement->GetRideIndex();
auto ride = get_ride(rideId);
if (ride != nullptr)
{

View File

@ -26,6 +26,7 @@
#include <openrct2/Input.h>
#include <openrct2/OpenRCT2.h>
#include <openrct2/ParkImporter.h>
#include <openrct2/Version.h>
#include <openrct2/actions/BannerPlaceAction.h>
#include <openrct2/actions/BannerSetColourAction.h>
#include <openrct2/actions/ClearAction.h>
@ -54,6 +55,7 @@
#include <openrct2/paint/VirtualFloor.h>
#include <openrct2/peep/Staff.h>
#include <openrct2/scenario/Scenario.h>
#include <openrct2/ui/UiContext.h>
#include <openrct2/util/Util.h>
#include <openrct2/windows/Intent.h>
#include <openrct2/world/Footpath.h>
@ -119,10 +121,12 @@ enum FILE_MENU_DDIDX {
DDIDX_SCREENSHOT = 7,
DDIDX_GIANT_SCREENSHOT = 8,
// separator
DDIDX_QUIT_TO_MENU = 10,
DDIDX_EXIT_OPENRCT2 = 11,
DDIDX_FILE_BUG_ON_GITHUB = 10,
// separator
DDIDX_UPDATE_AVAILABLE = 13,
DDIDX_QUIT_TO_MENU = 12,
DDIDX_EXIT_OPENRCT2 = 13,
// separator
DDIDX_UPDATE_AVAILABLE = 15,
};
enum TOP_TOOLBAR_VIEW_MENU_DDIDX {
@ -423,60 +427,61 @@ static void window_top_toolbar_mouseup(rct_window* w, rct_widgetindex widgetInde
*/
static void window_top_toolbar_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
{
int32_t numItems;
int32_t numItems = 0;
switch (widgetIndex)
{
case WIDX_FILE_MENU:
if (gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))
{
gDropdownItemsFormat[0] = STR_ABOUT;
gDropdownItemsFormat[1] = STR_OPTIONS;
gDropdownItemsFormat[2] = STR_SCREENSHOT;
gDropdownItemsFormat[3] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[4] = STR_EMPTY;
gDropdownItemsFormat[5] = STR_QUIT_TRACK_DESIGNS_MANAGER;
gDropdownItemsFormat[6] = STR_EXIT_OPENRCT2;
gDropdownItemsFormat[numItems++] = STR_ABOUT;
gDropdownItemsFormat[numItems++] = STR_OPTIONS;
gDropdownItemsFormat[numItems++] = STR_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_TRACK_DESIGNS_MANAGER;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
gDropdownItemsFormat[5] = STR_QUIT_ROLLERCOASTER_DESIGNER;
numItems = 7;
gDropdownItemsFormat[numItems++] = STR_QUIT_ROLLERCOASTER_DESIGNER;
}
else if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
{
gDropdownItemsFormat[0] = STR_LOAD_LANDSCAPE;
gDropdownItemsFormat[1] = STR_SAVE_LANDSCAPE;
gDropdownItemsFormat[2] = STR_EMPTY;
gDropdownItemsFormat[3] = STR_ABOUT;
gDropdownItemsFormat[4] = STR_OPTIONS;
gDropdownItemsFormat[5] = STR_SCREENSHOT;
gDropdownItemsFormat[6] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[7] = STR_EMPTY;
gDropdownItemsFormat[8] = STR_QUIT_SCENARIO_EDITOR;
gDropdownItemsFormat[9] = STR_EXIT_OPENRCT2;
numItems = 10;
gDropdownItemsFormat[numItems++] = STR_LOAD_LANDSCAPE;
gDropdownItemsFormat[numItems++] = STR_SAVE_LANDSCAPE;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_ABOUT;
gDropdownItemsFormat[numItems++] = STR_OPTIONS;
gDropdownItemsFormat[numItems++] = STR_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_SCENARIO_EDITOR;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
}
else
{
gDropdownItemsFormat[0] = STR_NEW_GAME;
gDropdownItemsFormat[1] = STR_LOAD_GAME;
gDropdownItemsFormat[2] = STR_SAVE_GAME;
gDropdownItemsFormat[3] = STR_SAVE_GAME_AS;
gDropdownItemsFormat[4] = STR_EMPTY;
gDropdownItemsFormat[5] = STR_ABOUT;
gDropdownItemsFormat[6] = STR_OPTIONS;
gDropdownItemsFormat[7] = STR_SCREENSHOT;
gDropdownItemsFormat[8] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[9] = STR_EMPTY;
gDropdownItemsFormat[10] = STR_QUIT_TO_MENU;
gDropdownItemsFormat[11] = STR_EXIT_OPENRCT2;
numItems = 12;
gDropdownItemsFormat[numItems++] = STR_NEW_GAME;
gDropdownItemsFormat[numItems++] = STR_LOAD_GAME;
gDropdownItemsFormat[numItems++] = STR_SAVE_GAME;
gDropdownItemsFormat[numItems++] = STR_SAVE_GAME_AS;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_ABOUT;
gDropdownItemsFormat[numItems++] = STR_OPTIONS;
gDropdownItemsFormat[numItems++] = STR_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_GIANT_SCREENSHOT;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_FILE_BUG_ON_GITHUB;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_QUIT_TO_MENU;
gDropdownItemsFormat[numItems++] = STR_EXIT_OPENRCT2;
if (OpenRCT2::GetContext()->HasNewVersionInfo())
{
gDropdownItemsFormat[12] = STR_EMPTY;
gDropdownItemsFormat[13] = STR_UPDATE_AVAILABLE;
numItems += 2;
gDropdownItemsFormat[numItems++] = STR_EMPTY;
gDropdownItemsFormat[numItems++] = STR_UPDATE_AVAILABLE;
}
}
WindowDropdownShowText(
@ -582,6 +587,15 @@ static void window_top_toolbar_dropdown(rct_window* w, rct_widgetindex widgetInd
case DDIDX_GIANT_SCREENSHOT:
screenshot_giant();
break;
case DDIDX_FILE_BUG_ON_GITHUB:
{
std::string url = "https://github.com/OpenRCT2/OpenRCT2/issues/"
"new?assignees=&labels=bug&template=bug_report.yaml";
auto versionStr = String::URLEncode(gVersionInfoFull);
url.append("&openrct2_build=" + versionStr);
OpenRCT2::GetContext()->GetUiContext()->OpenURL(url);
}
break;
case DDIDX_QUIT_TO_MENU:
{
window_close_by_class(WC_MANAGE_TRACK_DESIGN);
@ -661,13 +675,24 @@ static void window_top_toolbar_invalidate(rct_window* w)
window_top_toolbar_widgets[WIDX_NETWORK].type = WindowWidgetType::TrnBtn;
if (!gConfigInterface.toolbar_show_mute)
{
window_top_toolbar_widgets[WIDX_MUTE].type = WindowWidgetType::Empty;
}
if (!gConfigInterface.toolbar_show_chat)
{
window_top_toolbar_widgets[WIDX_CHAT].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_research)
window_top_toolbar_widgets[WIDX_RESEARCH].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_cheats)
window_top_toolbar_widgets[WIDX_CHEATS].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_news)
window_top_toolbar_widgets[WIDX_NEWS].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_zoom)
{
window_top_toolbar_widgets[WIDX_ZOOM_IN].type = WindowWidgetType::Empty;
window_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WindowWidgetType::Empty;
}
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR || gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)
@ -675,6 +700,9 @@ static void window_top_toolbar_invalidate(rct_window* w)
window_top_toolbar_widgets[WIDX_PAUSE].type = WindowWidgetType::Empty;
}
if ((gParkFlags & PARK_FLAGS_NO_MONEY) || !gConfigInterface.toolbar_show_finances)
window_top_toolbar_widgets[WIDX_FINANCES].type = WindowWidgetType::Empty;
if (gScreenFlags & SCREEN_FLAGS_EDITOR)
{
window_top_toolbar_widgets[WIDX_PARK].type = WindowWidgetType::Empty;
@ -711,39 +739,19 @@ static void window_top_toolbar_invalidate(rct_window* w)
window_top_toolbar_widgets[WIDX_VIEW_MENU].type = WindowWidgetType::Empty;
}
}
else
switch (network_get_mode())
{
if ((gParkFlags & PARK_FLAGS_NO_MONEY) || !gConfigInterface.toolbar_show_finances)
window_top_toolbar_widgets[WIDX_FINANCES].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_research)
window_top_toolbar_widgets[WIDX_RESEARCH].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_cheats)
window_top_toolbar_widgets[WIDX_CHEATS].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_news)
window_top_toolbar_widgets[WIDX_NEWS].type = WindowWidgetType::Empty;
if (!gConfigInterface.toolbar_show_zoom)
{
window_top_toolbar_widgets[WIDX_ZOOM_IN].type = WindowWidgetType::Empty;
window_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WindowWidgetType::Empty;
}
switch (network_get_mode())
{
case NETWORK_MODE_NONE:
window_top_toolbar_widgets[WIDX_NETWORK].type = WindowWidgetType::Empty;
window_top_toolbar_widgets[WIDX_CHAT].type = WindowWidgetType::Empty;
break;
case NETWORK_MODE_CLIENT:
window_top_toolbar_widgets[WIDX_PAUSE].type = WindowWidgetType::Empty;
[[fallthrough]];
case NETWORK_MODE_SERVER:
window_top_toolbar_widgets[WIDX_FASTFORWARD].type = WindowWidgetType::Empty;
break;
}
case NETWORK_MODE_NONE:
window_top_toolbar_widgets[WIDX_NETWORK].type = WindowWidgetType::Empty;
window_top_toolbar_widgets[WIDX_CHAT].type = WindowWidgetType::Empty;
break;
case NETWORK_MODE_CLIENT:
window_top_toolbar_widgets[WIDX_PAUSE].type = WindowWidgetType::Empty;
[[fallthrough]];
case NETWORK_MODE_SERVER:
window_top_toolbar_widgets[WIDX_FASTFORWARD].type = WindowWidgetType::Empty;
break;
}
enabledWidgets = 0;
@ -1233,7 +1241,7 @@ static void sub_6E1F34_small_scenery(
if (w == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1259,12 +1267,12 @@ static void sub_6E1F34_small_scenery(
if (!gSceneryCtrlPressed)
{
auto gridCoords = screen_get_map_xy_quadrant(screenPos, &quadrant);
if (!gridCoords)
if (!gridCoords.has_value())
{
gridPos.setNull();
gridPos.SetNull();
return;
}
gridPos = *gridCoords;
gridPos = gridCoords.value();
gSceneryPlaceZ = 0;
@ -1275,7 +1283,7 @@ static void sub_6E1F34_small_scenery(
if (surfaceElement == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1292,12 +1300,12 @@ static void sub_6E1F34_small_scenery(
int16_t z = gSceneryCtrlPressZ;
auto mapCoords = screen_get_map_xy_quadrant_with_z(screenPos, z, &quadrant);
if (!mapCoords)
if (!mapCoords.has_value())
{
gridPos.setNull();
gridPos.SetNull();
return;
}
gridPos = *mapCoords;
gridPos = mapCoords.value();
// If SHIFT pressed
if (gSceneryShiftPressed)
@ -1310,7 +1318,7 @@ static void sub_6E1F34_small_scenery(
gSceneryPlaceZ = z;
}
if (gridPos.isNull())
if (gridPos.IsNull())
return;
uint8_t rotation = gWindowSceneryRotation;
@ -1344,7 +1352,7 @@ static void sub_6E1F34_small_scenery(
if (info.SpriteType == ViewportInteractionItem::None)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1358,7 +1366,7 @@ static void sub_6E1F34_small_scenery(
if (surfaceElement == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1374,13 +1382,13 @@ static void sub_6E1F34_small_scenery(
{
int16_t z = gSceneryCtrlPressZ;
auto coords = screen_get_map_xy_with_z(screenPos, z);
if (coords)
if (coords.has_value())
{
gridPos = *coords;
}
else
{
gridPos.setNull();
gridPos.SetNull();
}
// If SHIFT pressed
if (gSceneryShiftPressed)
@ -1393,7 +1401,7 @@ static void sub_6E1F34_small_scenery(
gSceneryPlaceZ = z;
}
if (gridPos.isNull())
if (gridPos.IsNull())
return;
gridPos = gridPos.ToTileStart();
@ -1423,7 +1431,7 @@ static void sub_6E1F34_path_item(
if (w == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1437,7 +1445,7 @@ static void sub_6E1F34_path_item(
if (info.SpriteType == ViewportInteractionItem::None)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1456,7 +1464,7 @@ static void sub_6E1F34_wall(
if (w == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1477,12 +1485,12 @@ static void sub_6E1F34_wall(
if (!gSceneryCtrlPressed)
{
auto gridCoords = screen_get_map_xy_side(screenPos, &edge);
if (!gridCoords)
if (!gridCoords.has_value())
{
gridPos.setNull();
gridPos.SetNull();
return;
}
gridPos = *gridCoords;
gridPos = gridCoords.value();
gSceneryPlaceZ = 0;
@ -1493,7 +1501,7 @@ static void sub_6E1F34_wall(
if (surfaceElement == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1509,12 +1517,12 @@ static void sub_6E1F34_wall(
{
int16_t z = gSceneryCtrlPressZ;
auto mapCoords = screen_get_map_xy_side_with_z(screenPos, z, &edge);
if (!mapCoords)
if (!mapCoords.has_value())
{
gridPos.setNull();
gridPos.SetNull();
return;
}
gridPos = *mapCoords;
gridPos = mapCoords.value();
// If SHIFT pressed
if (gSceneryShiftPressed)
@ -1527,7 +1535,7 @@ static void sub_6E1F34_wall(
gSceneryPlaceZ = z;
}
if (gridPos.isNull())
if (gridPos.IsNull())
return;
if (gConfigGeneral.virtual_floor_style != VirtualFloorStyles::Off)
@ -1545,7 +1553,7 @@ static void sub_6E1F34_large_scenery(
if (w == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1572,7 +1580,7 @@ static void sub_6E1F34_large_scenery(
const CoordsXY mapCoords = ViewportInteractionGetTileStartAtCursor(screenPos);
gridPos = mapCoords;
if (gridPos.isNull())
if (gridPos.IsNull())
return;
gSceneryPlaceZ = 0;
@ -1584,7 +1592,7 @@ static void sub_6E1F34_large_scenery(
if (surfaceElement == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1600,13 +1608,13 @@ static void sub_6E1F34_large_scenery(
{
int16_t z = gSceneryCtrlPressZ;
auto coords = screen_get_map_xy_with_z(screenPos, z);
if (coords)
if (coords.has_value())
{
gridPos = *coords;
}
else
{
gridPos.setNull();
gridPos.SetNull();
}
// If SHIFT pressed
@ -1620,7 +1628,7 @@ static void sub_6E1F34_large_scenery(
gSceneryPlaceZ = z;
}
if (gridPos.isNull())
if (gridPos.IsNull())
return;
gridPos = gridPos.ToTileStart();
@ -1645,7 +1653,7 @@ static void sub_6E1F34_banner(
if (w == nullptr)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1659,7 +1667,7 @@ static void sub_6E1F34_banner(
if (info.SpriteType == ViewportInteractionItem::None)
{
gridPos.setNull();
gridPos.SetNull();
return;
}
@ -1718,7 +1726,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
uint8_t quadrant;
Direction rotation;
sub_6E1F34_small_scenery(windowPos, selectedScenery, gridPos, &quadrant, &rotation);
if (gridPos.isNull())
if (gridPos.IsNull())
return;
int32_t quantity = 1;
@ -1838,7 +1846,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
{
int32_t z;
sub_6E1F34_path_item(windowPos, selectedScenery, gridPos, &z);
if (gridPos.isNull())
if (gridPos.IsNull())
return;
auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction({ gridPos, z }, selectedScenery + 1);
@ -1857,7 +1865,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
{
uint8_t edges;
sub_6E1F34_wall(windowPos, selectedScenery, gridPos, &edges);
if (gridPos.isNull())
if (gridPos.IsNull())
return;
uint8_t zAttemptRange = 1;
@ -1909,7 +1917,7 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
{
Direction direction;
sub_6E1F34_large_scenery(windowPos, selectedScenery, gridPos, &direction);
if (gridPos.isNull())
if (gridPos.IsNull())
return;
uint8_t zAttemptRange = 1;
@ -1967,17 +1975,18 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
int32_t z;
Direction direction;
sub_6E1F34_banner(windowPos, selectedScenery, gridPos, &z, &direction);
if (gridPos.isNull())
if (gridPos.IsNull())
return;
CoordsXYZD loc{ gridPos, z, direction };
auto primaryColour = gWindowSceneryPrimaryColour;
auto bannerPlaceAction = BannerPlaceAction(loc, selectedScenery, primaryColour);
bannerPlaceAction.SetCallback([=](const GameAction* ga, const BannerPlaceActionResult* result) {
bannerPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
if (result->Error == GameActions::Status::Ok)
{
auto data = result->GetData<BannerPlaceActionResult>();
OpenRCT2::Audio::Play3D(OpenRCT2::Audio::SoundId::PlaceItem, result->Position);
context_open_detail_window(WD_BANNER, result->bannerId);
context_open_detail_window(WD_BANNER, data.bannerId);
}
});
GameActions::Execute(&bannerPlaceAction);
@ -1995,7 +2004,7 @@ static uint8_t top_toolbar_tool_update_land_paint(const ScreenCoordsXY& screenPo
auto mapTile = screen_get_map_xy(screenPos, nullptr);
if (!mapTile)
if (!mapTile.has_value())
{
if (gClearSceneryCost != MONEY64_UNDEFINED)
{
@ -2114,7 +2123,7 @@ static void top_toolbar_tool_update_land(const ScreenCoordsXY& screenPos)
screen_pos_to_map_pos(screenPos, &selectionType);
mapTile = screen_get_map_xy_side(screenPos, &side);
if (!mapTile)
if (!mapTile.has_value())
{
money64 lower_cost = MONEY64_UNDEFINED;
money64 raise_cost = MONEY64_UNDEFINED;
@ -2191,7 +2200,7 @@ static void top_toolbar_tool_update_land(const ScreenCoordsXY& screenPos)
// Get map coordinates and the side of the tile that is being hovered over
mapTile = screen_get_map_xy_side(screenPos, &side);
if (!mapTile)
if (!mapTile.has_value())
{
money64 lower_cost = MONEY64_UNDEFINED;
money64 raise_cost = MONEY64_UNDEFINED;
@ -2623,7 +2632,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
sub_6E1F34_small_scenery(screenPos, selection.EntryIndex, mapTile, &quadrant, &rotation);
if (mapTile.isNull())
if (mapTile.IsNull())
{
scenery_remove_ghost_tool_placement();
return;
@ -2701,7 +2710,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
sub_6E1F34_path_item(screenPos, selection.EntryIndex, mapTile, &z);
if (mapTile.isNull())
if (mapTile.IsNull())
{
scenery_remove_ghost_tool_placement();
return;
@ -2736,7 +2745,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
sub_6E1F34_wall(screenPos, selection.EntryIndex, mapTile, &edge);
if (mapTile.isNull())
if (mapTile.IsNull())
{
scenery_remove_ghost_tool_placement();
return;
@ -2791,7 +2800,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
sub_6E1F34_large_scenery(screenPos, selection.EntryIndex, mapTile, &direction);
if (mapTile.isNull())
if (mapTile.IsNull())
{
scenery_remove_ghost_tool_placement();
return;
@ -2858,7 +2867,7 @@ static void top_toolbar_tool_update_scenery(const ScreenCoordsXY& screenPos)
sub_6E1F34_banner(screenPos, selection.EntryIndex, mapTile, &z, &direction);
if (mapTile.isNull())
if (mapTile.IsNull())
{
scenery_remove_ghost_tool_placement();
return;

View File

@ -152,7 +152,7 @@ rct_window* window_track_place_open(const track_design_file_ref* tdFileRef)
window_push_others_right(w);
show_gridlines();
_window_track_place_last_cost = MONEY32_UNDEFINED;
_windowTrackPlaceLast.setNull();
_windowTrackPlaceLast.SetNull();
_currentTrackPieceDirection = (2 - get_current_rotation()) & 3;
window_track_place_clear_mini_preview();
@ -193,14 +193,14 @@ static void window_track_place_mouseup(rct_window* w, rct_widgetindex widgetInde
window_track_place_clear_provisional();
_currentTrackPieceDirection = (_currentTrackPieceDirection + 1) & 3;
w->Invalidate();
_windowTrackPlaceLast.setNull();
_windowTrackPlaceLast.SetNull();
window_track_place_draw_mini_preview(_trackDesign.get());
break;
case WIDX_MIRROR:
track_design_mirror(_trackDesign.get());
_currentTrackPieceDirection = (0 - _currentTrackPieceDirection) & 3;
w->Invalidate();
_windowTrackPlaceLast.setNull();
_windowTrackPlaceLast.SetNull();
window_track_place_draw_mini_preview(_trackDesign.get());
break;
case WIDX_SELECT_DIFFERENT_DESIGN:
@ -259,7 +259,7 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI
// Get the tool map position
CoordsXY mapCoords = ViewportInteractionGetTileStartAtCursor(screenCoords);
if (mapCoords.isNull())
if (mapCoords.IsNull())
{
window_track_place_clear_provisional();
return;
@ -268,7 +268,8 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI
// Check if tool map position has changed since last update
if (mapCoords == _windowTrackPlaceLast)
{
place_virtual_track(_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(0), { mapCoords, 0 });
place_virtual_track(
_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(PreviewRideId), { mapCoords, 0 });
return;
}
@ -308,7 +309,7 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI
widget_invalidate(w, WIDX_PRICE);
}
place_virtual_track(_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(0), trackLoc);
place_virtual_track(_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(PreviewRideId), trackLoc);
}
/**
@ -324,7 +325,7 @@ static void window_track_place_tooldown(rct_window* w, rct_widgetindex widgetInd
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
const CoordsXY mapCoords = ViewportInteractionGetTileStartAtCursor(screenCoords);
if (mapCoords.isNull())
if (mapCoords.IsNull())
return;
// Try increasing Z until a feasible placement is found
@ -348,7 +349,7 @@ static void window_track_place_tooldown(rct_window* w, rct_widgetindex widgetInd
if (track_design_are_entrance_and_exit_placed())
{
auto intent = Intent(WC_RIDE);
intent.putExtra(INTENT_EXTRA_RIDE_ID, result->rideIndex);
intent.putExtra(INTENT_EXTRA_RIDE_ID, static_cast<int32_t>(result->rideIndex));
context_open_intent(&intent);
auto wnd = window_find_by_class(WC_TRACK_DESIGN_PLACE);
window_close(wnd);
@ -469,7 +470,9 @@ static int32_t window_track_place_get_base_z(const CoordsXY& loc)
if (surfaceElement->GetWaterHeight() > 0)
z = std::max(z, surfaceElement->GetWaterHeight());
return z + place_virtual_track(_trackDesign.get(), PTD_OPERATION_GET_PLACE_Z, true, GetOrAllocateRide(0), { loc, z });
return z
+ place_virtual_track(
_trackDesign.get(), PTD_OPERATION_GET_PLACE_Z, true, GetOrAllocateRide(PreviewRideId), { loc, z });
}
/**

View File

@ -303,12 +303,12 @@ static void window_view_clipping_tool_update(rct_window* w, rct_widgetindex widg
int32_t direction;
auto mapCoords = screen_pos_to_map_pos(screenCoords, &direction);
if (mapCoords)
if (mapCoords.has_value())
{
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
map_invalidate_tile_full(gMapSelectPositionA);
gMapSelectPositionA = gMapSelectPositionB = *mapCoords;
map_invalidate_tile_full(*mapCoords);
gMapSelectPositionA = gMapSelectPositionB = mapCoords.value();
map_invalidate_tile_full(mapCoords.value());
gMapSelectType = MAP_SELECT_TYPE_FULL;
}
}
@ -317,10 +317,10 @@ static void window_view_clipping_tool_down(rct_window* w, rct_widgetindex widget
{
int32_t direction;
auto mapCoords = screen_pos_to_map_pos(screenCoords, &direction);
if (mapCoords)
if (mapCoords.has_value())
{
_dragging = true;
_selectionStart = *mapCoords;
_selectionStart = mapCoords.value();
}
}

View File

@ -47,7 +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();
void WindowFootpathResetSelectedPath();
rct_window* window_guest_open(Peep* peep);
rct_window* window_land_open();
rct_window* window_land_rights_open();

View File

@ -545,7 +545,7 @@ int32_t cmdline_for_sprite(const char** argv, int32_t argc)
}
auto importResult = SpriteImageImport(imagePath, x_offset, y_offset, false, false, gSpriteMode);
if (importResult == std::nullopt)
if (!importResult.has_value())
return -1;
auto spriteFile = SpriteFile::Open(spriteFilePath);

View File

@ -149,11 +149,11 @@ void setup_in_use_selection_flags()
case TILE_ELEMENT_TYPE_PATH:
{
auto footpathEl = iter.element->AsPath();
auto legacyPathEntryIndex = footpathEl->GetPathEntryIndex();
auto legacyPathEntryIndex = footpathEl->GetLegacyPathEntryIndex();
if (legacyPathEntryIndex == OBJECT_ENTRY_INDEX_NULL)
{
auto surfaceEntryIndex = footpathEl->GetSurfaceEntryIndex();
auto railingEntryIndex = footpathEl->GetRailingEntryIndex();
auto railingEntryIndex = footpathEl->GetRailingsEntryIndex();
Editor::SetSelectedObject(ObjectType::FootpathSurface, surfaceEntryIndex, OBJECT_SELECTION_FLAG_SELECTED);
Editor::SetSelectedObject(ObjectType::FootpathRailings, railingEntryIndex, OBJECT_SELECTION_FLAG_SELECTED);
}
@ -184,7 +184,7 @@ void setup_in_use_selection_flags()
if (parkEntranceEl->GetSequenceIndex() != 0)
break;
auto legacyPathEntryIndex = parkEntranceEl->GetPathEntryIndex();
auto legacyPathEntryIndex = parkEntranceEl->GetLegacyPathEntryIndex();
if (legacyPathEntryIndex == OBJECT_ENTRY_INDEX_NULL)
{
auto surfaceEntryIndex = parkEntranceEl->GetSurfaceEntryIndex();
@ -217,15 +217,11 @@ void setup_in_use_selection_flags()
}
} while (tile_element_iterator_next(&iter));
for (ride_id_t ride_index = 0; ride_index < MAX_RIDES; ride_index++)
for (auto& ride : GetRideManager())
{
auto ride = get_ride(ride_index);
if (ride != nullptr)
{
Editor::SetSelectedObject(ObjectType::Ride, ride->subtype, OBJECT_SELECTION_FLAG_SELECTED);
Editor::SetSelectedObject(ObjectType::Station, ride->entrance_style, OBJECT_SELECTION_FLAG_SELECTED);
Editor::SetSelectedObject(ObjectType::Music, ride->music, OBJECT_SELECTION_FLAG_SELECTED);
}
Editor::SetSelectedObject(ObjectType::Ride, ride.subtype, OBJECT_SELECTION_FLAG_SELECTED);
Editor::SetSelectedObject(ObjectType::Station, ride.entrance_style, OBJECT_SELECTION_FLAG_SELECTED);
Editor::SetSelectedObject(ObjectType::Music, ride.music, OBJECT_SELECTION_FLAG_SELECTED);
}
// Apply selected object status for hacked vehicles that may not have an associated ride
@ -289,7 +285,7 @@ void sub_6AB211()
const ObjectRepositoryItem* items = object_repository_get_items();
for (int32_t i = 0; i < numObjects; i++)
{
auto objectType = items[i].Type;
ObjectType objectType = items[i].Type;
_numAvailableObjectsForType[EnumValue(objectType)]++;
}
@ -431,6 +427,7 @@ static void ReplaceSelectedWaterPalette(const ObjectRepositoryItem* item)
{
auto& objectManager = OpenRCT2::GetContext()->GetObjectManager();
auto* oldPalette = objectManager.GetLoadedObject(ObjectType::Water, 0);
if (oldPalette != nullptr)
{
const std::vector<ObjectEntryDescriptor> oldEntries = { oldPalette->GetDescriptor() };
@ -463,7 +460,7 @@ void reset_selected_object_count_and_size()
const ObjectRepositoryItem* items = object_repository_get_items();
for (int32_t i = 0; i < numObjects; i++)
{
auto objectType = items[i].Type;
ObjectType objectType = items[i].Type;
if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)
{
_numSelectedObjectsForType[EnumValue(objectType)]++;

View File

@ -851,7 +851,7 @@ namespace OpenRCT2
}
// Focus camera on event.
if (isPositionValid && !result->Position.isNull())
if (isPositionValid && !result->Position.IsNull())
{
auto* mainWindow = window_get_main();
if (mainWindow != nullptr)

View File

@ -18,26 +18,6 @@
using namespace OpenRCT2;
BannerPlaceActionResult::BannerPlaceActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_POSITION_THIS_HERE)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err)
: GameActions::Result(err, STR_CANT_POSITION_THIS_HERE)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err, rct_string_id msg)
: GameActions::Result(err, STR_CANT_POSITION_THIS_HERE, msg)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err, rct_string_id title, rct_string_id message)
: GameActions::Result(err, title, message)
{
}
BannerPlaceAction::BannerPlaceAction(const CoordsXYZD& loc, ObjectEntryIndex bannerType, colour_t primaryColour)
: _loc(loc)
, _bannerType(bannerType)
@ -117,6 +97,7 @@ GameActions::Result::Ptr BannerPlaceAction::Query() const
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE);
}
res->Cost = bannerEntry->price;
return res;
}
@ -155,8 +136,7 @@ GameActions::Result::Ptr BannerPlaceAction::Execute() const
banner->colour = _primaryColour;
banner->position = TileCoordsXY(_loc);
res->bannerId = banner->id;
res->SetData(BannerPlaceActionResult{ banner->id });
auto* bannerElement = TileElementInsert<BannerElement>({ _loc, _loc.z + (2 * COORDS_Z_STEP) }, 0b0000);
Guard::Assert(bannerElement != nullptr);

View File

@ -11,18 +11,12 @@
#include "GameAction.h"
class BannerPlaceActionResult final : public GameActions::Result
struct BannerPlaceActionResult
{
public:
BannerPlaceActionResult();
BannerPlaceActionResult(GameActions::Status err);
BannerPlaceActionResult(GameActions::Status err, rct_string_id msg);
BannerPlaceActionResult(GameActions::Status err, rct_string_id title, rct_string_id message);
BannerIndex bannerId = BANNER_INDEX_NULL;
};
DEFINE_GAME_ACTION(BannerPlaceAction, GameCommand::PlaceBanner, BannerPlaceActionResult)
DEFINE_GAME_ACTION(BannerPlaceAction, GameCommand::PlaceBanner, GameActions::Result)
{
private:
CoordsXYZD _loc;

View File

@ -162,23 +162,23 @@ bool FootpathPlaceAction::IsSameAsPathElement(const PathElement* pathElement) co
if (pathElement->IsQueue() != ((_constructFlags & PathConstructFlag::IsQueue) != 0))
return false;
auto footpathObj = pathElement->GetPathEntry();
auto footpathObj = pathElement->GetLegacyPathEntry();
if (footpathObj == nullptr)
{
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return false;
}
else
{
return pathElement->GetSurfaceEntryIndex() == _type && pathElement->GetRailingEntryIndex() == _railingsType;
return pathElement->GetSurfaceEntryIndex() == _type && pathElement->GetRailingsEntryIndex() == _railingsType;
}
}
else
{
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return pathElement->GetPathEntryIndex() == _type;
return pathElement->GetLegacyPathEntryIndex() == _type;
}
else
{
@ -187,6 +187,30 @@ bool FootpathPlaceAction::IsSameAsPathElement(const PathElement* pathElement) co
}
}
bool FootpathPlaceAction::IsSameAsEntranceElement(const EntranceElement& entranceElement) const
{
if (entranceElement.HasLegacyPathEntry())
{
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return entranceElement.GetLegacyPathEntryIndex() == _type;
}
else
{
return false;
}
}
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return false;
}
else
{
return entranceElement.GetSurfaceEntryIndex() == _type;
}
}
GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateQuery(PathElement* pathElement, GameActions::Result::Ptr res) const
{
if (!IsSameAsPathElement(pathElement))
@ -215,14 +239,14 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement*
footpath_remove_edges_at(_loc, reinterpret_cast<TileElement*>(pathElement));
}
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
pathElement->SetPathEntryIndex(_type);
pathElement->SetLegacyPathEntryIndex(_type);
}
else
{
pathElement->SetSurfaceEntryIndex(_type);
pathElement->SetRailingEntryIndex(_railingsType);
pathElement->SetRailingsEntryIndex(_railingsType);
}
pathElement->SetIsQueue((_constructFlags & PathConstructFlag::IsQueue) != 0);
@ -280,7 +304,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertQuery(GameActions::Re
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetSurfaceEntryIndex() == _type)
if (IsSameAsEntranceElement(*entranceElement))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -346,7 +370,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetSurfaceEntryIndex() == _type)
if (IsSameAsEntranceElement(*entranceElement))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -380,9 +404,9 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
{
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
entranceElement->SetPathEntryIndex(_type);
entranceElement->SetLegacyPathEntryIndex(_type);
}
else
{
@ -397,14 +421,14 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
Guard::Assert(pathElement != nullptr);
pathElement->SetClearanceZ(zHigh);
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
pathElement->SetPathEntryIndex(_type);
pathElement->SetLegacyPathEntryIndex(_type);
}
else
{
pathElement->SetSurfaceEntryIndex(_type);
pathElement->SetRailingEntryIndex(_railingsType);
pathElement->SetRailingsEntryIndex(_railingsType);
}
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);

View File

@ -27,7 +27,6 @@ public:
FootpathPlaceAction(
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType,
Direction direction = INVALID_DIRECTION, PathConstructFlags constructFlags = 0);
void AcceptParameters(GameActionParameterVisitor & visitor) override;
uint16_t GetActionFlags() const override;
@ -45,4 +44,5 @@ private:
void RemoveIntersectingWalls(PathElement * pathElement) const;
PathElement* map_get_footpath_element_slope(const CoordsXYZ& footpathPos, int32_t slope) const;
bool IsSameAsPathElement(const PathElement* pathElement) const;
bool IsSameAsEntranceElement(const EntranceElement& entranceElement) const;
};

View File

@ -126,7 +126,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertQuery(GameAc
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetSurfaceEntryIndex() == _type)
if (IsSameAsEntranceElement(*entranceElement))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -193,7 +193,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetSurfaceEntryIndex() == _type)
if (IsSameAsEntranceElement(*entranceElement))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -226,9 +226,9 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
{
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
entranceElement->SetPathEntryIndex(_type);
entranceElement->SetLegacyPathEntryIndex(_type);
}
else
{
@ -243,14 +243,14 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
Guard::Assert(pathElement != nullptr);
pathElement->SetClearanceZ(zHigh);
if (_constructFlags & PathConstructFlag::IsPathObject)
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
pathElement->SetPathEntryIndex(_type);
pathElement->SetLegacyPathEntryIndex(_type);
}
else
{
pathElement->SetSurfaceEntryIndex(_type);
pathElement->SetRailingEntryIndex(_railingsType);
pathElement->SetRailingsEntryIndex(_railingsType);
}
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
@ -272,3 +272,27 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
return res;
}
bool FootpathPlaceFromTrackAction::IsSameAsEntranceElement(const EntranceElement& entranceElement) const
{
if (entranceElement.HasLegacyPathEntry())
{
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return entranceElement.GetLegacyPathEntryIndex() == _type;
}
else
{
return false;
}
}
if (_constructFlags & PathConstructFlag::IsLegacyPathObject)
{
return false;
}
else
{
return entranceElement.GetSurfaceEntryIndex() == _type;
}
}

View File

@ -36,4 +36,5 @@ public:
private:
GameActions::Result::Ptr ElementInsertQuery(GameActions::Result::Ptr res) const;
GameActions::Result::Ptr ElementInsertExecute(GameActions::Result::Ptr res) const;
bool IsSameAsEntranceElement(const EntranceElement& entranceElement) const;
};

View File

@ -492,7 +492,7 @@ namespace GameActions
network_add_player_money_spent(playerIndex, result->Cost);
}
if (!result->Position.isNull())
if (!result->Position.IsNull())
{
network_set_player_last_action_coord(playerIndex, result->Position);
}

View File

@ -16,6 +16,7 @@
#include "../localisation/StringIds.h"
#include "../world/Map.h"
#include <any>
#include <array>
#include <functional>
#include <memory>
@ -130,6 +131,7 @@ namespace GameActions
CoordsXYZ Position = { LOCATION_NULL, LOCATION_NULL, LOCATION_NULL };
money32 Cost = 0;
ExpenditureType Expenditure = ExpenditureType::Count;
std::any ResultData;
Result() = default;
Result(GameActions::Status error, rct_string_id message);
@ -140,6 +142,19 @@ namespace GameActions
std::string GetErrorTitle() const;
std::string GetErrorMessage() const;
// It is recommended to use strong types since a type alias such as 'using MyType = uint32_t'
// is still just uint32_t, this guarantees the data is associated with the correct type.
template<typename T> void SetData(const T&& data)
{
ResultData = std::forward<const T&&>(data);
}
// This function will throw std::bad_any_cast if the type mismatches.
template<typename T> T GetData() const
{
return std::any_cast<T>(ResultData);
}
};
class ConstructClearResult final : public Result

View File

@ -293,7 +293,7 @@ GameActions::Result::Ptr MazeSetTrackAction::Execute() const
if ((tileElement->AsTrack()->GetMazeEntry() & 0x8888) == 0x8888)
{
tile_element_remove(tileElement);
sub_6CB945(ride);
ride->ValidateStations();
ride->maze_tiles--;
}

View File

@ -70,7 +70,7 @@ GameActions::Result::Ptr ParkMarketingAction::Execute() const
campaign.Flags = MarketingCampaignFlags::FIRST_WEEK;
if (campaign.Type == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign.Type == ADVERTISING_CAMPAIGN_RIDE)
{
campaign.RideId = _item;
campaign.RideId = static_cast<ride_id_t>(_item);
}
else if (campaign.Type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
{

View File

@ -43,7 +43,7 @@ GameActions::Result::Ptr PeepPickupAction::Query() const
return MakeResult(GameActions::Status::InvalidParameters, STR_ERR_CANT_PLACE_PERSON_HERE);
}
if (!_loc.isNull() && !LocationValid(_loc))
if (!_loc.IsNull() && !LocationValid(_loc))
{
return MakeResult(GameActions::Status::InvalidParameters, STR_ERR_CANT_PLACE_PERSON_HERE);
}

View File

@ -152,7 +152,7 @@ GameActions::Result::Ptr PlaceParkEntranceAction::Execute() const
}
else
{
entranceElement->SetPathEntryIndex(gFootpathSelection.LegacyPath);
entranceElement->SetLegacyPathEntryIndex(gFootpathSelection.LegacyPath);
}
if (!entranceElement->IsGhost())

View File

@ -140,12 +140,12 @@ GameActions::Result::Ptr RideCreateAction::Execute() const
ride->type = _rideType;
ride->subtype = rideEntryIndex;
ride->SetColourPreset(_colour1);
ride->overall_view.setNull();
ride->overall_view.SetNull();
ride->SetNameToDefault();
for (int32_t i = 0; i < MAX_STATIONS; i++)
{
ride->stations[i].Start.setNull();
ride->stations[i].Start.SetNull();
ride_clear_entrance_location(ride, i);
ride_clear_exit_location(ride, i);
ride->stations[i].TrainAtStation = RideStation::NO_TRAIN;

View File

@ -129,16 +129,18 @@ GameActions::Result::Ptr RideDemolishAction::DemolishRide(Ride* ride) const
ride_remove_peeps(ride);
ride->StopGuestsQueuing();
sub_6CB945(ride);
ride->ValidateStations();
ride_clear_leftover_entrances(ride);
News::DisableNewsItems(News::ItemType::Ride, _rideIndex);
UnlinkAllBannersForRide(_rideIndex);
const auto rideId = ride->id;
News::DisableNewsItems(News::ItemType::Ride, EnumValue(rideId));
RideUse::GetHistory().RemoveValue(_rideIndex);
UnlinkAllBannersForRide(ride->id);
RideUse::GetHistory().RemoveValue(ride->id);
for (auto peep : EntityList<Guest>())
{
peep->RemoveRideFromMemory(_rideIndex);
peep->RemoveRideFromMemory(ride->id);
}
MarketingCancelCampaignsForRide(_rideIndex);
@ -147,7 +149,7 @@ GameActions::Result::Ptr RideDemolishAction::DemolishRide(Ride* ride) const
res->Expenditure = ExpenditureType::RideConstruction;
res->Cost = refundPrice;
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto xy = ride->overall_view.ToTileCentre();
res->Position = { xy, tile_element_height(xy) };
@ -157,9 +159,9 @@ GameActions::Result::Ptr RideDemolishAction::DemolishRide(Ride* ride) const
gParkValue = GetContext()->GetGameState()->GetPark().CalculateParkValue();
// Close windows related to the demolished ride
window_close_by_number(WC_RIDE_CONSTRUCTION, _rideIndex);
window_close_by_number(WC_RIDE, _rideIndex);
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, _rideIndex);
window_close_by_number(WC_RIDE_CONSTRUCTION, EnumValue(rideId));
window_close_by_number(WC_RIDE, EnumValue(rideId));
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, EnumValue(rideId));
window_close_by_class(WC_NEW_CAMPAIGN);
// Refresh windows that display the ride name
@ -266,13 +268,13 @@ GameActions::Result::Ptr RideDemolishAction::RefurbishRide(Ride* ride) const
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE | RIDE_INVALIDATE_RIDE_CUSTOMER;
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(location) };
}
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, _rideIndex);
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, EnumValue(_rideIndex));
return res;
}

View File

@ -54,7 +54,7 @@ GameActions::Result::Ptr RideEntranceExitPlaceAction::Query() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid game command for ride %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid game command for ride %d", EnumValue(_rideIndex));
return MakeResult(GameActions::Status::InvalidParameters, errorTitle);
}
@ -76,7 +76,7 @@ GameActions::Result::Ptr RideEntranceExitPlaceAction::Query() const
const auto location = _isExit ? ride_get_exit_location(ride, _stationNum) : ride_get_entrance_location(ride, _stationNum);
if (!location.isNull())
if (!location.IsNull())
{
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(location.ToCoordsXY(), _rideIndex, _stationNum, _isExit);
rideEntranceExitRemove.SetFlags(GetFlags());
@ -132,7 +132,7 @@ GameActions::Result::Ptr RideEntranceExitPlaceAction::Execute() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid game command for ride %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid game command for ride %d", EnumValue(_rideIndex));
return MakeResult(GameActions::Status::InvalidParameters, errorTitle);
}
@ -143,7 +143,7 @@ GameActions::Result::Ptr RideEntranceExitPlaceAction::Execute() const
}
const auto location = _isExit ? ride_get_exit_location(ride, _stationNum) : ride_get_entrance_location(ride, _stationNum);
if (!location.isNull())
if (!location.IsNull())
{
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(location.ToCoordsXY(), _rideIndex, _stationNum, _isExit);
rideEntranceExitRemove.SetFlags(GetFlags());

View File

@ -74,7 +74,7 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Query() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride id %d for entrance/exit removal", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride id %d for entrance/exit removal", EnumValue(_rideIndex));
return std::make_unique<GameActions::Result>(GameActions::Status::InvalidParameters, STR_NONE);
}
@ -99,8 +99,8 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Query() const
if (entranceElement == nullptr)
{
log_warning(
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y,
static_cast<int32_t>(_rideIndex), _stationNum);
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y, EnumValue(_rideIndex),
_stationNum);
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
}
@ -112,7 +112,7 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Execute() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride id %d for entrance/exit removal", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride id %d for entrance/exit removal", EnumValue(_rideIndex));
return std::make_unique<GameActions::Result>(GameActions::Status::InvalidParameters, STR_NONE);
}
@ -130,8 +130,8 @@ GameActions::Result::Ptr RideEntranceExitRemoveAction::Execute() const
if (entranceElement == nullptr)
{
log_warning(
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y,
static_cast<int32_t>(_rideIndex), _stationNum);
"Track Element not found. x = %d, y = %d, ride = %d, station = %d", _loc.x, _loc.y, EnumValue(_rideIndex),
_stationNum);
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
}

View File

@ -139,10 +139,10 @@ GameActions::Result::Ptr RideSetAppearanceAction::Execute() const
gfx_invalidate_screen();
break;
}
window_invalidate_by_number(WC_RIDE, _rideIndex);
window_invalidate_by_number(WC_RIDE, EnumValue(_rideIndex));
auto res = std::make_unique<GameActions::Result>();
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(location) };

View File

@ -61,7 +61,7 @@ GameActions::Result::Ptr RideSetColourSchemeAction::Execute() const
res->Expenditure = ExpenditureType::RideConstruction;
res->ErrorTitle = STR_CANT_SET_COLOUR_SCHEME;
sub_6C683D(_loc, _trackType, _newColourScheme, nullptr, TRACK_ELEMENT_SET_COLOUR_SCHEME);
GetTrackElementOriginAndApplyChanges(_loc, _trackType, _newColourScheme, nullptr, TRACK_ELEMENT_SET_COLOUR_SCHEME);
return res;
}

View File

@ -87,7 +87,7 @@ GameActions::Result::Ptr RideSetPriceAction::Execute() const
return MakeResult(GameActions::Status::InvalidParameters, STR_NONE);
}
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(location) };
@ -180,7 +180,7 @@ void RideSetPriceAction::RideSetCommonPrice(ShopItem shopItem) const
}
if (invalidate)
{
window_invalidate_by_number(WC_RIDE, ride.id);
window_invalidate_by_number(WC_RIDE, EnumValue(ride.id));
}
}
}

View File

@ -45,7 +45,7 @@ GameActions::Result::Ptr RideSetSettingAction::Query() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride: #%d.", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride: #%d.", EnumValue(_rideIndex));
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CHANGE_OPERATING_MODE);
}
@ -153,7 +153,7 @@ GameActions::Result::Ptr RideSetSettingAction::Execute() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride: #%d.", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride: #%d.", EnumValue(_rideIndex));
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_CHANGE_OPERATING_MODE);
}
@ -228,12 +228,12 @@ GameActions::Result::Ptr RideSetSettingAction::Execute() const
}
auto res = std::make_unique<GameActions::Result>();
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(location) };
}
window_invalidate_by_number(WC_RIDE, _rideIndex);
window_invalidate_by_number(WC_RIDE, EnumValue(_rideIndex));
return res;
}

View File

@ -59,7 +59,7 @@ GameActions::Result::Ptr RideSetStatusAction::Query() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid game command for ride %u", uint32_t(_rideIndex));
log_warning("Invalid game command for ride %u", EnumValue(_rideIndex));
res->Error = GameActions::Status::InvalidParameters;
res->ErrorTitle = STR_RIDE_DESCRIPTION_UNKNOWN;
res->ErrorMessage = STR_NONE;
@ -68,7 +68,7 @@ GameActions::Result::Ptr RideSetStatusAction::Query() const
if (_status >= RideStatus::Count)
{
log_warning("Invalid ride status %u for ride %u", uint32_t(_status), uint32_t(_rideIndex));
log_warning("Invalid ride status %u for ride %u", EnumValue(_status), EnumValue(_rideIndex));
res->Error = GameActions::Status::InvalidParameters;
res->ErrorTitle = STR_RIDE_DESCRIPTION_UNKNOWN;
res->ErrorMessage = STR_NONE;
@ -131,7 +131,7 @@ GameActions::Result::Ptr RideSetStatusAction::Execute() const
Formatter ft(res->ErrorMessageArgs.data());
ft.Increment(6);
ride->FormatNameTo(ft);
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(location) };
@ -154,7 +154,7 @@ GameActions::Result::Ptr RideSetStatusAction::Execute() const
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
ride->race_winner = SPRITE_INDEX_NULL;
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
window_invalidate_by_number(WC_RIDE, _rideIndex);
window_invalidate_by_number(WC_RIDE, EnumValue(_rideIndex));
break;
case RideStatus::Simulating:
{
@ -176,7 +176,7 @@ GameActions::Result::Ptr RideSetStatusAction::Execute() const
ride->last_issue_time = 0;
ride->GetMeasurement();
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
window_invalidate_by_number(WC_RIDE, _rideIndex);
window_invalidate_by_number(WC_RIDE, EnumValue(_rideIndex));
break;
}
case RideStatus::Testing:
@ -195,7 +195,7 @@ GameActions::Result::Ptr RideSetStatusAction::Execute() const
// Fix #3183: Make sure we close the construction window so the ride finishes any editing code before opening
// otherwise vehicles get added to the ride incorrectly (such as to a ghost station)
rct_window* constructionWindow = window_find_by_number(WC_RIDE_CONSTRUCTION, _rideIndex);
rct_window* constructionWindow = window_find_by_number(WC_RIDE_CONSTRUCTION, EnumValue(_rideIndex));
if (constructionWindow != nullptr)
{
window_close(constructionWindow);
@ -223,7 +223,7 @@ GameActions::Result::Ptr RideSetStatusAction::Execute() const
ride->last_issue_time = 0;
ride->GetMeasurement();
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
window_invalidate_by_number(WC_RIDE, _rideIndex);
window_invalidate_by_number(WC_RIDE, EnumValue(_rideIndex));
break;
}
default:

View File

@ -192,14 +192,14 @@ GameActions::Result::Ptr RideSetVehicleAction::Execute() const
ride->UpdateMaxVehicles();
auto res = std::make_unique<GameActions::Result>();
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
auto location = ride->overall_view.ToTileCentre();
res->Position = { location, tile_element_height(res->Position) };
}
auto intent = Intent(INTENT_ACTION_RIDE_PAINT_RESET_VEHICLE);
intent.putExtra(INTENT_EXTRA_RIDE_ID, _rideIndex);
intent.putExtra(INTENT_EXTRA_RIDE_ID, EnumValue(_rideIndex));
context_broadcast_intent(&intent);
gfx_invalidate_screen();

View File

@ -9,6 +9,7 @@
#include "TrackPlaceAction.h"
#include "../core/Numerics.hpp"
#include "../management/Finance.h"
#include "../ride/RideData.h"
#include "../ride/Track.h"
@ -85,13 +86,13 @@ GameActions::Result::Ptr TrackPlaceAction::Query() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride for track placement, rideIndex = %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride for track placement, rideIndex = %d", EnumValue(_rideIndex));
return std::make_unique<TrackPlaceActionResult>(GameActions::Status::InvalidParameters, STR_NONE);
}
rct_ride_entry* rideEntry = get_ride_entry(ride->subtype);
if (rideEntry == nullptr)
{
log_warning("Invalid ride subtype for track placement, rideIndex = %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride subtype for track placement, rideIndex = %d", EnumValue(_rideIndex));
return std::make_unique<TrackPlaceActionResult>(GameActions::Status::InvalidParameters, STR_NONE);
}
@ -379,14 +380,14 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
auto ride = get_ride(_rideIndex);
if (ride == nullptr)
{
log_warning("Invalid ride for track placement, rideIndex = %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride for track placement, rideIndex = %d", EnumValue(_rideIndex));
return std::make_unique<TrackPlaceActionResult>(GameActions::Status::InvalidParameters);
}
rct_ride_entry* rideEntry = get_ride_entry(ride->subtype);
if (rideEntry == nullptr)
{
log_warning("Invalid ride subtype for track placement, rideIndex = %d", static_cast<int32_t>(_rideIndex));
log_warning("Invalid ride subtype for track placement, rideIndex = %d", EnumValue(_rideIndex));
return std::make_unique<TrackPlaceActionResult>(GameActions::Status::InvalidParameters);
}
@ -453,7 +454,7 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
// Remove walls in the directions this track intersects
uint8_t intersectingDirections = wallEdges[blockIndex];
intersectingDirections ^= 0x0F;
intersectingDirections = rol4(intersectingDirections, _origin.direction);
intersectingDirections = Numerics::rol4(intersectingDirections, _origin.direction);
for (int32_t i = 0; i < NumOrthogonalDirections; i++)
{
if (intersectingDirections & (1 << i))
@ -534,7 +535,7 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
}
int32_t entranceDirections = 0;
if (!ride->overall_view.isNull())
if (!ride->overall_view.IsNull())
{
if (!(GetFlags() & GAME_COMMAND_FLAG_NO_SPEND))
{
@ -542,7 +543,7 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
}
}
if (entranceDirections & TRACK_SEQUENCE_FLAG_ORIGIN || ride->overall_view.isNull())
if (entranceDirections & TRACK_SEQUENCE_FLAG_ORIGIN || ride->overall_view.IsNull())
{
ride->overall_view = mapLoc;
}
@ -550,7 +551,7 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
auto* trackElement = TileElementInsert<TrackElement>(mapLoc, quarterTile.GetBaseQuarterOccupied());
if (trackElement == nullptr)
{
log_warning("Cannot create track element for ride = %d", static_cast<int32_t>(_rideIndex));
log_warning("Cannot create track element for ride = %d", EnumValue(_rideIndex));
return std::make_unique<TrackPlaceActionResult>(GameActions::Status::NoFreeElements);
}
@ -629,7 +630,7 @@ GameActions::Result::Ptr TrackPlaceAction::Execute() const
{
track_add_station_element({ mapLoc, _origin.direction }, _rideIndex, GAME_COMMAND_FLAG_APPLY, _fromTrackDesign);
}
sub_6CB945(ride);
ride->ValidateStations();
ride->UpdateMaxVehicles();
}

View File

@ -426,7 +426,7 @@ GameActions::Result::Ptr TrackRemoveAction::Execute() const
footpath_remove_edges_at(mapLoc, tileElement);
}
tile_element_remove(tileElement);
sub_6CB945(ride);
ride->ValidateStations();
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
{
ride->UpdateMaxVehicles();

View File

@ -443,7 +443,7 @@ bool WallPlaceAction::WallCheckObstructionWithTrack(
return false;
}
if (TrackDefinitions[trackType].bank_start == 0)
if (ted.Definition.bank_start == 0)
{
if (!(ted.Coordinates.rotation_begin & 4))
{
@ -468,7 +468,7 @@ bool WallPlaceAction::WallCheckObstructionWithTrack(
return false;
}
if (TrackDefinitions[trackType].bank_end != 0)
if (ted.Definition.bank_end != 0)
{
return false;
}

View File

@ -19,15 +19,12 @@
#endif
#include "Diagnostic.h"
#include "core/Numerics.hpp"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
using namespace Numerics;
using utf8 = char;
using utf8string = utf8*;
using const_utf8string = const utf8*;
@ -41,15 +38,6 @@ using const_utf8string = const utf8*;
using codepoint_t = uint32_t;
using colour_t = uint8_t;
const constexpr auto rol8 = rol<uint8_t>;
const constexpr auto ror8 = ror<uint8_t>;
const constexpr auto rol16 = rol<uint16_t>;
const constexpr auto ror16 = ror<uint16_t>;
const constexpr auto rol32 = rol<uint32_t>;
const constexpr auto ror32 = ror<uint32_t>;
const constexpr auto rol64 = rol<uint64_t>;
const constexpr auto ror64 = ror<uint64_t>;
namespace
{
[[maybe_unused]] constexpr bool is_power_of_2(int v)

View File

@ -38,19 +38,23 @@ template<typename T> struct DataSerializerTraits_t
template<typename T> struct DataSerializerTraits_enum
{
using TUnderlying = std::underlying_type_t<T>;
static void encode(OpenRCT2::IStream* stream, const T& val)
{
stream->Write(&val);
TUnderlying temp = ByteSwapBE(static_cast<TUnderlying>(val));
stream->Write(&temp);
}
static void decode(OpenRCT2::IStream* stream, T& val)
{
stream->Read(&val);
TUnderlying temp;
stream->Read(&temp);
val = static_cast<T>(ByteSwapBE(temp));
}
static void log(OpenRCT2::IStream* stream, const T& val)
{
using underlying = std::underlying_type_t<T>;
std::stringstream ss;
ss << std::hex << std::setw(sizeof(underlying) * 2) << std::setfill('0') << static_cast<underlying>(val);
ss << std::hex << std::setw(sizeof(TUnderlying) * 2) << std::setfill('0') << static_cast<TUnderlying>(val);
std::string str = ss.str();
stream->Write(str.c_str(), str.size());
@ -210,39 +214,6 @@ template<> struct DataSerializerTraits_t<NetworkPlayerId_t>
}
};
template<> struct DataSerializerTraits_t<NetworkRideId_t>
{
static void encode(OpenRCT2::IStream* stream, const NetworkRideId_t& val)
{
uint32_t temp = static_cast<uint32_t>(val.id);
temp = ByteSwapBE(temp);
stream->Write(&temp);
}
static void decode(OpenRCT2::IStream* stream, NetworkRideId_t& val)
{
uint32_t temp;
stream->Read(&temp);
val.id = static_cast<decltype(val.id)>(ByteSwapBE(temp));
}
static void log(OpenRCT2::IStream* stream, const NetworkRideId_t& val)
{
char rideId[28] = {};
snprintf(rideId, sizeof(rideId), "%u", val.id);
stream->Write(rideId, strlen(rideId));
auto ride = get_ride(val.id);
if (ride != nullptr)
{
auto rideName = ride->GetName();
stream->Write(" \"", 2);
stream->Write(rideName.c_str(), rideName.size());
stream->Write("\"", 1);
}
}
};
template<typename T> struct DataSerializerTraits_t<DataSerialiserTag<T>>
{
static void encode(OpenRCT2::IStream* stream, const DataSerialiserTag<T>& tag)

View File

@ -16,6 +16,7 @@
#include "FileScanner.h"
#include "FileStream.h"
#include "JobPool.h"
#include "Numerics.hpp"
#include "Path.hpp"
#include <chrono>
@ -156,7 +157,7 @@ private:
stats.TotalFileSize += fileInfo->Size;
stats.FileDateModifiedChecksum ^= static_cast<uint32_t>(fileInfo->LastModified >> 32)
^ static_cast<uint32_t>(fileInfo->LastModified & 0xFFFFFFFF);
stats.FileDateModifiedChecksum = ror32(stats.FileDateModifiedChecksum, 5);
stats.FileDateModifiedChecksum = Numerics::ror32(stats.FileDateModifiedChecksum, 5);
stats.PathChecksum += GetPathChecksum(path);
files.push_back(std::move(path));

View File

@ -25,6 +25,7 @@
#include "FileScanner.h"
#include "Memory.hpp"
#include "Numerics.hpp"
#include "Path.hpp"
#include "String.hpp"
@ -363,7 +364,7 @@ void Path::QueryDirectory(QueryDirectoryResult* result, const std::string& patte
result->TotalFileSize += fileInfo->Size;
result->FileDateModifiedChecksum ^= static_cast<uint32_t>(fileInfo->LastModified >> 32)
^ static_cast<uint32_t>(fileInfo->LastModified & 0xFFFFFFFF);
result->FileDateModifiedChecksum = ror32(result->FileDateModifiedChecksum, 5);
result->FileDateModifiedChecksum = Numerics::ror32(result->FileDateModifiedChecksum, 5);
result->PathChecksum += GetPathChecksum(path);
}
}

View File

@ -18,7 +18,7 @@
# include <stdexcept>
# include <thread>
# ifdef _WIN32
# if defined(_WIN32) && !defined(WIN32_LEAN_AND_MEAN)
// cURL includes windows.h, but we don't need all of it.
# define WIN32_LEAN_AND_MEAN
# endif

View File

@ -1,55 +0,0 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "../common.h"
#include <cstddef>
template<typename T> struct Nullable
{
public:
Nullable()
{
_value = T();
_hasValue = false;
}
Nullable(std::nullptr_t)
{
_value = T();
_hasValue = false;
}
Nullable(const T& value)
{
_value = value;
_hasValue = true;
}
bool HasValue() const
{
return _hasValue;
}
T GetValue() const
{
return _value;
}
T GetValueOrDefault(T defaultValue) const
{
return _hasValue ? _value : defaultValue;
}
private:
T _value;
bool _hasValue;
};

View File

@ -68,4 +68,13 @@ namespace Numerics
return (x >> shift | x << (4 - shift)) & 0x0F;
}
const constexpr auto rol8 = rol<uint8_t>;
const constexpr auto ror8 = ror<uint8_t>;
const constexpr auto rol16 = rol<uint16_t>;
const constexpr auto ror16 = ror<uint16_t>;
const constexpr auto rol32 = rol<uint32_t>;
const constexpr auto ror32 = ror<uint32_t>;
const constexpr auto rol64 = rol<uint64_t>;
const constexpr auto ror64 = ror<uint64_t>;
} // namespace Numerics

View File

@ -14,7 +14,10 @@
#endif // __MINGW32__
#include <algorithm>
#include <cctype>
#include <cwctype>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <vector>
#ifndef _WIN32
@ -818,11 +821,36 @@ namespace String
{
return trunc.substr(0, i);
}
i += *length;
i += length.value();
}
return trunc;
}
std::string URLEncode(std::string_view value)
{
std::ostringstream escaped;
escaped.fill('0');
escaped << std::hex;
for (auto c : value)
{
// Keep alphanumeric and other accepted characters intact
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
{
escaped << c;
}
else
{
// Any other characters are percent-escaped
escaped << std::uppercase;
escaped << '%' << std::setw(2) << int32_t(static_cast<unsigned char>(c));
escaped << std::nouppercase;
}
}
return escaped.str();
}
} // namespace String
char32_t CodepointView::iterator::GetNextCodepoint(const char* ch, const char** next)

View File

@ -170,7 +170,7 @@ namespace String
{
return { 4 };
}
return {};
return std::nullopt;
}
/**
@ -179,6 +179,8 @@ namespace String
*/
std::string_view UTF8Truncate(std::string_view v, size_t size);
// Escapes special characters in a string to the percentage equivalent that can be used in URLs.
std::string URLEncode(std::string_view value);
} // namespace String
class CodepointView

View File

@ -131,12 +131,12 @@ public:
{
std::vector<uint8_t> result;
auto index = GetIndexFromPath(path);
if (index)
if (index.has_value())
{
auto dataSize = GetFileSize(*index);
auto dataSize = GetFileSize(index.value());
if (dataSize > 0 && dataSize < SIZE_MAX)
{
auto zipFile = zip_fopen_index(_zip, *index, 0);
auto zipFile = zip_fopen_index(_zip, index.value(), 0);
if (zipFile != nullptr)
{
result.resize(static_cast<size_t>(dataSize));
@ -155,9 +155,9 @@ public:
std::unique_ptr<IStream> GetFileStream(std::string_view path) const override
{
auto index = GetIndexFromPath(path);
if (index)
if (index.has_value())
{
return std::make_unique<ZipItemStream>(_zip, *index);
return std::make_unique<ZipItemStream>(_zip, index.value());
}
return {};
}
@ -171,9 +171,9 @@ public:
auto source = zip_source_buffer(_zip, writeBuffer.data(), writeBuffer.size(), 0);
auto index = GetIndexFromPath(path);
if (index)
if (index.has_value())
{
zip_replace(_zip, *index, source);
zip_replace(_zip, index.value(), source);
}
else
{
@ -184,9 +184,9 @@ public:
void DeleteFile(std::string_view path) override
{
auto index = GetIndexFromPath(path);
if (index)
if (index.has_value())
{
zip_delete(_zip, *index);
zip_delete(_zip, index.value());
}
else
{

View File

@ -0,0 +1,86 @@
/*****************************************************************************
* 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
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "IStream.hpp"
#include "Zip.h"
#include <memory>
namespace OpenRCT2
{
/**
* Couples a zip archive and a zip item stream to ensure the lifetime of the zip archive is maintained
* for the lifetime of the stream.
*/
class ZipStreamWrapper final : public IStream
{
private:
std::unique_ptr<IZipArchive> _zipArchive;
std::unique_ptr<IStream> _base;
public:
ZipStreamWrapper(std::unique_ptr<IZipArchive> zipArchive, std::unique_ptr<IStream> base)
: _zipArchive(std::move(zipArchive))
, _base(std::move(base))
{
}
bool CanRead() const override
{
return _base->CanRead();
}
bool CanWrite() const override
{
return _base->CanWrite();
}
uint64_t GetLength() const override
{
return _base->GetLength();
}
uint64_t GetPosition() const override
{
return _base->GetPosition();
}
void SetPosition(uint64_t position) override
{
_base->SetPosition(position);
}
void Seek(int64_t offset, int32_t origin) override
{
_base->Seek(offset, origin);
}
void Read(void* buffer, uint64_t length) override
{
_base->Read(buffer, length);
}
void Write(const void* buffer, uint64_t length) override
{
_base->Write(buffer, length);
}
uint64_t TryRead(void* buffer, uint64_t length) override
{
return _base->TryRead(buffer, length);
}
const void* GetData() const override
{
return _base->GetData();
}
};
} // namespace OpenRCT2

View File

@ -378,25 +378,27 @@ static std::optional<PaletteMap> FASTCALL gfx_draw_sprite_get_palette(ImageId im
{
paletteMap = PaletteMap(gOtherPalette);
auto tertiaryPaletteMap = GetPaletteMapForColour(imageId.GetTertiary());
if (tertiaryPaletteMap)
if (tertiaryPaletteMap.has_value())
{
paletteMap.Copy(
PALETTE_OFFSET_REMAP_TERTIARY, *tertiaryPaletteMap, PALETTE_OFFSET_REMAP_PRIMARY, PALETTE_LENGTH_REMAP);
PALETTE_OFFSET_REMAP_TERTIARY, tertiaryPaletteMap.value(), PALETTE_OFFSET_REMAP_PRIMARY,
PALETTE_LENGTH_REMAP);
}
}
auto primaryPaletteMap = GetPaletteMapForColour(imageId.GetPrimary());
if (primaryPaletteMap)
if (primaryPaletteMap.has_value())
{
paletteMap.Copy(
PALETTE_OFFSET_REMAP_PRIMARY, *primaryPaletteMap, PALETTE_OFFSET_REMAP_PRIMARY, PALETTE_LENGTH_REMAP);
PALETTE_OFFSET_REMAP_PRIMARY, primaryPaletteMap.value(), PALETTE_OFFSET_REMAP_PRIMARY, PALETTE_LENGTH_REMAP);
}
auto secondaryPaletteMap = GetPaletteMapForColour(imageId.GetSecondary());
if (secondaryPaletteMap)
if (secondaryPaletteMap.has_value())
{
paletteMap.Copy(
PALETTE_OFFSET_REMAP_SECONDARY, *secondaryPaletteMap, PALETTE_OFFSET_REMAP_PRIMARY, PALETTE_LENGTH_REMAP);
PALETTE_OFFSET_REMAP_SECONDARY, secondaryPaletteMap.value(), PALETTE_OFFSET_REMAP_PRIMARY,
PALETTE_LENGTH_REMAP);
}
return paletteMap;

View File

@ -57,7 +57,7 @@ int32_t gfx_get_string_width_new_lined(std::string_view text, FontSpriteBase fon
if (token.kind == FormatToken::Newline || token.kind == FormatToken::NewlineSmall)
{
auto width = gfx_get_string_width(buffer, fontSpriteBase);
if (!maxWidth || maxWidth > width)
if (!maxWidth.has_value() || maxWidth.value() > width)
{
maxWidth = width;
}
@ -68,11 +68,11 @@ int32_t gfx_get_string_width_new_lined(std::string_view text, FontSpriteBase fon
buffer.append(token.text);
}
}
if (!maxWidth)
if (!maxWidth.has_value())
{
maxWidth = gfx_get_string_width(buffer, fontSpriteBase);
}
return *maxWidth;
return maxWidth.value();
}
/**
@ -829,11 +829,11 @@ static void ttf_process_string_literal(rct_drawpixelinfo* dpi, std::string_view
auto codepoint = *it;
if (ShouldUseSpriteForCodepoint(codepoint))
{
if (ttfRunIndex)
if (ttfRunIndex.has_value())
{
// Draw the TTF run
auto len = it.GetIndex() - *ttfRunIndex;
ttf_draw_string_raw_ttf(dpi, text.substr(*ttfRunIndex, len), info);
auto len = it.GetIndex() - ttfRunIndex.value();
ttf_draw_string_raw_ttf(dpi, text.substr(ttfRunIndex.value(), len), info);
ttfRunIndex = std::nullopt;
}
@ -842,18 +842,18 @@ static void ttf_process_string_literal(rct_drawpixelinfo* dpi, std::string_view
}
else
{
if (!ttfRunIndex)
if (!ttfRunIndex.has_value())
{
ttfRunIndex = it.GetIndex();
}
}
}
if (ttfRunIndex)
if (ttfRunIndex.has_value())
{
// Final TTF run
auto len = text.size() - *ttfRunIndex;
ttf_draw_string_raw_ttf(dpi, text.substr(*ttfRunIndex, len), info);
ttf_draw_string_raw_ttf(dpi, text.substr(ttfRunIndex.value(), len), info);
}
}
#endif // NO_TTF

View File

@ -750,9 +750,9 @@ std::optional<uint32_t> GetPaletteG1Index(colour_t paletteId)
std::optional<PaletteMap> GetPaletteMapForColour(colour_t paletteId)
{
auto g1Index = GetPaletteG1Index(paletteId);
if (g1Index)
if (g1Index.has_value())
{
auto g1 = gfx_get_g1_element(*g1Index);
auto g1 = gfx_get_g1_element(g1Index.value());
if (g1 != nullptr)
{
return PaletteMap(g1->offset, g1->height, g1->width);

View File

@ -235,24 +235,22 @@ int32_t ImageImporter::CalculatePaletteIndex(
{
auto& palette = StandardPalette;
auto paletteIndex = GetPaletteIndex(palette, rgbaSrc);
if (mode == IMPORT_MODE::CLOSEST || mode == IMPORT_MODE::DITHERING)
if ((mode == IMPORT_MODE::CLOSEST || mode == IMPORT_MODE::DITHERING) && !IsInPalette(palette, rgbaSrc))
{
if (paletteIndex == PALETTE_TRANSPARENT && !IsTransparentPixel(rgbaSrc))
{
paletteIndex = GetClosestPaletteIndex(palette, rgbaSrc);
}
}
if (mode == IMPORT_MODE::DITHERING)
{
if (!IsTransparentPixel(rgbaSrc) && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc)))
paletteIndex = GetClosestPaletteIndex(palette, rgbaSrc);
if (mode == IMPORT_MODE::DITHERING)
{
auto dr = rgbaSrc[0] - static_cast<int16_t>(palette[paletteIndex].Red);
auto dg = rgbaSrc[1] - static_cast<int16_t>(palette[paletteIndex].Green);
auto db = rgbaSrc[2] - static_cast<int16_t>(palette[paletteIndex].Blue);
// We don't want to dither remappable colours with nonremappable colours, etc
PaletteIndexType thisIndexType = GetPaletteIndexType(paletteIndex);
if (x + 1 < width)
{
if (!IsTransparentPixel(rgbaSrc + 4) && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4)))
if (!IsInPalette(palette, rgbaSrc + 4)
&& thisIndexType == GetPaletteIndexType(GetClosestPaletteIndex(palette, rgbaSrc + 4)))
{
// Right
rgbaSrc[4] += dr * 7 / 16;
@ -265,8 +263,8 @@ int32_t ImageImporter::CalculatePaletteIndex(
{
if (x > 0)
{
if (!IsTransparentPixel(rgbaSrc + 4 * (width - 1))
&& IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width - 1))))
if (!IsInPalette(palette, rgbaSrc + 4 * (width - 1))
&& thisIndexType == GetPaletteIndexType(GetClosestPaletteIndex(palette, rgbaSrc + 4 * (width - 1))))
{
// Bottom left
rgbaSrc[4 * (width - 1)] += dr * 3 / 16;
@ -276,7 +274,8 @@ int32_t ImageImporter::CalculatePaletteIndex(
}
// Bottom
if (!IsTransparentPixel(rgbaSrc + 4 * width) && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * width)))
if (!IsInPalette(palette, rgbaSrc + 4 * width)
&& thisIndexType == GetPaletteIndexType(GetClosestPaletteIndex(palette, rgbaSrc + 4 * width)))
{
rgbaSrc[4 * width] += dr * 5 / 16;
rgbaSrc[4 * width + 1] += dg * 5 / 16;
@ -285,8 +284,8 @@ int32_t ImageImporter::CalculatePaletteIndex(
if (x + 1 < width)
{
if (!IsTransparentPixel(rgbaSrc + 4 * (width + 1))
&& IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width + 1))))
if (!IsInPalette(palette, rgbaSrc + 4 * (width + 1))
&& thisIndexType == GetPaletteIndexType(GetClosestPaletteIndex(palette, rgbaSrc + 4 * (width + 1))))
{
// Bottom right
rgbaSrc[4 * (width + 1)] += dr * 1 / 16;
@ -297,6 +296,7 @@ int32_t ImageImporter::CalculatePaletteIndex(
}
}
}
return paletteIndex;
}
@ -322,23 +322,40 @@ bool ImageImporter::IsTransparentPixel(const int16_t* colour)
}
/**
* @returns true if pixel index is an index not used for remapping.
* @returns true if this colour is in the standard palette.
*/
bool ImageImporter::IsInPalette(const GamePalette& palette, int16_t* colour)
{
return !(GetPaletteIndex(palette, colour) == PALETTE_TRANSPARENT && !IsTransparentPixel(colour));
}
/**
* @returns true if palette index is an index not used for a special purpose.
*/
bool ImageImporter::IsChangablePixel(int32_t paletteIndex)
{
if (paletteIndex == PALETTE_TRANSPARENT)
return true;
if (paletteIndex == 0)
return false;
PaletteIndexType entryType = GetPaletteIndexType(paletteIndex);
return entryType != PaletteIndexType::Special && entryType != PaletteIndexType::PrimaryRemap;
}
/**
* @returns the type of palette entry this is.
*/
ImageImporter::PaletteIndexType ImageImporter::GetPaletteIndexType(int32_t paletteIndex)
{
if (paletteIndex <= 9)
return PaletteIndexType::Special;
if (paletteIndex >= 230 && paletteIndex <= 239)
return PaletteIndexType::Special;
if (paletteIndex == 255)
return PaletteIndexType::Special;
if (paletteIndex >= 243 && paletteIndex <= 254)
return PaletteIndexType::PrimaryRemap;
if (paletteIndex >= 202 && paletteIndex <= 213)
return false;
if (paletteIndex == 226)
return false;
if (paletteIndex >= 227 && paletteIndex <= 229)
return false;
if (paletteIndex >= 243)
return false;
return true;
return PaletteIndexType::SecondaryRemap;
if (paletteIndex >= 46 && paletteIndex <= 57)
return PaletteIndexType::TertiaryRemap;
return PaletteIndexType::Normal;
}
int32_t ImageImporter::GetClosestPaletteIndex(const GamePalette& palette, const int16_t* colour)

View File

@ -53,6 +53,15 @@ namespace OpenRCT2::Drawing
IMPORT_MODE mode = IMPORT_MODE::DEFAULT) const;
private:
enum class PaletteIndexType : uint8_t
{
Normal,
PrimaryRemap,
SecondaryRemap,
TertiaryRemap,
Special,
};
static std::vector<int32_t> GetPixels(
const uint8_t* pixels, uint32_t pitch, uint32_t srcX, uint32_t srcY, uint32_t width, uint32_t height,
IMPORT_FLAGS flags, IMPORT_MODE mode);
@ -63,16 +72,18 @@ namespace OpenRCT2::Drawing
IMPORT_MODE mode, int16_t* rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height);
static int32_t GetPaletteIndex(const GamePalette& palette, int16_t* colour);
static bool IsTransparentPixel(const int16_t* colour);
static bool IsInPalette(const GamePalette& palette, int16_t* colour);
static bool IsChangablePixel(int32_t paletteIndex);
static PaletteIndexType GetPaletteIndexType(int32_t paletteIndex);
static int32_t GetClosestPaletteIndex(const GamePalette& palette, const int16_t* colour);
};
} // namespace OpenRCT2::Drawing
constexpr const GamePalette StandardPalette = { {
// 0 (unused)
// 0 (Unused/Transparent)
{ 0, 0, 0, 255 },
// 1 - 9 (misc. e.g. font and water)
// 1 - 9 (Misc. e.g. font, water, chain lift)
{ 1, 1, 1, 255 },
{ 2, 2, 2, 255 },
{ 3, 3, 3, 255 },
@ -83,7 +94,7 @@ constexpr const GamePalette StandardPalette = { {
{ 8, 8, 8, 255 },
{ 9, 9, 9, 255 },
//
// 10 - 21 (Grey)
{ 35, 35, 23, 255 },
{ 51, 51, 35, 255 },
{ 67, 67, 47, 255 },
@ -96,6 +107,8 @@ constexpr const GamePalette StandardPalette = { {
{ 195, 195, 183, 255 },
{ 219, 219, 211, 255 },
{ 243, 243, 239, 255 },
// 22 - 33 (Olive)
{ 0, 47, 51, 255 },
{ 0, 59, 63, 255 },
{ 11, 75, 79, 255 },
@ -108,6 +121,8 @@ constexpr const GamePalette StandardPalette = { {
{ 115, 191, 187, 255 },
{ 139, 207, 203, 255 },
{ 163, 227, 223, 255 },
// 34 - 45 (Light Brown)
{ 7, 43, 67, 255 },
{ 11, 59, 87, 255 },
{ 23, 75, 111, 255 },
@ -120,6 +135,8 @@ constexpr const GamePalette StandardPalette = { {
{ 135, 199, 219, 255 },
{ 163, 219, 231, 255 },
{ 195, 239, 247, 255 },
// 46 - 57 (Yellow, also used for tertiary remap)
{ 0, 27, 71, 255 },
{ 0, 43, 95, 255 },
{ 0, 63, 119, 255 },
@ -132,6 +149,8 @@ constexpr const GamePalette StandardPalette = { {
{ 95, 243, 255, 255 },
{ 143, 251, 255, 255 },
{ 195, 255, 255, 255 },
// 58 - 69 (Indian Red)
{ 0, 0, 35, 255 },
{ 0, 0, 79, 255 },
{ 7, 7, 95, 255 },
@ -144,6 +163,8 @@ constexpr const GamePalette StandardPalette = { {
{ 127, 127, 215, 255 },
{ 159, 159, 235, 255 },
{ 191, 191, 255, 255 },
// 70 - 81 (Grass Green)
{ 19, 51, 27, 255 },
{ 23, 63, 35, 255 },
{ 31, 79, 47, 255 },
@ -156,6 +177,8 @@ constexpr const GamePalette StandardPalette = { {
{ 83, 187, 147, 255 },
{ 95, 203, 163, 255 },
{ 103, 219, 183, 255 },
// 82 - 93 (Olive Green)
{ 27, 55, 31, 255 },
{ 35, 71, 47, 255 },
{ 43, 83, 59, 255 },
@ -168,6 +191,8 @@ constexpr const GamePalette StandardPalette = { {
{ 147, 219, 195, 255 },
{ 167, 231, 207, 255 },
{ 191, 247, 223, 255 },
// 94 - 105 (Green)
{ 0, 63, 15, 255 },
{ 0, 83, 19, 255 },
{ 0, 103, 23, 255 },
@ -180,6 +205,8 @@ constexpr const GamePalette StandardPalette = { {
{ 115, 223, 139, 255 },
{ 143, 239, 163, 255 },
{ 179, 255, 195, 255 },
// 106 - 117 (Tan)
{ 19, 43, 79, 255 },
{ 27, 55, 99, 255 },
{ 43, 71, 119, 255 },
@ -192,6 +219,8 @@ constexpr const GamePalette StandardPalette = { {
{ 151, 191, 239, 255 },
{ 171, 207, 247, 255 },
{ 195, 227, 255, 255 },
// 118 - 129 (Indigo)
{ 55, 19, 15, 255 },
{ 87, 43, 39, 255 },
{ 103, 55, 51, 255 },
@ -204,6 +233,8 @@ constexpr const GamePalette StandardPalette = { {
{ 223, 183, 183, 255 },
{ 239, 211, 211, 255 },
{ 255, 239, 239, 255 },
// 130 - 141 (Blue)
{ 111, 27, 0, 255 },
{ 151, 39, 0, 255 },
{ 167, 51, 7, 255 },
@ -216,6 +247,8 @@ constexpr const GamePalette StandardPalette = { {
{ 243, 211, 143, 255 },
{ 251, 231, 175, 255 },
{ 255, 247, 215, 255 },
// 142 - 153 (Sea Green)
{ 15, 43, 11, 255 },
{ 23, 55, 15, 255 },
{ 31, 71, 23, 255 },
@ -228,6 +261,8 @@ constexpr const GamePalette StandardPalette = { {
{ 167, 199, 147, 255 },
{ 195, 219, 175, 255 },
{ 223, 243, 207, 255 },
// 154 - 165 (Purple)
{ 95, 0, 63, 255 },
{ 115, 7, 75, 255 },
{ 127, 15, 83, 255 },
@ -240,6 +275,8 @@ constexpr const GamePalette StandardPalette = { {
{ 231, 155, 191, 255 },
{ 243, 195, 215, 255 },
{ 255, 235, 243, 255 },
// 166 - 177 (Red)
{ 0, 0, 63, 255 },
{ 0, 0, 87, 255 },
{ 0, 0, 115, 255 },
@ -252,6 +289,8 @@ constexpr const GamePalette StandardPalette = { {
{ 115, 123, 255, 255 },
{ 163, 171, 255, 255 },
{ 215, 219, 255, 255 },
// 178 - 189 (Orange)
{ 0, 39, 79, 255 },
{ 0, 51, 111, 255 },
{ 0, 63, 147, 255 },
@ -264,6 +303,8 @@ constexpr const GamePalette StandardPalette = { {
{ 107, 183, 255, 255 },
{ 135, 203, 255, 255 },
{ 163, 219, 255, 255 },
// 190 - 201 (Water Blue)
{ 47, 51, 0, 255 },
{ 55, 63, 0, 255 },
{ 67, 75, 0, 255 },
@ -277,7 +318,7 @@ constexpr const GamePalette StandardPalette = { {
{ 231, 231, 171, 255 },
{ 255, 255, 207, 255 },
// 202 - 213 (Secondary remap)
// 202 - 213 (Pink, also used for secondary remap)
{ 27, 0, 63, 255 },
{ 51, 0, 103, 255 },
{ 63, 11, 123, 255 },
@ -305,27 +346,29 @@ constexpr const GamePalette StandardPalette = { {
{ 195, 219, 231, 255 },
{ 223, 243, 255, 255 },
// 226 (unknown)
// 226 (Extra grey)
{ 75, 75, 55, 255 },
// 227 - 229 (tertiary remap)
// 227 - 229 (Extra yellows)
{ 0, 183, 255, 255 },
{ 0, 219, 255, 255 },
{ 0, 255, 255, 255 },
// 230 - 239 (water)
// 230 - 234 (Water waves)
{ 99, 107, 7, 255 },
{ 99, 107, 7, 255 },
{ 135, 143, 39, 255 },
{ 123, 131, 27, 255 },
{ 99, 107, 7, 255 },
// 235 - 249 (Water sparkles)
{ 151, 155, 55, 255 },
{ 151, 155, 55, 255 },
{ 227, 227, 155, 255 },
{ 203, 203, 115, 255 },
{ 151, 155, 55, 255 },
// 240 - 242 (chain lift)
// 240 - 242 (Extra grey)
{ 91, 91, 67, 255 },
{ 107, 107, 83, 255 },
{ 123, 123, 99, 255 },
@ -335,7 +378,7 @@ constexpr const GamePalette StandardPalette = { {
// { 47, 47, 47, 255 },
// { 47, 71, 87, 255 },
// 243 to 254 (primary remap)
// 243 to 254 (Primary remap)
{ 47, 51, 111, 255 },
{ 47, 55, 131, 255 },
{ 51, 63, 151, 255 },
@ -349,6 +392,6 @@ constexpr const GamePalette StandardPalette = { {
{ 63, 183, 255, 255 },
{ 75, 207, 255, 255 },
// 255 (unused?)
{ 0, 0, 0, 255 },
// 255 (Used in a small number of cases for pure white)
{ 255, 255, 255, 255 },
} };

View File

@ -19,6 +19,7 @@
# include "../OpenRCT2.h"
# include "../config/Config.h"
# include "../core/Numerics.hpp"
# include "../core/String.hpp"
# include "../localisation/Localisation.h"
# include "../localisation/LocalisationService.h"
@ -186,7 +187,7 @@ static uint32_t ttf_surface_cache_hash(TTF_Font* font, std::string_view text)
uint32_t hash = static_cast<uint32_t>(((reinterpret_cast<uintptr_t>(font) * 23) ^ 0xAAAAAAAA) & 0xFFFFFFFF);
for (auto c : text)
{
hash = ror32(hash, 3) ^ (c * 13);
hash = Numerics::ror32(hash, 3) ^ (c * 13);
}
return hash;
}

View File

@ -13,6 +13,7 @@
#include "../Game.h"
#include "../Intro.h"
#include "../config/Config.h"
#include "../core/Numerics.hpp"
#include "../interface/Screenshot.h"
#include "../interface/Viewport.h"
#include "../interface/Window.h"
@ -583,7 +584,7 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3
for (int32_t i = 0; i < height; i++)
{
uint8_t* nextdst = dst + dpi->width + dpi->pitch;
uint32_t p = ror32(crossPattern, 1);
uint32_t p = Numerics::ror32(crossPattern, 1);
p = (p & 0xFFFF0000) | width;
// Fill every other pixel with the colour
@ -702,8 +703,9 @@ void X8DrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int32_t
// Find colour in colour table?
auto paletteMap = GetPaletteMapForColour(EnumValue(palette));
if (paletteMap)
if (paletteMap.has_value())
{
const auto& paletteEntries = paletteMap.value();
const int32_t scaled_width = width / dpi->zoom_level;
const int32_t step = ((dpi->width / dpi->zoom_level) + dpi->pitch);
@ -715,7 +717,7 @@ void X8DrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int32_t
for (int32_t j = 0; j < scaled_width; j++)
{
auto index = *(nextdst + j);
*(nextdst + j) = (*paletteMap)[index];
*(nextdst + j) = paletteEntries[index];
}
}
}

View File

@ -194,7 +194,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
int32_t res = set_operating_setting(ride_index, RideSetSetting::RideType, type);
int32_t res = set_operating_setting(static_cast<ride_id_t>(ride_index), RideSetSetting::RideType, type);
if (res == MONEY32_UNDEFINED)
{
if (!gCheatsAllowArbitraryRideTypeChanges)
@ -224,7 +224,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto ride = get_ride(ride_index);
auto ride = get_ride(static_cast<ride_id_t>(ride_index));
if (mode >= static_cast<uint8_t>(RideMode::Count))
{
console.WriteFormatLine("Invalid ride mode.");
@ -256,7 +256,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto ride = get_ride(ride_index);
auto ride = get_ride(static_cast<ride_id_t>(ride_index));
if (mass <= 0)
{
console.WriteFormatLine("Friction value must be strictly positive");
@ -294,7 +294,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto ride = get_ride(ride_index);
auto ride = get_ride(static_cast<ride_id_t>(ride_index));
if (excitement <= 0)
{
console.WriteFormatLine("Excitement value must be strictly positive");
@ -325,7 +325,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto ride = get_ride(ride_index);
auto ride = get_ride(static_cast<ride_id_t>(ride_index));
if (intensity <= 0)
{
console.WriteFormatLine("Intensity value must be strictly positive");
@ -356,7 +356,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto ride = get_ride(ride_index);
auto ride = get_ride(static_cast<ride_id_t>(ride_index));
if (nausea <= 0)
{
console.WriteFormatLine("Nausea value must be strictly positive");
@ -426,7 +426,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
auto rideSetPrice = RideSetPriceAction(rideId, price, true);
auto rideSetPrice = RideSetPriceAction(static_cast<ride_id_t>(rideId), price, true);
GameActions::Execute(&rideSetPrice);
}
}

View File

@ -161,14 +161,14 @@ std::string screenshot_dump_png(rct_drawpixelinfo* dpi)
// Get a free screenshot path
auto path = screenshot_get_next_path();
if (path == std::nullopt)
if (!path.has_value())
{
return "";
}
if (WriteDpiToFile(path->c_str(), dpi, gPalette))
if (WriteDpiToFile(path.value(), dpi, gPalette))
{
return *path;
return path.value();
}
else
{
@ -180,7 +180,7 @@ std::string screenshot_dump_png_32bpp(int32_t width, int32_t height, const void*
{
auto path = screenshot_get_next_path();
if (path == std::nullopt)
if (!path.has_value())
{
return "";
}
@ -196,8 +196,8 @@ std::string screenshot_dump_png_32bpp(int32_t width, int32_t height, const void*
image.Depth = 32;
image.Stride = width * 4;
image.Pixels = std::vector<uint8_t>(pixels8, pixels8 + pixelsLen);
Imaging::WriteToFile(path->c_str(), image, IMAGE_FORMAT::PNG_32);
return *path;
Imaging::WriteToFile(path.value(), image, IMAGE_FORMAT::PNG_32);
return path.value();
}
catch (const std::exception& e)
{
@ -384,7 +384,7 @@ void screenshot_giant()
try
{
auto path = screenshot_get_next_path();
if (path == std::nullopt)
if (!path.has_value())
{
throw std::runtime_error("Giant screenshot failed, unable to find a suitable destination path.");
}
@ -412,7 +412,7 @@ void screenshot_giant()
dpi = CreateDPI(viewport);
RenderViewport(nullptr, viewport, dpi);
WriteDpiToFile(path->c_str(), &dpi, gPalette);
WriteDpiToFile(path.value(), &dpi, gPalette);
// Show user that screenshot saved successfully
Formatter ft;
@ -792,7 +792,7 @@ static std::string ResolveFilenameForCapture(const fs::path& filename)
void CaptureImage(const CaptureOptions& options)
{
rct_viewport viewport{};
if (options.View)
if (options.View.has_value())
{
viewport.width = options.View->Width;
viewport.height = options.View->Height;

View File

@ -106,7 +106,7 @@ std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, rct_vi
// If the start location was invalid
// propagate the invalid location to the output.
// This fixes a bug that caused the game to enter an infinite loop.
if (loc.isNull())
if (loc.IsNull())
{
return std::nullopt;
}
@ -186,7 +186,7 @@ void viewport_create(
}
auto centreLoc = centre_2d_coordinates(centrePos, viewport);
if (!centreLoc)
if (!centreLoc.has_value())
{
log_error("Invalid location for viewport.");
return;
@ -519,7 +519,8 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp
// rct2: 0x006E7A15
static void viewport_set_underground_flag(int32_t underground, rct_window* window, rct_viewport* viewport)
{
if (window->classification != WC_MAIN_WINDOW)
if (window->classification != WC_MAIN_WINDOW
|| (window->classification == WC_MAIN_WINDOW && window->viewport_smart_follow_sprite != SPRITE_INDEX_NULL))
{
if (!underground)
{
@ -597,9 +598,9 @@ void viewport_update_position(rct_window* window)
if (at_map_edge)
{
auto centreLoc = centre_2d_coordinates({ mapCoord, 0 }, viewport);
if (centreLoc)
if (centreLoc.has_value())
{
window->savedViewPos = *centreLoc;
window->savedViewPos = centreLoc.value();
}
}
@ -658,7 +659,7 @@ void viewport_update_sprite_follow(rct_window* window)
viewport_set_underground_flag(underground, window, window->viewport);
auto centreLoc = centre_2d_coordinates({ sprite->x, sprite->y, sprite->z }, window->viewport);
if (centreLoc)
if (centreLoc.has_value())
{
window->savedViewPos = *centreLoc;
viewport_move(*centreLoc, window, window->viewport);
@ -669,44 +670,35 @@ void viewport_update_sprite_follow(rct_window* window)
void viewport_update_smart_sprite_follow(rct_window* window)
{
auto entity = TryGetEntity(window->viewport_smart_follow_sprite);
if (entity == nullptr)
if (entity == nullptr || entity->Type == EntityType::Null)
{
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
window->viewport_target_sprite = SPRITE_INDEX_NULL;
return;
}
else if (entity->Type == EntityType::Guest || entity->Type == EntityType::Staff)
{
Peep* peep = TryGetEntity<Peep>(window->viewport_smart_follow_sprite);
if (peep == nullptr)
{
// will never happen
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
window->viewport_target_sprite = SPRITE_INDEX_NULL;
return;
}
if (peep->Is<Guest>())
viewport_update_smart_guest_follow(window, peep);
else if (peep->Is<Staff>())
viewport_update_smart_staff_follow(window, peep);
}
else if (entity->Type == EntityType::Vehicle)
switch (entity->Type)
{
viewport_update_smart_vehicle_follow(window);
}
else if (entity->Type != EntityType::Null)
{
window->viewport_focus_sprite.sprite_id = window->viewport_smart_follow_sprite;
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
}
else
{
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
window->viewport_target_sprite = SPRITE_INDEX_NULL;
case EntityType::Vehicle:
viewport_update_smart_vehicle_follow(window);
break;
case EntityType::Guest:
viewport_update_smart_guest_follow(window, entity->As<Guest>());
break;
case EntityType::Staff:
viewport_update_smart_staff_follow(window, entity->As<Staff>());
break;
default: // All other types don't need any "smart" following; steam particle, duck, money effect, etc.
window->viewport_focus_sprite.sprite_id = window->viewport_smart_follow_sprite;
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
break;
}
}
viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep)
viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
{
viewport_focus focus{};
focus.type = VIEWPORT_FOCUS_TYPE_SPRITE;
@ -719,54 +711,53 @@ viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep
window->viewport_target_sprite = SPRITE_INDEX_NULL;
return focus;
}
else
bool overallFocus = true;
if (peep->State == PeepState::OnRide || peep->State == PeepState::EnteringRide
|| (peep->State == PeepState::LeavingRide && peep->x == LOCATION_NULL))
{
bool overallFocus = true;
if (peep->State == PeepState::OnRide || peep->State == PeepState::EnteringRide
|| (peep->State == PeepState::LeavingRide && peep->x == LOCATION_NULL))
auto ride = get_ride(peep->CurrentRide);
if (ride != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
{
auto ride = get_ride(peep->CurrentRide);
if (ride != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
auto train = GetEntity<Vehicle>(ride->vehicles[peep->CurrentTrain]);
if (train != nullptr)
{
auto train = GetEntity<Vehicle>(ride->vehicles[peep->CurrentTrain]);
if (train != nullptr)
const auto car = train->GetCar(peep->CurrentCar);
if (car != nullptr)
{
const auto car = train->GetCar(peep->CurrentCar);
if (car != nullptr)
{
focus.sprite.sprite_id = car->sprite_index;
overallFocus = false;
}
focus.sprite.sprite_id = car->sprite_index;
overallFocus = false;
}
}
}
if (peep->x == LOCATION_NULL && overallFocus)
{
auto ride = get_ride(peep->CurrentRide);
if (ride != nullptr)
{
auto xy = ride->overall_view.ToTileCentre();
focus.type = VIEWPORT_FOCUS_TYPE_COORDINATE;
focus.coordinate.x = xy.x;
focus.coordinate.y = xy.y;
focus.coordinate.z = tile_element_height(xy) + (4 * COORDS_Z_STEP);
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
}
}
else
{
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
focus.sprite.pad_486 &= 0xFFFF;
}
focus.coordinate.rotation = get_current_rotation();
}
if (peep->x == LOCATION_NULL && overallFocus)
{
auto ride = get_ride(peep->CurrentRide);
if (ride != nullptr)
{
auto xy = ride->overall_view.ToTileCentre();
focus.type = VIEWPORT_FOCUS_TYPE_COORDINATE;
focus.coordinate.x = xy.x;
focus.coordinate.y = xy.y;
focus.coordinate.z = tile_element_height(xy) + (4 * COORDS_Z_STEP);
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
}
}
else
{
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
focus.sprite.pad_486 &= 0xFFFF;
}
focus.coordinate.rotation = get_current_rotation();
window->viewport_focus_sprite = focus.sprite;
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
return focus;
}
void viewport_update_smart_staff_follow(rct_window* window, Peep* peep)
void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep)
{
sprite_focus focus = {};
@ -774,15 +765,12 @@ void viewport_update_smart_staff_follow(rct_window* window, Peep* peep)
if (peep->State == PeepState::Picked)
{
// focus.sprite.sprite_id = SPRITE_INDEX_NULL;
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
window->viewport_target_sprite = SPRITE_INDEX_NULL;
return;
}
else
{
focus.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
}
focus.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
window->viewport_focus_sprite = focus;
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
@ -790,9 +778,7 @@ void viewport_update_smart_staff_follow(rct_window* window, Peep* peep)
void viewport_update_smart_vehicle_follow(rct_window* window)
{
// Can be expanded in the future if needed
sprite_focus focus = {};
focus.sprite_id = window->viewport_smart_follow_sprite;
window->viewport_focus_sprite = focus;
@ -1095,7 +1081,7 @@ static void viewport_paint_weather_gloom(rct_drawpixelinfo* dpi)
std::optional<CoordsXY> screen_pos_to_map_pos(const ScreenCoordsXY& screenCoords, int32_t* direction)
{
auto mapCoords = screen_get_map_xy(screenCoords, nullptr);
if (!mapCoords)
if (!mapCoords.has_value())
return std::nullopt;
int32_t my_direction;
@ -1628,9 +1614,9 @@ static bool is_sprite_interacted_with(rct_drawpixelinfo* dpi, int32_t imageId, c
{
index &= 0x1F;
}
if (auto pm = GetPaletteMapForColour(index))
if (auto pm = GetPaletteMapForColour(index); pm.has_value())
{
paletteMap = *pm;
paletteMap = pm.value();
}
}
else
@ -1880,7 +1866,7 @@ std::optional<CoordsXY> screen_get_map_xy_with_z(const ScreenCoordsXY& screenCoo
std::optional<CoordsXY> screen_get_map_xy_quadrant(const ScreenCoordsXY& screenCoords, uint8_t* quadrant)
{
auto mapCoords = screen_get_map_xy(screenCoords, nullptr);
if (!mapCoords)
if (!mapCoords.has_value())
return std::nullopt;
*quadrant = map_get_tile_quadrant(*mapCoords);
@ -1894,7 +1880,7 @@ std::optional<CoordsXY> screen_get_map_xy_quadrant(const ScreenCoordsXY& screenC
std::optional<CoordsXY> screen_get_map_xy_quadrant_with_z(const ScreenCoordsXY& screenCoords, int32_t z, uint8_t* quadrant)
{
auto mapCoords = screen_get_map_xy_with_z(screenCoords, z);
if (!mapCoords)
if (!mapCoords.has_value())
return std::nullopt;
*quadrant = map_get_tile_quadrant(*mapCoords);
@ -1908,7 +1894,7 @@ std::optional<CoordsXY> screen_get_map_xy_quadrant_with_z(const ScreenCoordsXY&
std::optional<CoordsXY> screen_get_map_xy_side(const ScreenCoordsXY& screenCoords, uint8_t* side)
{
auto mapCoords = screen_get_map_xy(screenCoords, nullptr);
if (!mapCoords)
if (!mapCoords.has_value())
return std::nullopt;
*side = map_get_tile_side(*mapCoords);
@ -1922,7 +1908,7 @@ std::optional<CoordsXY> screen_get_map_xy_side(const ScreenCoordsXY& screenCoord
std::optional<CoordsXY> screen_get_map_xy_side_with_z(const ScreenCoordsXY& screenCoords, int32_t z, uint8_t* side)
{
auto mapCoords = screen_get_map_xy_with_z(screenCoords, z);
if (!mapCoords)
if (!mapCoords.has_value())
return std::nullopt;
*side = map_get_tile_side(*mapCoords);

View File

@ -20,11 +20,12 @@ struct paint_session;
struct RecordedPaintSession;
struct paint_struct;
struct rct_drawpixelinfo;
struct Peep;
struct TileElement;
struct rct_window;
union paint_entry;
struct EntityBase;
struct Guest;
struct Staff;
union paint_entry;
enum
{
@ -111,8 +112,8 @@ void viewports_invalidate(int32_t left, int32_t top, int32_t right, int32_t bott
void viewport_update_position(rct_window* window);
void viewport_update_sprite_follow(rct_window* window);
void viewport_update_smart_sprite_follow(rct_window* window);
viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep);
void viewport_update_smart_staff_follow(rct_window* window, Peep* peep);
viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Guest* peep);
void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep);
void viewport_update_smart_vehicle_follow(rct_window* window);
void viewport_render(
rct_drawpixelinfo* dpi, const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom,

View File

@ -909,7 +909,7 @@ void window_rotate_camera(rct_window* w, int32_t direction)
// other != viewport probably triggers on viewports in ride or guest window?
// naoXYCoords is nullopt if middle of viewport is obstructed by another window?
if (!mapXYCoords || other != viewport)
if (!mapXYCoords.has_value() || other != viewport)
{
auto viewPos = ScreenCoordsXY{ (viewport->view_width >> 1), (viewport->view_height >> 1) } + viewport->viewPos;
@ -926,9 +926,9 @@ void window_rotate_camera(rct_window* w, int32_t direction)
auto centreLoc = centre_2d_coordinates(coords, viewport);
if (centreLoc)
if (centreLoc.has_value())
{
w->savedViewPos = *centreLoc;
w->savedViewPos = centreLoc.value();
viewport->viewPos = *centreLoc;
}
@ -976,7 +976,7 @@ void window_viewport_centre_tile_around_cursor(rct_window* w, int32_t map_x, int
int32_t z = tile_element_height({ map_x, map_y });
auto centreLoc = centre_2d_coordinates({ map_x, map_y, z }, w->viewport);
if (!centreLoc)
if (!centreLoc.has_value())
{
log_error("Invalid location.");
return;

View File

@ -45,10 +45,14 @@ struct rct_window
int16_t max_width{};
int16_t min_height{};
int16_t max_height{};
rct_windownumber number{};
union
{
rct_windownumber number{};
ride_id_t rideId;
};
uint16_t flags{};
rct_scroll scrolls[3];
uint8_t list_item_positions[1024]{};
uint32_t list_item_positions[1024]{};
uint16_t no_list_items{}; // 0 for no items
int16_t selected_list_item{}; // -1 for none selected
coordinate_focus viewport_focus_coordinates;

View File

@ -175,7 +175,6 @@
<ClInclude Include="core\Memory.hpp" />
<ClInclude Include="core\MemoryStream.h" />
<ClInclude Include="core\Meta.hpp" />
<ClInclude Include="core\Nullable.hpp" />
<ClInclude Include="core\Numerics.hpp" />
<ClInclude Include="core\Path.hpp" />
<ClInclude Include="core\Random.hpp" />
@ -185,6 +184,7 @@
<ClInclude Include="core\StringBuilder.h" />
<ClInclude Include="core\StringReader.h" />
<ClInclude Include="core\Zip.h" />
<ClInclude Include="core\ZipStream.hpp" />
<ClInclude Include="Date.h" />
<ClInclude Include="Diagnostic.h" />
<ClInclude Include="drawing\Drawing.h" />
@ -924,4 +924,4 @@
<ClCompile Include="world\Wall.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@ -16,6 +16,8 @@
extern thread_local uint8_t gCommonFormatArgs[80];
enum class ride_id_t : uint16_t;
class Formatter
{
std::array<uint8_t, 80> Buffer{};
@ -83,6 +85,7 @@ public:
std::is_same_v<typename std::remove_cv<TSpecified>::type, int32_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, money32> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, money64> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, ride_id_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, rct_string_id> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, uint16_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, uint32_t> ||
@ -92,7 +95,7 @@ public:
// clang-format on
uint64_t convertedValue;
if constexpr (std::is_integral_v<TSpecified>)
if constexpr (std::is_integral_v<TSpecified> || std::is_enum_v<TSpecified>)
{
convertedValue = static_cast<uint64_t>(value);
}

View File

@ -3916,6 +3916,10 @@ enum
STR_SHORTCUT_GIANT_SCREENSHOT = 6456,
STR_FILE_BUG_ON_GITHUB = 6457,
STR_FOLLOW_SUBJECT_TIP = 6458,
// 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
};

Some files were not shown because too many files have changed in this diff Show More