diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 5d3f4d978a..1e640a268b 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -554,7 +554,7 @@ public: auto viewport = window_get_viewport(mainWindow); auto zoomDifference = zoom - viewport->zoom; - mainWindow->viewport_target_sprite = SPRITE_INDEX_NULL; + mainWindow->viewport_target_sprite = EntityId::GetNull(); mainWindow->savedViewPos = viewPos; viewport->zoom = zoom; gCurrentRotation = rotation; diff --git a/src/openrct2-ui/scripting/CustomMenu.cpp b/src/openrct2-ui/scripting/CustomMenu.cpp index 3e1e673096..4faf3389dd 100644 --- a/src/openrct2-ui/scripting/CustomMenu.cpp +++ b/src/openrct2-ui/scripting/CustomMenu.cpp @@ -194,7 +194,7 @@ namespace OpenRCT2::Scripting if (info.SpriteType == ViewportInteractionItem::Entity && info.Entity != nullptr) { - obj.Set("entityId", info.Entity->sprite_index); + obj.Set("entityId", info.Entity->sprite_index.ToUnderlying()); } else if (info.Element != nullptr) { diff --git a/src/openrct2-ui/scripting/ScTitleSequence.hpp b/src/openrct2-ui/scripting/ScTitleSequence.hpp index 411fb29c4d..643a12606d 100644 --- a/src/openrct2-ui/scripting/ScTitleSequence.hpp +++ b/src/openrct2-ui/scripting/ScTitleSequence.hpp @@ -65,10 +65,10 @@ namespace OpenRCT2::Scripting obj.Set("zoom", value.Zoom); break; case TitleScript::Follow: - if (value.SpriteIndex == SPRITE_INDEX_NULL) + if (value.SpriteIndex.IsNull()) obj.Set("id", nullptr); else - obj.Set("id", value.SpriteIndex); + obj.Set("id", value.SpriteIndex.ToUnderlying()); break; case TitleScript::Speed: obj.Set("speed", value.Speed); @@ -117,11 +117,11 @@ namespace OpenRCT2::Scripting auto dukId = value["id"]; if (dukId.type() == DukValue::Type::NUMBER) { - command.SpriteIndex = dukId.as_int(); + command.SpriteIndex = EntityId::FromUnderlying(dukId.as_int()); } else { - command.SpriteIndex = SPRITE_INDEX_NULL; + command.SpriteIndex = EntityId::GetNull(); } break; } diff --git a/src/openrct2-ui/title/TitleSequencePlayer.cpp b/src/openrct2-ui/title/TitleSequencePlayer.cpp index 6189555c30..53705453f6 100644 --- a/src/openrct2-ui/title/TitleSequencePlayer.cpp +++ b/src/openrct2-ui/title/TitleSequencePlayer.cpp @@ -339,7 +339,7 @@ private: } } - void FollowSprite(uint16_t spriteIndex) + void FollowSprite(EntityId spriteIndex) { rct_window* w = window_get_main(); if (w != nullptr) @@ -502,7 +502,7 @@ private: void FixViewLocation() { rct_window* w = window_get_main(); - if (w != nullptr && w->viewport_smart_follow_sprite == SPRITE_INDEX_NULL) + if (w != nullptr && w->viewport_smart_follow_sprite.IsNull()) { if (w->width != _lastScreenWidth || w->height != _lastScreenHeight) { diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index a0a20bb667..e8b35b2622 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -594,7 +594,7 @@ static void WindowGameBottomToolbarDrawNewsItem(rct_drawpixelinfo* dpi, rct_wind break; } - auto peep = TryGetEntity(newsItem->Assoc); + auto peep = TryGetEntity(EntityId::FromUnderlying(newsItem->Assoc)); if (peep == nullptr) return; diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index c1a33fd091..6f3ba80e09 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -289,7 +289,7 @@ void WindowGuestSetColours(); static Guest* GetGuest(rct_window* w) { - auto guest = GetEntity(w->number); + auto guest = GetEntity(EntityId::FromUnderlying(w->number)); if (guest == nullptr) { window_close(w); @@ -316,7 +316,7 @@ rct_window* WindowGuestOpen(Peep* peep) rct_window* window; - window = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index); + window = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index.ToUnderlying()); if (window == nullptr) { int32_t windowWidth = 192; @@ -325,7 +325,7 @@ rct_window* WindowGuestOpen(Peep* peep) window = WindowCreateAutoPos(windowWidth, 157, &window_guest_overview_events, WC_PEEP, WF_RESIZABLE); window->widgets = window_guest_overview_widgets; - window->number = peep->sprite_index; + window->number = peep->sprite_index.ToUnderlying(); window->page = 0; window->frame_no = 0; window->list_information_type = 0; @@ -518,7 +518,8 @@ void WindowGuestOverviewMouseUp(rct_window* w, rct_widgetindex widgetIndex) w->picked_peep_old_x = peep->x; CoordsXYZ nullLoc{}; nullLoc.SetNull(); - PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, nullLoc, network_get_current_player_id() }; + PeepPickupAction pickupAction{ PeepPickupType::Pickup, EntityId::FromUnderlying(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) return; @@ -541,7 +542,7 @@ void WindowGuestOverviewMouseUp(rct_window* w, rct_widgetindex widgetIndex) { uint32_t flags = peep->PeepFlags ^ PEEP_FLAGS_TRACKING; - auto guestSetFlagsAction = GuestSetFlagsAction(w->number, flags); + auto guestSetFlagsAction = GuestSetFlagsAction(EntityId::FromUnderlying(w->number), flags); GameActions::Execute(&guestSetFlagsAction); } break; @@ -590,7 +591,7 @@ static void WindowGuestShowLocateDropdown(rct_window* w, rct_widget* widget) static void WindowGuestFollow(rct_window* w) { rct_window* w_main = window_get_main(); - window_follow_sprite(w_main, w->number); + window_follow_sprite(w_main, EntityId::FromUnderlying(w->number)); } /** @@ -712,7 +713,7 @@ static void WindowGuestOverviewTabPaint(rct_window* w, rct_drawpixelinfo* dpi) screenCoords = ScreenCoordsXY{ 14, 20 }; - const Peep* peep = GetEntity(w->number); + const Peep* peep = GetEntity(EntityId::FromUnderlying(w->number)); if (peep == nullptr) { window_close(w); @@ -1075,7 +1076,7 @@ void WindowGuestOverviewTextInput(rct_window* w, rct_widgetindex widgetIndex, ch if (text == nullptr) return; - guest_set_name(w->number, text); + guest_set_name(EntityId::FromUnderlying(w->number), text); } /** @@ -1141,9 +1142,10 @@ void WindowGuestOverviewToolDown(rct_window* w, rct_widgetindex widgetIndex, con if (destCoords.IsNull()) return; - PeepPickupAction pickupAction{ - PeepPickupType::Place, w->number, { destCoords, tileElement->GetBaseZ() }, network_get_current_player_id() - }; + PeepPickupAction pickupAction{ PeepPickupType::Place, + EntityId::FromUnderlying(w->number), + { destCoords, tileElement->GetBaseZ() }, + network_get_current_player_id() }; pickupAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) { if (result->Error != GameActions::Status::Ok) return; @@ -1162,9 +1164,10 @@ void WindowGuestOverviewToolAbort(rct_window* w, rct_widgetindex widgetIndex) if (widgetIndex != WIDX_PICKUP) return; - PeepPickupAction pickupAction{ - PeepPickupType::Cancel, w->number, { w->picked_peep_old_x, 0, 0 }, network_get_current_player_id() - }; + PeepPickupAction pickupAction{ PeepPickupType::Cancel, + EntityId::FromUnderlying(w->number), + { w->picked_peep_old_x, 0, 0 }, + network_get_current_player_id() }; GameActions::Execute(&pickupAction); } diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index e05c6aad21..6d9aa93be7 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -121,7 +121,7 @@ private: { using CompareFunc = bool (*)(const GuestItem&, const GuestItem&); - uint16_t Id; + EntityId Id; char Name[256]; }; diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index 7af93494a4..73273b7ef2 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -237,7 +237,7 @@ public: break; } - auto peep = TryGetEntity(newsItem.Assoc); + auto peep = TryGetEntity(EntityId::FromUnderlying(newsItem.Assoc)); if (peep == nullptr) { break; diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 889e5928b7..5388f5cf06 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1288,7 +1288,7 @@ rct_window* WindowRideOpenVehicle(Vehicle* vehicle) if (headVehicle == nullptr) return nullptr; - uint16_t headVehicleSpriteIndex = headVehicle->sprite_index; + EntityId headVehicleSpriteIndex = headVehicle->sprite_index; auto ride = headVehicle->GetRide(); if (ride == nullptr) return nullptr; @@ -1489,21 +1489,21 @@ static void WindowRideInitViewport(rct_window* w) if (viewSelectionIndex >= 0 && viewSelectionIndex < ride->num_vehicles && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) { - uint16_t vehId = ride->vehicles[viewSelectionIndex]; + auto vehId = ride->vehicles[viewSelectionIndex]; rct_ride_entry* ride_entry = ride->GetRideEntry(); if (ride_entry != nullptr && ride_entry->tab_vehicle != 0) { Vehicle* vehicle = GetEntity(vehId); if (vehicle == nullptr) { - vehId = SPRITE_INDEX_NULL; + vehId = EntityId::GetNull(); } - else if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) + else if (!vehicle->next_vehicle_on_train.IsNull()) { vehId = vehicle->next_vehicle_on_train; } } - if (vehId != SPRITE_INDEX_NULL) + if (!vehId.IsNull()) { focus = Focus(vehId); } @@ -1939,7 +1939,7 @@ static void WindowRideShowLocateDropdown(rct_window* w, rct_widget* widget) static void WindowRideMainFollowRide(rct_window* w) { - auto ride = get_ride(w->rideId); + auto* ride = get_ride(w->rideId); if (ride != nullptr) { if (!(ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_MAIN)) @@ -1951,7 +1951,7 @@ static void WindowRideMainFollowRide(rct_window* w) Vehicle* vehicle = GetEntity(ride->vehicles[w->ride.view - 1]); if (vehicle != nullptr) { - uint16_t headVehicleSpriteIndex = vehicle->sprite_index; + auto headVehicleSpriteIndex = vehicle->sprite_index; rct_window* w_main = window_get_main(); window_follow_sprite(w_main, headVehicleSpriteIndex); } diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 60719466af..6d22bf1c4b 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -219,7 +219,7 @@ static PatrolAreaValue _staffPatrolAreaPaintValue = PatrolAreaValue::NONE; static Staff* GetStaff(rct_window* w) { - auto staff = GetEntity(w->number); + auto staff = GetEntity(EntityId::FromUnderlying(w->number)); if (staff == nullptr) { window_close(w); @@ -234,12 +234,12 @@ static Staff* GetStaff(rct_window* w) */ rct_window* WindowStaffOpen(Peep* peep) { - rct_window* w = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index); + rct_window* w = window_bring_to_front_by_number(WC_PEEP, peep->sprite_index.ToUnderlying()); if (w == nullptr) { w = WindowCreateAutoPos(WW, WH, &window_staff_overview_events, WC_PEEP, WF_10 | WF_RESIZABLE); - w->number = peep->sprite_index; + w->number = peep->sprite_index.ToUnderlying(); w->page = 0; w->frame_no = 0; w->highlighted_item = 0; @@ -386,7 +386,8 @@ void WindowStaffOverviewMouseup(rct_window* w, rct_widgetindex widgetIndex) w->picked_peep_old_x = peep->x; CoordsXYZ nullLoc{}; nullLoc.SetNull(); - PeepPickupAction pickupAction{ PeepPickupType::Pickup, w->number, nullLoc, network_get_current_player_id() }; + PeepPickupAction pickupAction{ PeepPickupType::Pickup, EntityId::FromUnderlying(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) return; @@ -571,7 +572,7 @@ static void WindowStaffShowLocateDropdown(rct_window* w, rct_widget* widget) static void WindowStaffFollow(rct_window* w) { rct_window* w_main = window_get_main(); - window_follow_sprite(w_main, w->number); + window_follow_sprite(w_main, EntityId::FromUnderlying(w->number)); } /** @@ -603,7 +604,7 @@ static void WindowStaffSetOrder(rct_window* w, int32_t order_id) } uint8_t newOrders = peep->StaffOrders ^ (1 << order_id); - auto staffSetOrdersAction = StaffSetOrdersAction(w->number, newOrders); + auto staffSetOrdersAction = StaffSetOrdersAction(EntityId::FromUnderlying(w->number), newOrders); GameActions::Execute(&staffSetOrdersAction); } @@ -1172,6 +1173,8 @@ void WindowStaffOverviewToolUpdate(rct_window* w, rct_widgetindex widgetIndex, c */ void WindowStaffOverviewToolDown(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords) { + const auto staffEntityId = EntityId::FromUnderlying(w->number); + if (widgetIndex == WIDX_PICKUP) { TileElement* tileElement; @@ -1181,7 +1184,7 @@ void WindowStaffOverviewToolDown(rct_window* w, rct_widgetindex widgetIndex, con return; PeepPickupAction pickupAction{ - PeepPickupType::Place, w->number, { destCoords, tileElement->GetBaseZ() }, network_get_current_player_id() + PeepPickupType::Place, staffEntityId, { destCoords, tileElement->GetBaseZ() }, network_get_current_player_id() }; pickupAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) { if (result->Error != GameActions::Status::Ok) @@ -1198,7 +1201,7 @@ void WindowStaffOverviewToolDown(rct_window* w, rct_widgetindex widgetIndex, con if (destCoords.IsNull()) return; - auto staff = TryGetEntity(w->number); + auto staff = TryGetEntity(staffEntityId); if (staff == nullptr) return; @@ -1211,7 +1214,7 @@ void WindowStaffOverviewToolDown(rct_window* w, rct_widgetindex widgetIndex, con _staffPatrolAreaPaintValue = PatrolAreaValue::SET; } auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction( - w->number, destCoords, + staffEntityId, destCoords, _staffPatrolAreaPaintValue == PatrolAreaValue::SET ? StaffSetPatrolAreaMode::Set : StaffSetPatrolAreaMode::Unset); GameActions::Execute(&staffSetPatrolAreaAction); } @@ -1236,7 +1239,9 @@ void WindowStaffOverviewToolDrag(rct_window* w, rct_widgetindex widgetIndex, con if (destCoords.IsNull()) return; - auto staff = TryGetEntity(w->number); + const auto staffEntityId = EntityId::FromUnderlying(w->number); + + auto* staff = TryGetEntity(staffEntityId); if (staff == nullptr) return; @@ -1247,7 +1252,7 @@ void WindowStaffOverviewToolDrag(rct_window* w, rct_widgetindex widgetIndex, con return; // Since area is already the value we want, skip... auto staffSetPatrolAreaAction = StaffSetPatrolAreaAction( - w->number, destCoords, + staffEntityId, destCoords, _staffPatrolAreaPaintValue == PatrolAreaValue::SET ? StaffSetPatrolAreaMode::Set : StaffSetPatrolAreaMode::Unset); GameActions::Execute(&staffSetPatrolAreaAction); } @@ -1268,9 +1273,10 @@ void WindowStaffOverviewToolAbort(rct_window* w, rct_widgetindex widgetIndex) { if (widgetIndex == WIDX_PICKUP) { - PeepPickupAction pickupAction{ - PeepPickupType::Cancel, w->number, { w->picked_peep_old_x, 0, 0 }, network_get_current_player_id() - }; + PeepPickupAction pickupAction{ PeepPickupType::Cancel, + EntityId::FromUnderlying(w->number), + { w->picked_peep_old_x, 0, 0 }, + network_get_current_player_id() }; GameActions::Execute(&pickupAction); } else if (widgetIndex == WIDX_PATROL) @@ -1290,7 +1296,7 @@ void WindowStaffOverviewTextInput(rct_window* w, rct_widgetindex widgetIndex, ch if (text == nullptr) return; - auto gameAction = StaffSetNameAction(w->number, text); + auto gameAction = StaffSetNameAction(EntityId::FromUnderlying(w->number), text); GameActions::Execute(&gameAction); } @@ -1429,6 +1435,6 @@ void WindowStaffOptionsDropdown(rct_window* w, rct_widgetindex widgetIndex, int3 return; EntertainerCostume costume = _availableCostumes[dropdownIndex]; - auto staffSetCostumeAction = StaffSetCostumeAction(w->number, costume); + auto staffSetCostumeAction = StaffSetCostumeAction(EntityId::FromUnderlying(w->number), costume); GameActions::Execute(&staffSetCostumeAction); } diff --git a/src/openrct2-ui/windows/StaffFirePrompt.cpp b/src/openrct2-ui/windows/StaffFirePrompt.cpp index bb606f3888..8268e43f1d 100644 --- a/src/openrct2-ui/windows/StaffFirePrompt.cpp +++ b/src/openrct2-ui/windows/StaffFirePrompt.cpp @@ -56,7 +56,7 @@ rct_window* WindowStaffFirePromptOpen(Peep* peep) rct_window* w; // Check if the confirm window already exists. - w = window_bring_to_front_by_number(WC_FIRE_PROMPT, peep->sprite_index); + w = window_bring_to_front_by_number(WC_FIRE_PROMPT, peep->sprite_index.ToUnderlying()); if (w != nullptr) { return w; @@ -67,7 +67,7 @@ rct_window* WindowStaffFirePromptOpen(Peep* peep) WindowInitScrollWidgets(w); - w->number = peep->sprite_index; + w->number = peep->sprite_index.ToUnderlying(); return w; } @@ -82,7 +82,7 @@ static void WindowStaffFireMouseup(rct_window* w, rct_widgetindex widgetIndex) { case WIDX_YES: { - auto staffFireAction = StaffFireAction(w->number); + auto staffFireAction = StaffFireAction(EntityId::FromUnderlying(w->number)); GameActions::Execute(&staffFireAction); break; } @@ -100,7 +100,7 @@ static void WindowStaffFirePaint(rct_window* w, rct_drawpixelinfo* dpi) { WindowDrawWidgets(w, dpi); - Peep* peep = GetEntity(w->number); + Peep* peep = GetEntity(EntityId::FromUnderlying(w->number)); auto ft = Formatter(); peep->FormatNameTo(ft); diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index d344de3a1b..a0e9801d58 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -93,7 +93,7 @@ private: rct_string_id ActionHire; }; - std::vector _staffList; + std::vector _staffList; bool _quickFireMode{}; std::optional _highlightedIndex{}; int32_t _selectedTab{}; @@ -490,8 +490,7 @@ public: } } - std::sort( - _staffList.begin(), _staffList.end(), [](const uint16_t a, const uint16_t b) { return peep_compare(a, b) < 0; }); + std::sort(_staffList.begin(), _staffList.end(), [](const auto a, const auto b) { return peep_compare(a, b) < 0; }); } private: diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index de32970cb4..aecd027a80 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -254,9 +254,9 @@ void WindowTitleCommandEditorOpen(TitleSequence* sequence, int32_t index, bool i snprintf(textbox1Buffer, BUF_SIZE, "%d", _command.Milliseconds); break; case TitleScript::Follow: - if (_command.SpriteIndex != SPRITE_INDEX_NULL) + if (!_command.SpriteIndex.IsNull()) { - window_follow_sprite(window, static_cast(_command.SpriteIndex)); + window_follow_sprite(window, _command.SpriteIndex); } break; case TitleScript::Undefined: @@ -432,7 +432,7 @@ static void WindowTitleCommandEditorDropdown(rct_window* w, rct_widgetindex widg switch (widgetIndex) { case WIDX_COMMAND_DROPDOWN: - if (_command.SpriteIndex != SPRITE_INDEX_NULL) + if (!_command.SpriteIndex.IsNull()) { window_unfollow_sprite(w); } @@ -471,7 +471,7 @@ static void WindowTitleCommandEditorDropdown(rct_window* w, rct_widgetindex widg snprintf(textbox1Buffer, BUF_SIZE, "%d", _command.Zoom); break; case TitleScript::Follow: - _command.SpriteIndex = SPRITE_INDEX_NULL; + _command.SpriteIndex = EntityId::GetNull(); _command.SpriteName[0] = '\0'; window_unfollow_sprite(w); // This is incorrect @@ -680,7 +680,7 @@ static void WindowTitleCommandEditorToolDown(rct_window* w, rct_widgetindex widg if (validSprite) { _command.SpriteIndex = entity->sprite_index; - window_follow_sprite(w, static_cast(_command.SpriteIndex)); + window_follow_sprite(w, _command.SpriteIndex); tool_cancel(); w->Invalidate(); } @@ -790,7 +790,7 @@ static void WindowTitleCommandEditorPaint(rct_window* w, rct_drawpixelinfo* dpi) uint8_t colour = COLOUR_BLACK; rct_string_id spriteString = STR_TITLE_COMMAND_EDITOR_FORMAT_SPRITE_NAME; auto ft = Formatter(); - if (_command.SpriteIndex != SPRITE_INDEX_NULL) + if (!_command.SpriteIndex.IsNull()) { window_draw_viewport(dpi, w); ft.Add(_command.SpriteName); diff --git a/src/openrct2-ui/windows/TitleEditor.cpp b/src/openrct2-ui/windows/TitleEditor.cpp index 5c08636095..a1c0ced3d3 100644 --- a/src/openrct2-ui/windows/TitleEditor.cpp +++ b/src/openrct2-ui/windows/TitleEditor.cpp @@ -974,7 +974,7 @@ static void WindowTitleEditorScrollpaintCommands(rct_window* w, rct_drawpixelinf case TitleScript::Follow: { auto commandName = STR_TITLE_EDITOR_COMMAND_FOLLOW; - if (command.SpriteIndex == SPRITE_INDEX_NULL) + if (command.SpriteIndex.IsNull()) { commandName = STR_TITLE_EDITOR_COMMAND_FOLLOW_NO_SPRITE; ft.Add(commandName); diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index bd6d81532d..6b8edd06b6 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -521,7 +521,7 @@ void reset_all_sprite_quadrant_placements() { for (size_t i = 0; i < MAX_ENTITIES; i++) { - auto* spr = GetEntity(i); + auto* spr = GetEntity(EntityId::FromUnderlying(i)); if (spr != nullptr && spr->Type != EntityType::Null) { spr->MoveTo(spr->GetLocation()); diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp index 8a93b07aa9..1cd7e1cae8 100644 --- a/src/openrct2/GameStateSnapshots.cpp +++ b/src/openrct2/GameStateSnapshots.cpp @@ -69,7 +69,7 @@ struct GameStateSnapshot_t } // Must pass a function that can access the sprite. - void SerialiseSprites(std::function getEntity, const size_t numSprites, bool saving) + void SerialiseSprites(std::function getEntity, const size_t numSprites, bool saving) { const bool loading = !saving; @@ -85,7 +85,7 @@ struct GameStateSnapshot_t { for (size_t i = 0; i < numSprites; i++) { - auto entity = getEntity(i); + auto entity = getEntity(EntityId::FromUnderlying(i)); if (entity == nullptr || entity->base.Type == EntityType::Null) continue; indexTable.push_back(static_cast(i)); @@ -111,7 +111,7 @@ struct GameStateSnapshot_t { ds << indexTable[i]; - const uint32_t spriteIdx = indexTable[i]; + const EntityId spriteIdx = EntityId::FromUnderlying(indexTable[i]); EntitySnapshot* entity = getEntity(spriteIdx); if (entity == nullptr) { @@ -184,7 +184,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots virtual void Capture(GameStateSnapshot_t& snapshot) override final { snapshot.SerialiseSprites( - [](const size_t index) { return reinterpret_cast(GetEntity(index)); }, MAX_ENTITIES, true); + [](const EntityId index) { return reinterpret_cast(GetEntity(index)); }, MAX_ENTITIES, true); // log_info("Snapshot size: %u bytes", static_cast(snapshot.storedSprites.GetLength())); } @@ -218,7 +218,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots sprite.base.Type = EntityType::Null; } - snapshot.SerialiseSprites([&spriteList](const size_t index) { return &spriteList[index]; }, MAX_ENTITIES, false); + snapshot.SerialiseSprites([&spriteList](const EntityId index) { return &spriteList[index.ToUnderlying()]; }, MAX_ENTITIES, false); return spriteList; } diff --git a/src/openrct2/Identifiers.h b/src/openrct2/Identifiers.h index 53e5eb4c3b..e33a8f38f8 100644 --- a/src/openrct2/Identifiers.h +++ b/src/openrct2/Identifiers.h @@ -19,3 +19,5 @@ using ParkEntranceIndex = TIdentifier::max using BannerIndex = TIdentifier::max(), struct BannerIndexTag>; using RideId = TIdentifier::max(), struct RideIdTag>; + +using EntityId = TIdentifier::max(), struct EntityIdTag>; diff --git a/src/openrct2/actions/BalloonPressAction.cpp b/src/openrct2/actions/BalloonPressAction.cpp index 13e9c82215..a7bf53aedd 100644 --- a/src/openrct2/actions/BalloonPressAction.cpp +++ b/src/openrct2/actions/BalloonPressAction.cpp @@ -13,7 +13,7 @@ #include "../entity/EntityRegistry.h" #include "GameAction.h" -BalloonPressAction::BalloonPressAction(uint16_t spriteIndex) +BalloonPressAction::BalloonPressAction(EntityId spriteIndex) : _spriteIndex(spriteIndex) { } diff --git a/src/openrct2/actions/BalloonPressAction.h b/src/openrct2/actions/BalloonPressAction.h index 6e126b3c3c..953b3b30fd 100644 --- a/src/openrct2/actions/BalloonPressAction.h +++ b/src/openrct2/actions/BalloonPressAction.h @@ -9,15 +9,16 @@ #pragma once +#include "../Identifiers.h" #include "GameAction.h" class BalloonPressAction final : public GameActionBase { - uint16_t _spriteIndex{ SPRITE_INDEX_NULL }; + EntityId _spriteIndex{ EntityId::GetNull() }; public: BalloonPressAction() = default; - BalloonPressAction(uint16_t spriteIndex); + BalloonPressAction(EntityId spriteIndex); void AcceptParameters(GameActionParameterVisitor& visitor) override; diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index 2ccb75cad0..02b3e69713 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -110,7 +110,7 @@ void ride_action_modify(Ride* ride, int32_t modifyType, int32_t flags) #pragma region GuestSetName -void guest_set_name(uint16_t spriteIndex, const char* name) +void guest_set_name(EntityId spriteIndex, const char* name) { auto gameAction = GuestSetNameAction(spriteIndex, name); GameActions::Execute(&gameAction); diff --git a/src/openrct2/actions/GuestSetFlagsAction.cpp b/src/openrct2/actions/GuestSetFlagsAction.cpp index d3fd1747a3..9366812d38 100644 --- a/src/openrct2/actions/GuestSetFlagsAction.cpp +++ b/src/openrct2/actions/GuestSetFlagsAction.cpp @@ -13,7 +13,7 @@ #include "../OpenRCT2.h" #include "../entity/EntityRegistry.h" -GuestSetFlagsAction::GuestSetFlagsAction(uint16_t peepId, uint32_t flags) +GuestSetFlagsAction::GuestSetFlagsAction(EntityId peepId, uint32_t flags) : _peepId(peepId) , _newFlags(flags) { @@ -42,7 +42,7 @@ GameActions::Result GuestSetFlagsAction::Query() const auto* peep = TryGetEntity(_peepId); if (peep == nullptr) { - log_error("Used invalid sprite index for peep: %u", static_cast(_peepId)); + log_error("Used invalid sprite index for peep: %u", _peepId.ToUnderlying()); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_CHANGE_THIS, STR_NONE); } return GameActions::Result(); @@ -53,7 +53,7 @@ GameActions::Result GuestSetFlagsAction::Execute() const auto* peep = TryGetEntity(_peepId); if (peep == nullptr) { - log_error("Used invalid sprite index for peep: %u", static_cast(_peepId)); + log_error("Used invalid sprite index for peep: %u", _peepId.ToUnderlying()); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_CHANGE_THIS, STR_NONE); } diff --git a/src/openrct2/actions/GuestSetFlagsAction.h b/src/openrct2/actions/GuestSetFlagsAction.h index 9cc5b4384f..1bfc75493f 100644 --- a/src/openrct2/actions/GuestSetFlagsAction.h +++ b/src/openrct2/actions/GuestSetFlagsAction.h @@ -14,12 +14,12 @@ class GuestSetFlagsAction final : public GameActionBase { private: - uint16_t _peepId{ SPRITE_INDEX_NULL }; + EntityId _peepId{ EntityId::GetNull() }; uint32_t _newFlags{}; public: GuestSetFlagsAction() = default; - GuestSetFlagsAction(uint16_t peepId, uint32_t flags); + GuestSetFlagsAction(EntityId peepId, uint32_t flags); void AcceptParameters(GameActionParameterVisitor& visitor) override; diff --git a/src/openrct2/actions/GuestSetNameAction.cpp b/src/openrct2/actions/GuestSetNameAction.cpp index 2dfdf1ea5d..fd5e4e70a4 100644 --- a/src/openrct2/actions/GuestSetNameAction.cpp +++ b/src/openrct2/actions/GuestSetNameAction.cpp @@ -20,13 +20,13 @@ #include "../windows/Intent.h" #include "../world/Park.h" -GuestSetNameAction::GuestSetNameAction(uint16_t spriteIndex, const std::string& name) +GuestSetNameAction::GuestSetNameAction(EntityId spriteIndex, const std::string& name) : _spriteIndex(spriteIndex) , _name(name) { } -uint16_t GuestSetNameAction::GetSpriteIndex() const +EntityId GuestSetNameAction::GetSpriteIndex() const { return _spriteIndex; } @@ -56,7 +56,7 @@ void GuestSetNameAction::Serialise(DataSerialiser& stream) GameActions::Result GuestSetNameAction::Query() const { - if (_spriteIndex >= MAX_ENTITIES) + if (_spriteIndex.ToUnderlying() >= MAX_ENTITIES || _spriteIndex.IsNull()) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_NAME_GUEST, STR_NONE); } diff --git a/src/openrct2/actions/GuestSetNameAction.h b/src/openrct2/actions/GuestSetNameAction.h index 347bc6b079..a1ca8f485f 100644 --- a/src/openrct2/actions/GuestSetNameAction.h +++ b/src/openrct2/actions/GuestSetNameAction.h @@ -14,14 +14,14 @@ class GuestSetNameAction final : public GameActionBase { private: - uint16_t _spriteIndex{ SPRITE_INDEX_NULL }; + EntityId _spriteIndex{ EntityId::GetNull() }; std::string _name; public: GuestSetNameAction() = default; - GuestSetNameAction(uint16_t spriteIndex, const std::string& name); + GuestSetNameAction(EntityId spriteIndex, const std::string& name); - uint16_t GetSpriteIndex() const; + EntityId GetSpriteIndex() const; std::string GetGuestName() const; void AcceptParameters(GameActionParameterVisitor& visitor) override; diff --git a/src/openrct2/actions/PeepPickupAction.cpp b/src/openrct2/actions/PeepPickupAction.cpp index 27f134b530..80b3916661 100644 --- a/src/openrct2/actions/PeepPickupAction.cpp +++ b/src/openrct2/actions/PeepPickupAction.cpp @@ -15,7 +15,7 @@ #include "../network/network.h" #include "../util/Util.h" -PeepPickupAction::PeepPickupAction(PeepPickupType type, uint32_t spriteId, const CoordsXYZ& loc, NetworkPlayerId_t owner) +PeepPickupAction::PeepPickupAction(PeepPickupType type, EntityId spriteId, const CoordsXYZ& loc, NetworkPlayerId_t owner) : _type(type) , _spriteId(spriteId) , _loc(loc) @@ -37,7 +37,7 @@ void PeepPickupAction::Serialise(DataSerialiser& stream) GameActions::Result PeepPickupAction::Query() const { - if (_spriteId >= MAX_ENTITIES || _spriteId == SPRITE_INDEX_NULL) + if (_spriteId.IsNull()) { log_error("Failed to pick up peep for sprite %d", _spriteId); return GameActions::Result(GameActions::Status::InvalidParameters, STR_ERR_CANT_PLACE_PERSON_HERE, STR_NONE); diff --git a/src/openrct2/actions/PeepPickupAction.h b/src/openrct2/actions/PeepPickupAction.h index 3dc6dbfd16..edb777a848 100644 --- a/src/openrct2/actions/PeepPickupAction.h +++ b/src/openrct2/actions/PeepPickupAction.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "GameAction.h" enum class PeepPickupType : uint8_t @@ -23,13 +24,13 @@ class PeepPickupAction final : public GameActionBase { private: PeepPickupType _type{ PeepPickupType::Count }; - uint32_t _spriteId{ SPRITE_INDEX_NULL }; + EntityId _spriteId{ EntityId::GetNull() }; CoordsXYZ _loc; NetworkPlayerId_t _owner{ -1 }; public: PeepPickupAction() = default; - PeepPickupAction(PeepPickupType type, uint32_t spriteId, const CoordsXYZ& loc, NetworkPlayerId_t owner); + PeepPickupAction(PeepPickupType type, EntityId spriteId, const CoordsXYZ& loc, NetworkPlayerId_t owner); uint16_t GetActionFlags() const override; diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 0ebdf369d7..3cd2d40b1f 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -147,10 +147,7 @@ GameActions::Result RideCreateAction::Execute() const ride->stations[i].QueueTime = 0; } - for (auto& vehicle : ride->vehicles) - { - vehicle = SPRITE_INDEX_NULL; - } + std::fill(std::begin(ride->vehicles), std::end(ride->vehicles), EntityId::GetNull()); ride->status = RideStatus::Closed; ride->lifecycle_flags = 0; diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.cpp b/src/openrct2/actions/RideEntranceExitPlaceAction.cpp index 6c5da7146b..45a9501690 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.cpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.cpp @@ -196,7 +196,7 @@ GameActions::Result RideEntranceExitPlaceAction::Execute() const else { ride_set_entrance_location(ride, _stationNum, TileCoordsXYZD(CoordsXYZD{ _loc, z, entranceElement->GetDirection() })); - ride->stations[_stationNum].LastPeepInQueue = SPRITE_INDEX_NULL; + ride->stations[_stationNum].LastPeepInQueue = EntityId::GetNull(); ride->stations[_stationNum].QueueLength = 0; map_animation_create(MAP_ANIMATION_TYPE_RIDE_ENTRANCE, { _loc, z }); diff --git a/src/openrct2/actions/RideSetStatusAction.cpp b/src/openrct2/actions/RideSetStatusAction.cpp index 6892bba763..ce0c49515e 100644 --- a/src/openrct2/actions/RideSetStatusAction.cpp +++ b/src/openrct2/actions/RideSetStatusAction.cpp @@ -154,7 +154,7 @@ GameActions::Result RideSetStatusAction::Execute() const ride->status = RideStatus::Closed; ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING; - ride->race_winner = SPRITE_INDEX_NULL; + ride->race_winner = EntityId::GetNull(); ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; window_invalidate_by_number(WC_RIDE, _rideIndex.ToUnderlying()); break; @@ -173,7 +173,7 @@ GameActions::Result RideSetStatusAction::Execute() const ride->status = _status; ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING; - ride->race_winner = SPRITE_INDEX_NULL; + ride->race_winner = EntityId::GetNull(); ride->current_issues = 0; ride->last_issue_time = 0; ride->GetMeasurement(); @@ -219,7 +219,7 @@ GameActions::Result RideSetStatusAction::Execute() const return res; } - ride->race_winner = SPRITE_INDEX_NULL; + ride->race_winner = EntityId::GetNull(); ride->status = _status; ride->current_issues = 0; ride->last_issue_time = 0; diff --git a/src/openrct2/actions/SetCheatAction.cpp b/src/openrct2/actions/SetCheatAction.cpp index 8719fb552c..cad95b5da3 100644 --- a/src/openrct2/actions/SetCheatAction.cpp +++ b/src/openrct2/actions/SetCheatAction.cpp @@ -633,7 +633,7 @@ void SetCheatAction::RemoveAllGuests() const for (size_t stationIndex = 0; stationIndex < OpenRCT2::Limits::MaxStationsPerRide; stationIndex++) { ride.stations[stationIndex].QueueLength = 0; - ride.stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; + ride.stations[stationIndex].LastPeepInQueue = EntityId::GetNull(); } for (auto trainIndex : ride.vehicles) @@ -652,7 +652,7 @@ void SetCheatAction::RemoveAllGuests() const vehicle->ApplyMass(-peep->Mass); } } - peepInTrainIndex = SPRITE_INDEX_NULL; + peepInTrainIndex = EntityId::GetNull(); } vehicle->num_peeps = 0; diff --git a/src/openrct2/actions/StaffFireAction.cpp b/src/openrct2/actions/StaffFireAction.cpp index b53436fbba..6abe354781 100644 --- a/src/openrct2/actions/StaffFireAction.cpp +++ b/src/openrct2/actions/StaffFireAction.cpp @@ -13,7 +13,7 @@ #include "../entity/Staff.h" #include "../interface/Window.h" -StaffFireAction::StaffFireAction(uint16_t spriteId) +StaffFireAction::StaffFireAction(EntityId spriteId) : _spriteId(spriteId) { } @@ -31,7 +31,7 @@ void StaffFireAction::Serialise(DataSerialiser& stream) GameActions::Result StaffFireAction::Query() const { - if (_spriteId >= MAX_ENTITIES) + if (_spriteId.ToUnderlying() >= MAX_ENTITIES || _spriteId.IsNull()) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); diff --git a/src/openrct2/actions/StaffFireAction.h b/src/openrct2/actions/StaffFireAction.h index 7caebf323e..2869f314ae 100644 --- a/src/openrct2/actions/StaffFireAction.h +++ b/src/openrct2/actions/StaffFireAction.h @@ -14,11 +14,11 @@ class StaffFireAction final : public GameActionBase { private: - uint16_t _spriteId{ SPRITE_INDEX_NULL }; + EntityId _spriteId{ EntityId::GetNull() }; public: StaffFireAction() = default; - StaffFireAction(uint16_t spriteId); + StaffFireAction(EntityId spriteId); uint16_t GetActionFlags() const override; diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index 51f33f051f..319265d73a 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -123,7 +123,7 @@ GameActions::Result StaffHireNewAction::QueryExecute(bool execute) const // In query we just want to see if we can obtain a sprite slot. EntityRemove(newPeep); - res.SetData(StaffHireNewActionResult{ SPRITE_INDEX_NULL }); + res.SetData(StaffHireNewActionResult{ EntityId::GetNull() }); } else { diff --git a/src/openrct2/actions/StaffHireNewAction.h b/src/openrct2/actions/StaffHireNewAction.h index 6a78407c39..84ef323e5a 100644 --- a/src/openrct2/actions/StaffHireNewAction.h +++ b/src/openrct2/actions/StaffHireNewAction.h @@ -14,7 +14,7 @@ struct StaffHireNewActionResult { - uint16_t StaffEntityId = SPRITE_INDEX_NULL; + EntityId StaffEntityId = EntityId::GetNull(); }; class StaffHireNewAction final : public GameActionBase diff --git a/src/openrct2/actions/StaffSetCostumeAction.cpp b/src/openrct2/actions/StaffSetCostumeAction.cpp index 294339695c..2944981c02 100644 --- a/src/openrct2/actions/StaffSetCostumeAction.cpp +++ b/src/openrct2/actions/StaffSetCostumeAction.cpp @@ -36,7 +36,7 @@ constexpr const bool peep_slow_walking_types[] = { true, // PeepSpriteType::Balloon }; -StaffSetCostumeAction::StaffSetCostumeAction(uint16_t spriteIndex, EntertainerCostume costume) +StaffSetCostumeAction::StaffSetCostumeAction(EntityId spriteIndex, EntertainerCostume costume) : _spriteIndex(spriteIndex) , _costume(costume) { @@ -56,7 +56,7 @@ void StaffSetCostumeAction::Serialise(DataSerialiser& stream) GameActions::Result StaffSetCostumeAction::Query() const { - if (_spriteIndex >= MAX_ENTITIES) + if (_spriteIndex.ToUnderlying() >= MAX_ENTITIES || _spriteIndex.IsNull()) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); } diff --git a/src/openrct2/actions/StaffSetCostumeAction.h b/src/openrct2/actions/StaffSetCostumeAction.h index f9f47c8cc2..823737abc2 100644 --- a/src/openrct2/actions/StaffSetCostumeAction.h +++ b/src/openrct2/actions/StaffSetCostumeAction.h @@ -15,12 +15,12 @@ class StaffSetCostumeAction final : public GameActionBase { private: - uint16_t _spriteIndex{ SPRITE_INDEX_NULL }; + EntityId _spriteIndex{ EntityId::GetNull() }; EntertainerCostume _costume = EntertainerCostume::Count; public: StaffSetCostumeAction() = default; - StaffSetCostumeAction(uint16_t spriteIndex, EntertainerCostume costume); + StaffSetCostumeAction(EntityId spriteIndex, EntertainerCostume costume); uint16_t GetActionFlags() const override; diff --git a/src/openrct2/actions/StaffSetNameAction.cpp b/src/openrct2/actions/StaffSetNameAction.cpp index 33e21ad200..07f281b6fb 100644 --- a/src/openrct2/actions/StaffSetNameAction.cpp +++ b/src/openrct2/actions/StaffSetNameAction.cpp @@ -21,7 +21,7 @@ #include "../windows/Intent.h" #include "../world/Park.h" -StaffSetNameAction::StaffSetNameAction(uint16_t spriteIndex, const std::string& name) +StaffSetNameAction::StaffSetNameAction(EntityId spriteIndex, const std::string& name) : _spriteIndex(spriteIndex) , _name(name) { @@ -41,7 +41,7 @@ void StaffSetNameAction::Serialise(DataSerialiser& stream) GameActions::Result StaffSetNameAction::Query() const { - if (_spriteIndex >= MAX_ENTITIES) + if (_spriteIndex.ToUnderlying() >= MAX_ENTITIES || _spriteIndex.IsNull()) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_STAFF_ERROR_CANT_NAME_STAFF_MEMBER, STR_NONE); } diff --git a/src/openrct2/actions/StaffSetNameAction.h b/src/openrct2/actions/StaffSetNameAction.h index 7cf8804fa6..59ac9ad6ce 100644 --- a/src/openrct2/actions/StaffSetNameAction.h +++ b/src/openrct2/actions/StaffSetNameAction.h @@ -14,12 +14,12 @@ class StaffSetNameAction final : public GameActionBase { private: - uint16_t _spriteIndex{ SPRITE_INDEX_NULL }; + EntityId _spriteIndex{ EntityId::GetNull() }; std::string _name; public: StaffSetNameAction() = default; - StaffSetNameAction(uint16_t spriteIndex, const std::string& name); + StaffSetNameAction(EntityId spriteIndex, const std::string& name); uint16_t GetActionFlags() const override; void Serialise(DataSerialiser& stream) override; diff --git a/src/openrct2/actions/StaffSetOrdersAction.cpp b/src/openrct2/actions/StaffSetOrdersAction.cpp index 8070041c77..2ed8b0b271 100644 --- a/src/openrct2/actions/StaffSetOrdersAction.cpp +++ b/src/openrct2/actions/StaffSetOrdersAction.cpp @@ -17,7 +17,7 @@ #include "../localisation/StringIds.h" #include "../windows/Intent.h" -StaffSetOrdersAction::StaffSetOrdersAction(uint16_t spriteIndex, uint8_t ordersId) +StaffSetOrdersAction::StaffSetOrdersAction(EntityId spriteIndex, uint8_t ordersId) : _spriteIndex(spriteIndex) , _ordersId(ordersId) { @@ -37,7 +37,7 @@ void StaffSetOrdersAction::Serialise(DataSerialiser& stream) GameActions::Result StaffSetOrdersAction::Query() const { - if (_spriteIndex >= MAX_ENTITIES) + if (_spriteIndex.ToUnderlying() >= MAX_ENTITIES || _spriteIndex.IsNull()) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); } diff --git a/src/openrct2/actions/StaffSetOrdersAction.h b/src/openrct2/actions/StaffSetOrdersAction.h index 078d1eb82a..5d81ded28c 100644 --- a/src/openrct2/actions/StaffSetOrdersAction.h +++ b/src/openrct2/actions/StaffSetOrdersAction.h @@ -14,12 +14,12 @@ class StaffSetOrdersAction final : public GameActionBase { private: - uint16_t _spriteIndex{ SPRITE_INDEX_NULL }; + EntityId _spriteIndex{ EntityId::GetNull() }; uint8_t _ordersId{}; public: StaffSetOrdersAction() = default; - StaffSetOrdersAction(uint16_t spriteIndex, uint8_t ordersId); + StaffSetOrdersAction(EntityId spriteIndex, uint8_t ordersId); uint16_t GetActionFlags() const override; diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.cpp b/src/openrct2/actions/StaffSetPatrolAreaAction.cpp index c95503da85..ad2aa456cd 100644 --- a/src/openrct2/actions/StaffSetPatrolAreaAction.cpp +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.cpp @@ -14,7 +14,7 @@ #include "../entity/Staff.h" #include "../interface/Window.h" -StaffSetPatrolAreaAction::StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode) +StaffSetPatrolAreaAction::StaffSetPatrolAreaAction(EntityId spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode) : _spriteId(spriteId) , _loc(loc) , _mode(mode) @@ -34,7 +34,7 @@ void StaffSetPatrolAreaAction::Serialise(DataSerialiser& stream) GameActions::Result StaffSetPatrolAreaAction::Query() const { - if (_spriteId >= MAX_ENTITIES) + if (_spriteId.ToUnderlying() >= MAX_ENTITIES || _spriteId.IsNull()) { log_error("Invalid spriteId. spriteId = %u", _spriteId); return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); diff --git a/src/openrct2/actions/StaffSetPatrolAreaAction.h b/src/openrct2/actions/StaffSetPatrolAreaAction.h index e18a851977..939f608a73 100644 --- a/src/openrct2/actions/StaffSetPatrolAreaAction.h +++ b/src/openrct2/actions/StaffSetPatrolAreaAction.h @@ -21,13 +21,13 @@ enum class StaffSetPatrolAreaMode : uint8_t class StaffSetPatrolAreaAction final : public GameActionBase { private: - uint16_t _spriteId{ SPRITE_INDEX_NULL }; + EntityId _spriteId{ EntityId::GetNull() }; CoordsXY _loc; StaffSetPatrolAreaMode _mode; public: StaffSetPatrolAreaAction() = default; - StaffSetPatrolAreaAction(uint16_t spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode); + StaffSetPatrolAreaAction(EntityId spriteId, const CoordsXY& loc, const StaffSetPatrolAreaMode mode); uint16_t GetActionFlags() const override; diff --git a/src/openrct2/audio/audio.h b/src/openrct2/audio/audio.h index 8c05248d81..7480b0a2a8 100644 --- a/src/openrct2/audio/audio.h +++ b/src/openrct2/audio/audio.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "../common.h" #include "../ride/RideTypes.h" diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index 7916508cc6..4a6d86a9b9 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -329,6 +329,12 @@ template struct DataSerializerTraits_t : public D { }; +template +struct DataSerializerTraits_t[_Size]> + : public DataSerializerTraitsPODArray, _Size> +{ +}; + template struct DataSerializerTraits_t> { static void encode(OpenRCT2::IStream* stream, const std::array<_Ty, _Size>& val) diff --git a/src/openrct2/core/GroupVector.hpp b/src/openrct2/core/GroupVector.hpp index 195e669783..89157a7dc3 100644 --- a/src/openrct2/core/GroupVector.hpp +++ b/src/openrct2/core/GroupVector.hpp @@ -18,20 +18,22 @@ template class GroupVector public: bool Contains(Handle handle, V value) { - if (handle >= _data.size()) + const auto index = static_cast(handle); + if (index >= _data.size()) return false; - const auto& values = _data[handle]; + const auto& values = _data[index]; return std::find(values.begin(), values.end(), value) != values.end(); } void Add(Handle handle, V value) { - if (handle >= _data.size()) + const auto index = static_cast(handle); + if (index >= _data.size()) { - _data.resize(handle + 1); + _data.resize(index + 1); } - auto& values = _data[handle]; + auto& values = _data[index]; auto it = std::find(values.begin(), values.end(), value); if (it != values.end()) @@ -42,18 +44,20 @@ public: void Set(Handle handle, std::vector&& values) { - if (handle >= _data.size()) + const auto index = static_cast(handle); + if (index >= _data.size()) { - _data.resize(handle + 1); + _data.resize(index + 1); } - _data[handle] = values; + _data[index] = values; } std::vector* GetAll(Handle handle) { - if (handle < _data.size()) + const auto index = static_cast(handle); + if (index < _data.size()) { - return &_data[handle]; + return &_data[index]; } return nullptr; } @@ -65,9 +69,10 @@ public: void RemoveHandle(Handle handle) { - if (handle < _data.size()) + const auto index = static_cast(handle); + if (index < _data.size()) { - _data[handle].clear(); + _data[index].clear(); } } diff --git a/src/openrct2/core/Identifier.hpp b/src/openrct2/core/Identifier.hpp index 40be23d05e..540ebe58c1 100644 --- a/src/openrct2/core/Identifier.hpp +++ b/src/openrct2/core/Identifier.hpp @@ -47,6 +47,12 @@ public: return static_cast(_handle); } + // Support for static_cast. + explicit operator std::size_t() const noexcept + { + return static_cast(ToUnderlying()); + } + constexpr bool IsNull() const noexcept { return _handle == ValueType::Null; @@ -71,4 +77,14 @@ public: { return _handle != other._handle; } + + constexpr bool operator<(const TIdentifier& other) const noexcept + { + return ToUnderlying() < other.ToUnderlying(); + } + + constexpr bool operator>(const TIdentifier& other) const noexcept + { + return ToUnderlying() > other.ToUnderlying(); + } }; diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index 699959e918..8882aef305 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -677,7 +677,7 @@ static void LightfxAdd3DLight(const CoordsXYZ& loc, const LightType lightType) void LightfxAdd3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType) { - LightfxAdd3DLight(entity.sprite_index, LightFXQualifier::Entity, id, loc, lightType); + LightfxAdd3DLight(entity.sprite_index.ToUnderlying(), LightFXQualifier::Entity, id, loc, lightType); } void lightfx_add_3d_light_magic_from_drawing_tile( @@ -736,7 +736,7 @@ void lightfx_add_lights_magic_vehicle(const Vehicle* vehicle) case RIDE_TYPE_WATER_COASTER: { Vehicle* vehicle_draw = vehicle->TrainHead(); - auto nextVeh = GetEntity(vehicle_draw->next_vehicle_on_train); + auto* nextVeh = GetEntity(vehicle_draw->next_vehicle_on_train); if (nextVeh != nullptr) { vehicle_draw = nextVeh; diff --git a/src/openrct2/entity/Balloon.cpp b/src/openrct2/entity/Balloon.cpp index c5cc3403e9..d0cb58732e 100644 --- a/src/openrct2/entity/Balloon.cpp +++ b/src/openrct2/entity/Balloon.cpp @@ -65,7 +65,7 @@ void Balloon::Press() // There is a random chance that pressing the balloon will not pop it // and instead shift it slightly uint32_t random = scenario_rand(); - if ((sprite_index & 7) || (random & 0xFFFF) < 0x2000) + if ((sprite_index.ToUnderlying() & 7) || (random & 0xFFFF) < 0x2000) { Pop(); } diff --git a/src/openrct2/entity/Duck.cpp b/src/openrct2/entity/Duck.cpp index 96558c7317..ef834a3558 100644 --- a/src/openrct2/entity/Duck.cpp +++ b/src/openrct2/entity/Duck.cpp @@ -150,7 +150,7 @@ void Duck::UpdateFlyToWater() void Duck::UpdateSwim() { - if (((gCurrentTicks + sprite_index) & 3) != 0) + if (((gCurrentTicks + sprite_index.ToUnderlying()) & 3) != 0) return; uint32_t randomNumber = scenario_rand(); diff --git a/src/openrct2/entity/EntityBase.h b/src/openrct2/entity/EntityBase.h index 04e6d6eec7..391f72d997 100644 --- a/src/openrct2/entity/EntityBase.h +++ b/src/openrct2/entity/EntityBase.h @@ -1,5 +1,6 @@ #pragma once +#include "../Identifiers.h" #include "../common.h" #include "../world/Location.hpp" @@ -25,7 +26,7 @@ enum class EntityType : uint8_t struct EntityBase { EntityType Type; - uint16_t sprite_index; + EntityId sprite_index; int32_t x; int32_t y; int32_t z; diff --git a/src/openrct2/entity/EntityList.h b/src/openrct2/entity/EntityList.h index ca181c6b34..2752dc2446 100644 --- a/src/openrct2/entity/EntityList.h +++ b/src/openrct2/entity/EntityList.h @@ -18,22 +18,22 @@ #include #include -const std::list& GetEntityList(const EntityType id); +const std::list& GetEntityList(const EntityType id); uint16_t GetEntityListCount(EntityType list); uint16_t GetMiscEntityCount(); uint16_t GetNumFreeEntities(); -const std::vector& GetEntityTileList(const CoordsXY& spritePos); +const std::vector& GetEntityTileList(const CoordsXY& spritePos); template class EntityTileIterator { private: - std::vector::const_iterator iter; - std::vector::const_iterator end; + std::vector::const_iterator iter; + std::vector::const_iterator end; T* Entity = nullptr; public: - EntityTileIterator(std::vector::const_iterator _iter, std::vector::const_iterator _end) + EntityTileIterator(std::vector::const_iterator _iter, std::vector::const_iterator _end) : iter(_iter) , end(_end) { @@ -79,7 +79,7 @@ public: template class EntityTileList { private: - const std::vector& vec; + const std::vector& vec; public: EntityTileList(const CoordsXY& loc) @@ -100,12 +100,12 @@ public: template class EntityListIterator { private: - std::list::const_iterator iter; - std::list::const_iterator end; + std::list::const_iterator iter; + std::list::const_iterator end; T* Entity = nullptr; public: - EntityListIterator(std::list::const_iterator _iter, std::list::const_iterator _end) + EntityListIterator(std::list::const_iterator _iter, std::list::const_iterator _end) : iter(_iter) , end(_end) { @@ -152,7 +152,7 @@ template class EntityList { private: using EntityListIterator_t = EntityListIterator; - const std::list& vec; + const std::list& vec; public: EntityList() diff --git a/src/openrct2/entity/EntityRegistry.cpp b/src/openrct2/entity/EntityRegistry.cpp index 4a93ade023..f8666d714b 100644 --- a/src/openrct2/entity/EntityRegistry.cpp +++ b/src/openrct2/entity/EntityRegistry.cpp @@ -46,15 +46,15 @@ union Entity }; static Entity _entities[MAX_ENTITIES]{}; -static std::array, EnumValue(EntityType::Count)> gEntityLists; -static std::vector _freeIdList; +static std::array, EnumValue(EntityType::Count)> gEntityLists; +static std::vector _freeIdList; static bool _entityFlashingList[MAX_ENTITIES]; constexpr const uint32_t SPATIAL_INDEX_SIZE = (MAXIMUM_MAP_SIZE_TECHNICAL * MAXIMUM_MAP_SIZE_TECHNICAL) + 1; constexpr const uint32_t SPATIAL_INDEX_LOCATION_NULL = SPATIAL_INDEX_SIZE - 1; -static std::array, SPATIAL_INDEX_SIZE> gEntitySpatialIndex; +static std::array, SPATIAL_INDEX_SIZE> gEntitySpatialIndex; static void FreeEntity(EntityBase& entity); @@ -117,22 +117,23 @@ std::string EntitiesChecksum::ToString() const return result; } -EntityBase* TryGetEntity(size_t entityIndex) +EntityBase* TryGetEntity(EntityId entityIndex) { - return entityIndex >= MAX_ENTITIES ? nullptr : &_entities[entityIndex].base; + const auto idx = entityIndex.ToUnderlying(); + return idx >= MAX_ENTITIES ? nullptr : &_entities[idx].base; } -EntityBase* GetEntity(size_t entityIndex) +EntityBase* GetEntity(EntityId entityIndex) { - if (entityIndex == SPRITE_INDEX_NULL) + if (entityIndex.IsNull()) { return nullptr; } - openrct2_assert(entityIndex < MAX_ENTITIES, "Tried getting entity %u", entityIndex); + openrct2_assert(entityIndex.ToUnderlying() < MAX_ENTITIES, "Tried getting entity %u", entityIndex.ToUnderlying()); return TryGetEntity(entityIndex); } -const std::vector& GetEntityTileList(const CoordsXY& spritePos) +const std::vector& GetEntityTileList(const CoordsXY& spritePos) { return gEntitySpatialIndex[GetSpatialIndexOffset(spritePos)]; } @@ -148,13 +149,17 @@ static void ResetEntityLists() static void ResetFreeIds() { _freeIdList.clear(); - _freeIdList.resize(MAX_ENTITIES); + // List needs to be back to front to simplify removing - std::iota(std::rbegin(_freeIdList), std::rend(_freeIdList), 0); + auto nextId = 0; + std::for_each(std::rbegin(_freeIdList), std::rend(_freeIdList), [&](auto& elem) { + elem = EntityId::FromUnderlying(nextId); + nextId++; + }); } -const std::list& GetEntityList(const EntityType id) +const std::list& GetEntityList(const EntityType id) { return gEntityLists[EnumValue(id)]; } @@ -170,7 +175,7 @@ void ResetAllEntities() // Free all associated Entity pointers prior to zeroing memory for (int32_t i = 0; i < MAX_ENTITIES; ++i) { - auto* spr = GetEntity(i); + auto* spr = GetEntity(EntityId::FromUnderlying(i)); if (spr == nullptr) { continue; @@ -183,13 +188,13 @@ void ResetAllEntities() OpenRCT2::RideUse::GetTypeHistory().Clear(); for (int32_t i = 0; i < MAX_ENTITIES; ++i) { - auto* spr = GetEntity(i); + auto* spr = GetEntity(EntityId::FromUnderlying(i)); if (spr == nullptr) { continue; } spr->Type = EntityType::Null; - spr->sprite_index = i; + spr->sprite_index = EntityId::FromUnderlying(i); _entityFlashingList[i] = false; } @@ -214,7 +219,7 @@ void ResetEntitySpatialIndices() } for (size_t i = 0; i < MAX_ENTITIES; i++) { - auto* spr = GetEntity(i); + auto* spr = GetEntity(EntityId::FromUnderlying(i)); if (spr != nullptr && spr->Type != EntityType::Null) { EntitySpatialInsert(spr, { spr->x, spr->y }); @@ -259,8 +264,8 @@ EntitiesChecksum GetAllEntitiesChecksum() static void EntityReset(EntityBase* entity) { // Need to retain how the sprite is linked in lists - uint16_t entityIndex = entity->sprite_index; - _entityFlashingList[entityIndex] = false; + auto entityIndex = entity->sprite_index; + _entityFlashingList[entityIndex.ToUnderlying()] = false; Entity* spr = reinterpret_cast(entity); *spr = Entity(); @@ -277,7 +282,7 @@ static void AddToEntityList(EntityBase* entity) list.insert(std::lower_bound(std::begin(list), std::end(list), entity->sprite_index), entity->sprite_index); } -static void AddToFreeList(uint16_t index) +static void AddToFreeList(EntityId index) { // Free list must be in reverse sprite_index order to prevent desync issues _freeIdList.insert(std::upper_bound(std::rbegin(_freeIdList), std::rend(_freeIdList), index).base(), index); @@ -357,7 +362,7 @@ EntityBase* CreateEntity(EntityType type) return entity; } -EntityBase* CreateEntityAt(const uint16_t index, const EntityType type) +EntityBase* CreateEntityAt(const EntityId index, const EntityType type) { auto id = std::lower_bound(std::rbegin(_freeIdList), std::rend(_freeIdList), index); if (id == std::rend(_freeIdList) || *id != index) @@ -544,12 +549,12 @@ uint16_t RemoveFloatingEntities() void EntitySetFlashing(EntityBase* entity, bool flashing) { - assert(entity->sprite_index < MAX_ENTITIES); - _entityFlashingList[entity->sprite_index] = flashing; + assert(entity->sprite_index.ToUnderlying() < MAX_ENTITIES); + _entityFlashingList[entity->sprite_index.ToUnderlying()] = flashing; } bool EntityGetFlashing(EntityBase* entity) { - assert(entity->sprite_index < MAX_ENTITIES); - return _entityFlashingList[entity->sprite_index]; + assert(entity->sprite_index.ToUnderlying() < MAX_ENTITIES); + return _entityFlashingList[entity->sprite_index.ToUnderlying()]; } diff --git a/src/openrct2/entity/EntityRegistry.h b/src/openrct2/entity/EntityRegistry.h index 458129ca26..8ae1f71ffa 100644 --- a/src/openrct2/entity/EntityRegistry.h +++ b/src/openrct2/entity/EntityRegistry.h @@ -16,17 +16,17 @@ constexpr uint16_t MAX_ENTITIES = 65535; -EntityBase* GetEntity(size_t sprite_idx); +EntityBase* GetEntity(EntityId sprite_idx); -template T* GetEntity(size_t sprite_idx) +template T* GetEntity(EntityId sprite_idx) { auto spr = GetEntity(sprite_idx); return spr != nullptr ? spr->As() : nullptr; } -EntityBase* TryGetEntity(size_t spriteIndex); +EntityBase* TryGetEntity(EntityId spriteIndex); -template T* TryGetEntity(size_t sprite_idx) +template T* TryGetEntity(EntityId sprite_idx) { auto spr = TryGetEntity(sprite_idx); return spr != nullptr ? spr->As() : nullptr; @@ -40,9 +40,9 @@ template T* CreateEntity() } // Use only with imports that must happen at a specified index -EntityBase* CreateEntityAt(const uint16_t index, const EntityType type); +EntityBase* CreateEntityAt(const EntityId index, const EntityType type); // Use only with imports that must happen at a specified index -template T* CreateEntityAt(const uint16_t index) +template T* CreateEntityAt(const EntityId index) { return static_cast(CreateEntityAt(index, T::cEntityType)); } diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index ff668e9dd3..9d44f7bfa7 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -1956,7 +1956,7 @@ bool Guest::ShouldGoOnRide(Ride* ride, int32_t entranceNum, bool atQueue, bool t // Rides without queues can only have one peep waiting at a time. if (!atQueue) { - if (ride->stations[entranceNum].LastPeepInQueue != SPRITE_INDEX_NULL) + if (!ride->stations[entranceNum].LastPeepInQueue.IsNull()) { peep_tried_to_enter_full_queue(this, ride); return false; @@ -2549,7 +2549,7 @@ bool Guest::FindVehicleToEnter(Ride* ride, std::vector& car_array) int32_t i = 0; - uint16_t vehicle_id = ride->vehicles[chosen_train]; + auto vehicle_id = ride->vehicles[chosen_train]; for (Vehicle* vehicle = GetEntity(vehicle_id); vehicle != nullptr; vehicle = GetEntity(vehicle->next_vehicle_on_train), ++i) { @@ -2570,7 +2570,7 @@ bool Guest::FindVehicleToEnter(Ride* ride, std::vector& car_array) if (ride->mode == RideMode::ForwardRotation || ride->mode == RideMode::BackwardRotation) { uint8_t position = (((~vehicle->Pitch + 1) >> 3) & 0xF) * 2; - if (vehicle->peep[position] != SPRITE_INDEX_NULL) + if (!vehicle->peep[position].IsNull()) continue; } car_array.push_back(i); @@ -3982,7 +3982,7 @@ void Guest::UpdateRideFreeVehicleCheck() } vehicle->next_free_seat--; - vehicle->peep[CurrentSeat] = SPRITE_INDEX_NULL; + vehicle->peep[CurrentSeat] = EntityId::GetNull(); peep_update_ride_no_free_vehicle_rejoin_queue(this, ride); } @@ -5258,7 +5258,7 @@ void Guest::UpdateWalking() } else if (HasEmptyContainer()) { - if ((!GetNextIsSurface()) && (static_cast(sprite_index & 0x1FF) == (gCurrentTicks & 0x1FF)) + if ((!GetNextIsSurface()) && (static_cast(sprite_index.ToUnderlying() & 0x1FF) == (gCurrentTicks & 0x1FF)) && ((0xFFFF & scenario_rand()) <= 4096)) { int32_t container = bitscanforward(GetEmptyContainerFlags()); @@ -7127,7 +7127,7 @@ Guest* Guest::Generate(const CoordsXYZ& coords) // Create event args object auto obj = OpenRCT2::Scripting::DukObject(ctx); - obj.Set("id", peep->sprite_index); + obj.Set("id", peep->sprite_index.ToUnderlying()); // Call the subscriptions auto e = obj.Take(); diff --git a/src/openrct2/entity/Guest.h b/src/openrct2/entity/Guest.h index dcd7ea513e..59e01e2372 100644 --- a/src/openrct2/entity/Guest.h +++ b/src/openrct2/entity/Guest.h @@ -261,7 +261,7 @@ struct Guest : Peep public: uint8_t GuestNumRides; - uint16_t GuestNextInQueue; + EntityId GuestNextInQueue; int32_t ParkEntryTime; RideId GuestHeadingToRideId; uint8_t GuestIsLostCountdown; @@ -465,7 +465,7 @@ extern uint8_t gGuestInitialThirst; extern uint32_t gNextGuestNumber; -void guest_set_name(uint16_t spriteIndex, const char* name); +void guest_set_name(EntityId spriteIndex, const char* name); void peep_thought_set_format_args(const PeepThought* thought, Formatter& ft); diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index 6c819d8728..6293f923b5 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -277,7 +277,7 @@ bool Peep::CheckForPath() PROFILED_FUNCTION(); PathCheckOptimisation++; - if ((PathCheckOptimisation & 0xF) != (sprite_index & 0xF)) + if ((PathCheckOptimisation & 0xF) != (sprite_index.ToUnderlying() & 0xF)) { // This condition makes the check happen less often // As a side effect peeps hover for a short, @@ -486,7 +486,7 @@ std::optional Peep::UpdateAction(int16_t& xy_distance) WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_2; const auto curLoc = GetLocation(); - Litter::Create({ curLoc, sprite_direction }, (sprite_index & 1) ? Litter::Type::VomitAlt : Litter::Type::Vomit); + Litter::Create({ curLoc, sprite_direction }, (sprite_index.ToUnderlying() & 1) ? Litter::Type::VomitAlt : Litter::Type::Vomit); static constexpr OpenRCT2::Audio::SoundId coughs[4] = { OpenRCT2::Audio::SoundId::Cough1, @@ -524,7 +524,7 @@ void peep_decrement_num_riders(Peep* peep) */ void peep_window_state_update(Peep* peep) { - rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); + rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index.ToUnderlying()); if (w != nullptr) window_event_invalidate_call(w); @@ -661,14 +661,14 @@ void peep_sprite_remove(Peep* peep) bool wasGuest = staff == nullptr; if (wasGuest) { - News::DisableNewsItems(News::ItemType::PeepOnRide, peep->sprite_index); + News::DisableNewsItems(News::ItemType::PeepOnRide, peep->sprite_index.ToUnderlying()); } else { staff->ClearPatrolArea(); staff_update_greyed_patrol_areas(); - News::DisableNewsItems(News::ItemType::Peep, staff->sprite_index); + News::DisableNewsItems(News::ItemType::Peep, staff->sprite_index.ToUnderlying()); } EntityRemove(peep); @@ -1702,7 +1702,7 @@ static bool peep_interact_with_entrance(Peep* peep, const CoordsXYE& coords, uin guest->ActionSpriteImageOffset = _unk_F1AEF0; guest->InteractionRideIndex = rideIndex; - uint16_t previous_last = ride->stations[stationNum].LastPeepInQueue; + auto previous_last = ride->stations[stationNum].LastPeepInQueue; ride->stations[stationNum].LastPeepInQueue = guest->sprite_index; guest->GuestNextInQueue = previous_last; ride->stations[stationNum].QueueLength++; @@ -2127,7 +2127,7 @@ static void peep_interact_with_path(Peep* peep, const CoordsXYE& coords) guest->InteractionRideIndex = rideIndex; // Add the peep to the ride queue. - uint16_t old_last_peep = ride->stations[stationNum].LastPeepInQueue; + auto old_last_peep = ride->stations[stationNum].LastPeepInQueue; ride->stations[stationNum].LastPeepInQueue = guest->sprite_index; guest->GuestNextInQueue = old_last_peep; ride->stations[stationNum].QueueLength++; @@ -2489,7 +2489,7 @@ rct_string_id get_real_name_string_id_from_id(uint32_t id) return dx; } -int32_t peep_compare(const uint16_t sprite_index_a, const uint16_t sprite_index_b) +int32_t peep_compare(const EntityId sprite_index_a, const EntityId sprite_index_b) { Peep const* peep_a = GetEntity(sprite_index_a); Peep const* peep_b = GetEntity(sprite_index_b); diff --git a/src/openrct2/entity/Peep.h b/src/openrct2/entity/Peep.h index 97087a0182..b59201fc70 100644 --- a/src/openrct2/entity/Peep.h +++ b/src/openrct2/entity/Peep.h @@ -473,7 +473,7 @@ void peep_window_state_update(Peep* peep); void peep_decrement_num_riders(Peep* peep); void peep_set_map_tooltip(Peep* peep); -int32_t peep_compare(const uint16_t sprite_index_a, const uint16_t sprite_index_b); +int32_t peep_compare(const EntityId sprite_index_a, const EntityId sprite_index_b); void peep_update_names(bool realNames); diff --git a/src/openrct2/entity/Staff.cpp b/src/openrct2/entity/Staff.cpp index 1e6f33409d..ced50d8cc0 100644 --- a/src/openrct2/entity/Staff.cpp +++ b/src/openrct2/entity/Staff.cpp @@ -551,7 +551,7 @@ bool Staff::DoHandymanPathFinding() Direction litterDirection = INVALID_DIRECTION; uint8_t validDirections = GetValidPatrolDirections(NextLoc); - if ((StaffOrders & STAFF_ORDERS_SWEEPING) && ((gCurrentTicks + sprite_index) & 0xFFF) > 110) + if ((StaffOrders & STAFF_ORDERS_SWEEPING) && ((gCurrentTicks + sprite_index.ToUnderlying()) & 0xFFF) > 110) { litterDirection = HandymanDirectionToNearestLitter(); } diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 0ef9aedee9..2e07c59e17 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -482,7 +482,7 @@ static int32_t cc_staff(InteractiveConsole& console, const arguments_t& argv) if (int_valid[0] && int_valid[1]) { - Peep* peep = GetEntity(int_val[0]); + Peep* peep = GetEntity(EntityId::FromUnderlying(int_val[0])); if (peep != nullptr) { peep->Energy = int_val[1]; @@ -501,7 +501,7 @@ static int32_t cc_staff(InteractiveConsole& console, const arguments_t& argv) console.WriteLineError("Invalid staff ID"); return 1; } - auto staff = GetEntity(int_val[0]); + auto staff = GetEntity(EntityId::FromUnderlying(int_val[0])); if (staff == nullptr) { console.WriteLineError("Invalid staff ID"); @@ -519,7 +519,7 @@ static int32_t cc_staff(InteractiveConsole& console, const arguments_t& argv) } EntertainerCostume costume = static_cast(int_val[1]); - auto staffSetCostumeAction = StaffSetCostumeAction(int_val[0], costume); + auto staffSetCostumeAction = StaffSetCostumeAction(EntityId::FromUnderlying(int_val[0]), costume); GameActions::Execute(&staffSetCostumeAction); } } diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 8e4b31c927..0914fe217b 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -192,7 +192,7 @@ void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) - return SPRITE_INDEX_NULL; + return EntityId::GetNull(); else if constexpr (std::is_same_v) return arg; }, @@ -533,7 +533,7 @@ static void viewport_move(const ScreenCoordsXY& coords, rct_window* w, rct_viewp static void viewport_set_underground_flag(int32_t underground, rct_window* window, rct_viewport* viewport) { if (window->classification != WC_MAIN_WINDOW - || (window->classification == WC_MAIN_WINDOW && window->viewport_smart_follow_sprite != SPRITE_INDEX_NULL)) + || (window->classification == WC_MAIN_WINDOW && !window->viewport_smart_follow_sprite.IsNull())) { if (!underground) { @@ -565,12 +565,12 @@ void viewport_update_position(rct_window* window) if (viewport == nullptr) return; - if (window->viewport_smart_follow_sprite != SPRITE_INDEX_NULL) + if (!window->viewport_smart_follow_sprite.IsNull()) { viewport_update_smart_sprite_follow(window); } - if (window->viewport_target_sprite != SPRITE_INDEX_NULL) + if (!window->viewport_target_sprite.IsNull()) { viewport_update_sprite_follow(window); return; @@ -660,7 +660,7 @@ void viewport_update_position(rct_window* window) void viewport_update_sprite_follow(rct_window* window) { - if (window->viewport_target_sprite != SPRITE_INDEX_NULL && window->viewport != nullptr) + if (!window->viewport_target_sprite.IsNull() && window->viewport != nullptr) { auto* sprite = GetEntity(window->viewport_target_sprite); if (sprite == nullptr) @@ -689,8 +689,8 @@ void viewport_update_smart_sprite_follow(rct_window* window) auto entity = TryGetEntity(window->viewport_smart_follow_sprite); if (entity == nullptr || entity->Type == EntityType::Null) { - window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL; - window->viewport_target_sprite = SPRITE_INDEX_NULL; + window->viewport_smart_follow_sprite = EntityId::GetNull(); + window->viewport_target_sprite = EntityId::GetNull(); return; } @@ -722,8 +722,8 @@ void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep) if (peep->State == PeepState::Picked) { - window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL; - window->viewport_target_sprite = SPRITE_INDEX_NULL; + window->viewport_smart_follow_sprite = EntityId::GetNull(); + window->viewport_target_sprite = EntityId::GetNull(); window->focus = std::nullopt; // No focus return; } @@ -760,7 +760,7 @@ void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep) coordFocus.y = xy.y; coordFocus.z = tile_element_height(xy) + (4 * COORDS_Z_STEP); focus = Focus(coordFocus); - window->viewport_target_sprite = SPRITE_INDEX_NULL; + window->viewport_target_sprite = EntityId::GetNull(); } } @@ -771,8 +771,8 @@ void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep) { if (peep->State == PeepState::Picked) { - window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL; - window->viewport_target_sprite = SPRITE_INDEX_NULL; + window->viewport_smart_follow_sprite = EntityId::GetNull(); + window->viewport_target_sprite = EntityId::GetNull(); window->focus = std::nullopt; return; } diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index c312f3ffc2..66306ec60c 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -300,6 +300,12 @@ void window_close_by_number(rct_windowclass cls, rct_windownumber number) window_close_by_condition([cls, number](rct_window* w) -> bool { return w->classification == cls && w->number == number; }); } +// TODO: Refactor this to use variant once the new window class is done. +void window_close_by_number(rct_windowclass cls, EntityId number) +{ + window_close_by_number(cls, static_cast(number.ToUnderlying())); +} + /** * Finds the first window with the specified window class. * rct2: 0x006EA8A0 @@ -337,6 +343,12 @@ rct_window* window_find_by_number(rct_windowclass cls, rct_windownumber number) return nullptr; } +// TODO: Use variant for this once the window framework is done. +rct_window* window_find_by_number(rct_windowclass cls, EntityId id) +{ + return window_find_by_number(cls, static_cast(id.ToUnderlying())); +} + /** * Closes the top-most window * @@ -491,6 +503,12 @@ void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number) [cls, number](rct_window* w) -> bool { return w->classification == cls && w->number == number; }); } +// TODO: Use variant for this once the window framework is done. +void window_invalidate_by_number(rct_windowclass cls, EntityId id) +{ + window_invalidate_by_number(cls, static_cast(id.ToUnderlying())); +} + /** * Invalidates all windows. */ @@ -867,7 +885,7 @@ void window_scroll_to_location(rct_window* w, const CoordsXYZ& coords) } } // rct2: 0x006E7C76 - if (w->viewport_target_sprite == SPRITE_INDEX_NULL) + if (w->viewport_target_sprite.IsNull()) { if (!(w->flags & WF_NO_SCROLLING)) { @@ -2121,18 +2139,18 @@ void window_init_all() window_close_all_except_flags(0); } -void window_follow_sprite(rct_window* w, size_t spriteIndex) +void window_follow_sprite(rct_window* w, EntityId spriteIndex) { - if (spriteIndex < MAX_ENTITIES || spriteIndex == SPRITE_INDEX_NULL) + if (spriteIndex.ToUnderlying() < MAX_ENTITIES || spriteIndex.IsNull()) { - w->viewport_smart_follow_sprite = static_cast(spriteIndex); + w->viewport_smart_follow_sprite = spriteIndex; } } void window_unfollow_sprite(rct_window* w) { - w->viewport_smart_follow_sprite = SPRITE_INDEX_NULL; - w->viewport_target_sprite = SPRITE_INDEX_NULL; + w->viewport_smart_follow_sprite = EntityId::GetNull(); + w->viewport_target_sprite = EntityId::GetNull(); } rct_viewport* window_get_viewport(rct_window* w) diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index f2ff9c7f0f..404c28f5e0 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "../common.h" #include "../localisation/Formatter.h" #include "../ride/RideTypes.h" @@ -197,7 +198,7 @@ constexpr auto WINDOW_SCROLL_UNDEFINED = std::numeric_limits::max(); struct Focus { using CoordinateFocus = CoordsXYZ; - using EntityFocus = uint16_t; + using EntityFocus = EntityId; ZoomLevel zoom{}; std::variant data; @@ -713,16 +714,19 @@ rct_window* WindowCreateCentred( void window_close(rct_window* window); void window_close_by_class(rct_windowclass cls); void window_close_by_number(rct_windowclass cls, rct_windownumber number); +void window_close_by_number(rct_windowclass cls, EntityId number); void window_close_top(); void window_close_all(); void window_close_all_except_class(rct_windowclass cls); void window_close_all_except_flags(uint16_t flags); rct_window* window_find_by_class(rct_windowclass cls); rct_window* window_find_by_number(rct_windowclass cls, rct_windownumber number); +rct_window* window_find_by_number(rct_windowclass cls, EntityId id); rct_window* window_find_from_point(const ScreenCoordsXY& screenCoords); rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsXY& screenCoords); void window_invalidate_by_class(rct_windowclass cls); void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number); +void window_invalidate_by_number(rct_windowclass cls, EntityId id); void window_invalidate_all(); void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex); void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex); @@ -851,7 +855,7 @@ void window_footpath_keyboard_shortcut_slope_up(); void window_footpath_keyboard_shortcut_build_current(); void window_footpath_keyboard_shortcut_demolish_current(); -void window_follow_sprite(rct_window* w, size_t spriteIndex); +void window_follow_sprite(rct_window* w, EntityId spriteIndex); void window_unfollow_sprite(rct_window* w); bool window_ride_construction_update_state( diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index efbab2cccc..36ed878251 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -96,12 +96,12 @@ struct rct_window }; int16_t selected_tab{}; int16_t var_4AE{}; - uint16_t viewport_target_sprite{}; + EntityId viewport_target_sprite{ EntityId::GetNull() }; ScreenCoordsXY savedViewPos{}; rct_windowclass classification{}; colour_t colours[6]{}; VisibilityCache visibility{}; - uint16_t viewport_smart_follow_sprite = SPRITE_INDEX_NULL; // Handles setting viewport target sprite etc + EntityId viewport_smart_follow_sprite{ EntityId::GetNull() }; // Handles setting viewport target sprite etc void SetLocation(const CoordsXYZ& coords); void ScrollToViewport(); diff --git a/src/openrct2/localisation/Formatter.h b/src/openrct2/localisation/Formatter.h index bc67042eaf..51073d3fd5 100644 --- a/src/openrct2/localisation/Formatter.h +++ b/src/openrct2/localisation/Formatter.h @@ -92,6 +92,7 @@ public: std::is_same_v, money32> || std::is_same_v, money64> || std::is_same_v, RideId> || + std::is_same_v, EntityId> || std::is_same_v, rct_string_id> || std::is_same_v, uint16_t> || std::is_same_v, uint32_t> || @@ -105,6 +106,10 @@ public: { convertedValue = static_cast(value.ToUnderlying()); } + else if constexpr (std::is_same_v, EntityId>) + { + convertedValue = static_cast(value.ToUnderlying()); + } else if constexpr (std::is_integral_v || std::is_enum_v) { convertedValue = static_cast(value); diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index abc06f42ba..b6f0db5e83 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -224,7 +224,7 @@ std::optional News::GetSubjectLocation(News::ItemType type, int32_t s } case News::ItemType::PeepOnRide: { - auto peep = TryGetEntity(subject); + auto peep = TryGetEntity(EntityId::FromUnderlying(subject)); if (peep == nullptr) break; @@ -261,7 +261,7 @@ std::optional News::GetSubjectLocation(News::ItemType type, int32_t s } case News::ItemType::Peep: { - auto peep = TryGetEntity(subject); + auto peep = TryGetEntity(EntityId::FromUnderlying(subject)); if (peep != nullptr) { subjectLoc = peep->GetLocation(); @@ -314,6 +314,12 @@ News::Item* News::AddItemToQueue(News::ItemType type, rct_string_id string_id, u return News::AddItemToQueue(type, buffer, assoc); } +// TODO: Use variant for assoc, requires strong type for each possible input. +News::Item* News::AddItemToQueue(ItemType type, rct_string_id string_id, EntityId assoc, const Formatter& formatter) +{ + return AddItemToQueue(type, string_id, assoc.ToUnderlying(), formatter); +} + News::Item* News::AddItemToQueue(News::ItemType type, const utf8* text, uint32_t assoc) { News::Item* newsItem = gNewsItems.FirstOpenOrNewSlot(); @@ -367,7 +373,7 @@ void News::OpenSubject(News::ItemType type, int32_t subject) case News::ItemType::PeepOnRide: case News::ItemType::Peep: { - auto peep = TryGetEntity(subject); + auto peep = TryGetEntity(EntityId::FromUnderlying(subject)); if (peep != nullptr) { auto intent = Intent(WC_PEEP); diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 52948bbc60..9ffdb2e131 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "../common.h" #include "../core/String.hpp" @@ -292,6 +293,7 @@ namespace News std::optional GetSubjectLocation(News::ItemType type, int32_t subject); News::Item* AddItemToQueue(News::ItemType type, rct_string_id string_id, uint32_t assoc, const Formatter& formatter); + News::Item* AddItemToQueue(News::ItemType type, rct_string_id string_id, EntityId assoc, const Formatter& formatter); News::Item* AddItemToQueue(News::ItemType type, const utf8* text, uint32_t assoc); bool CheckIfItemRequiresAssoc(News::ItemType type); diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 38ff6bb0e2..2d109c921c 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -900,14 +900,16 @@ static void PaintPatrolAreas(paint_session& session, const PathElement& pathEl) { if (gStaffDrawPatrolAreas != 0xFFFF) { + // TODO: Split this into two. auto staffIndex = gStaffDrawPatrolAreas; auto staffType = static_cast(staffIndex & 0x7FFF); auto is_staff_list = staffIndex & 0x8000; + auto patrolColour = COLOUR_LIGHT_BLUE; if (!is_staff_list) { - Staff* staff = GetEntity(staffIndex); + Staff* staff = GetEntity(EntityId::FromUnderlying(staffIndex)); if (staff == nullptr) { log_error("Invalid staff index for draw patrol areas!"); diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 92c83d4911..7f23d95bcb 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1105,6 +1105,7 @@ void PaintSurface(paint_session& session, uint8_t direction, uint16_t height, co // loc_660D02 if (gStaffDrawPatrolAreas != SPRITE_INDEX_NULL) { + // TODO: Split is_staff_list into a new variable. const int32_t staffIndex = gStaffDrawPatrolAreas; const bool is_staff_list = staffIndex & 0x8000; const int16_t x = session.MapPosition.x, y = session.MapPosition.y; @@ -1115,7 +1116,7 @@ void PaintSurface(paint_session& session, uint8_t direction, uint16_t height, co if (!is_staff_list) { - Staff* staff = GetEntity(staffIndex); + Staff* staff = GetEntity(EntityId::FromUnderlying(staffIndex)); if (staff == nullptr) { log_error("Invalid staff index for draw patrol areas!"); diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index b3a86cf73c..8cd03c1dc6 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -1160,7 +1160,7 @@ namespace OpenRCT2 cs.ReadWrite(ride.min_waiting_time); cs.ReadWrite(ride.max_waiting_time); - cs.ReadWriteArray(ride.vehicles, [&cs](uint16_t& v) { + cs.ReadWriteArray(ride.vehicles, [&cs](EntityId& v) { cs.ReadWrite(v); return true; }); @@ -2168,7 +2168,7 @@ namespace OpenRCT2 { T placeholder{}; - auto index = cs.Read(); + auto index = cs.Read(); auto* ent = CreateEntityAt(index); if (ent == nullptr) { diff --git a/src/openrct2/peep/RideUseSystem.h b/src/openrct2/peep/RideUseSystem.h index 822f2d136c..4074ba2e26 100644 --- a/src/openrct2/peep/RideUseSystem.h +++ b/src/openrct2/peep/RideUseSystem.h @@ -13,8 +13,8 @@ namespace OpenRCT2::RideUse { - using RideHistory = GroupVector; - using RideTypeHistory = GroupVector; + using RideHistory = GroupVector; + using RideTypeHistory = GroupVector; RideHistory& GetHistory(); RideTypeHistory& GetTypeHistory(); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index da129197a7..f255e107bb 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -872,7 +872,7 @@ namespace RCT1 ride_set_exit_location(dst, i, { src->exit[i].x, src->exit[i].y, src->station_height[i] / 2, 0 }); dst->stations[i].QueueTime = src->queue_time[i]; - dst->stations[i].LastPeepInQueue = src->last_peep_in_queue[i]; + dst->stations[i].LastPeepInQueue = EntityId::FromUnderlying(src->last_peep_in_queue[i]); dst->stations[i].QueueLength = src->num_peeps_in_queue[i]; dst->stations[i].SegmentTime = src->time[i]; @@ -885,7 +885,7 @@ namespace RCT1 dst->stations[i].TrainAtStation = RideStation::NO_TRAIN; ride_clear_entrance_location(dst, i); ride_clear_exit_location(dst, i); - dst->stations[i].LastPeepInQueue = SPRITE_INDEX_NULL; + dst->stations[i].LastPeepInQueue = EntityId::GetNull(); } dst->num_stations = src->num_stations; @@ -893,11 +893,11 @@ namespace RCT1 // Vehicle links (indexes converted later) for (int32_t i = 0; i < Limits::MaxTrainsPerRide; i++) { - dst->vehicles[i] = src->vehicles[i]; + dst->vehicles[i] = EntityId::FromUnderlying(src->vehicles[i]); } for (int32_t i = Limits::MaxTrainsPerRide; i <= OpenRCT2::Limits::MaxTrainsPerRide; i++) { - dst->vehicles[i] = SPRITE_INDEX_NULL; + dst->vehicles[i] = EntityId::GetNull(); } dst->num_vehicles = src->num_trains; @@ -971,7 +971,7 @@ namespace RCT1 dst->downtime = src->downtime; dst->breakdown_reason = src->breakdown_reason; dst->mechanic_status = src->mechanic_status; - dst->mechanic = src->mechanic; + dst->mechanic = EntityId::FromUnderlying(src->mechanic); dst->breakdown_reason_pending = src->breakdown_reason_pending; dst->inspection_station = src->inspection_station; dst->broken_car = src->broken_car; @@ -2702,7 +2702,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity<::Vehicle>(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt<::Vehicle>(srcBase.sprite_index); + auto* dst = CreateEntityAt<::Vehicle>(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); const auto* ride = get_ride(RideId::FromUnderlying(src->ride)); if (ride == nullptr) @@ -2759,16 +2759,16 @@ namespace RCT1 dst->seat_rotation = DEFAULT_SEAT_ROTATION; // Vehicle links (indexes converted later) - dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; - dst->next_vehicle_on_ride = src->next_vehicle_on_ride; - dst->next_vehicle_on_train = src->next_vehicle_on_train; + dst->prev_vehicle_on_ride = EntityId::FromUnderlying(src->prev_vehicle_on_ride); + dst->next_vehicle_on_ride = EntityId::FromUnderlying(src->next_vehicle_on_ride); + dst->next_vehicle_on_train = EntityId::FromUnderlying(src->next_vehicle_on_train); // Guests (indexes converted later) for (int i = 0; i < 32; i++) { - uint16_t spriteIndex = src->peep[i]; + const auto spriteIndex = EntityId::FromUnderlying(src->peep[i]); dst->peep[i] = spriteIndex; - if (spriteIndex != SPRITE_INDEX_NULL) + if (spriteIndex.IsNull()) { dst->peep_tshirt_colours[i] = RCT1::GetColour(src->peep_tshirt_colours[i]); } @@ -2814,7 +2814,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportPeep(dst, src); @@ -2886,7 +2886,7 @@ namespace RCT1 dst->PreviousRideTimeOut = src->previous_ride_time_out; dst->GuestHeadingToRideId = RCT12RideIdToOpenRCT2RideId(src->guest_heading_to_ride_id); dst->GuestIsLostCountdown = src->peep_is_lost_countdown; - dst->GuestNextInQueue = src->next_in_queue; + dst->GuestNextInQueue = EntityId::FromUnderlying(src->next_in_queue); // Guests' favourite ride was only saved in LL. // Set it to N/A if the save comes from the original or AA. if (_gameVersion == FILE_VERSION_RCT1_LL) @@ -2914,7 +2914,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportPeep(dst, src); dst->AssignedStaffType = StaffType(src->staff_type); @@ -2932,7 +2932,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); @@ -2941,7 +2941,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); @@ -2950,7 +2950,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); @@ -2963,35 +2963,35 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); } template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); @@ -3004,7 +3004,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); @@ -3021,7 +3021,7 @@ namespace RCT1 template<> void S4Importer::ImportEntity(const RCT12SpriteBase& srcBase) { - auto* dst = CreateEntityAt(srcBase.sprite_index); + auto* dst = CreateEntityAt(EntityId::FromUnderlying(srcBase.sprite_index)); auto* src = static_cast(&srcBase); ImportEntityCommonProperties(dst, src); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 011f51ade0..18707d1c6d 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -705,7 +705,7 @@ namespace RCT2 else ride_set_exit_location(dst, i, { src->exits[i].x, src->exits[i].y, src->station_heights[i], 0 }); - dst->stations[i].LastPeepInQueue = src->last_peep_in_queue[i]; + dst->stations[i].LastPeepInQueue = EntityId::FromUnderlying(src->last_peep_in_queue[i]); dst->stations[i].SegmentLength = src->length[i]; dst->stations[i].SegmentTime = src->time[i]; @@ -721,16 +721,16 @@ namespace RCT2 dst->stations[i].TrainAtStation = RideStation::NO_TRAIN; ride_clear_entrance_location(dst, i); ride_clear_exit_location(dst, i); - dst->stations[i].LastPeepInQueue = SPRITE_INDEX_NULL; + dst->stations[i].LastPeepInQueue = EntityId::GetNull(); } for (int32_t i = 0; i < Limits::MaxTrainsPerRide; i++) { - dst->vehicles[i] = src->vehicles[i]; + dst->vehicles[i] = EntityId::FromUnderlying(src->vehicles[i]); } for (int32_t i = Limits::MaxTrainsPerRide - 1; i <= OpenRCT2::Limits::MaxTrainsPerRide; i++) { - dst->vehicles[i] = SPRITE_INDEX_NULL; + dst->vehicles[i] = EntityId::GetNull(); } dst->depart_flags = src->depart_flags; @@ -833,7 +833,7 @@ namespace RCT2 dst->music_tune_id = src->music_tune_id; dst->slide_in_use = src->slide_in_use; // Includes maze_tiles - dst->slide_peep = src->slide_peep; + dst->slide_peep = EntityId::FromUnderlying(src->slide_peep); // pad_160[0xE]; dst->slide_peep_t_shirt_colour = src->slide_peep_t_shirt_colour; // pad_16F[0x7]; @@ -841,13 +841,13 @@ namespace RCT2 // pad_177[0x9]; dst->build_date = static_cast(src->build_date); dst->upkeep_cost = src->upkeep_cost; - dst->race_winner = src->race_winner; + dst->race_winner = EntityId::FromUnderlying(src->race_winner); // pad_186[0x02]; dst->music_position = src->music_position; dst->breakdown_reason_pending = src->breakdown_reason_pending; dst->mechanic_status = src->mechanic_status; - dst->mechanic = src->mechanic; + dst->mechanic = EntityId::FromUnderlying(src->mechanic); dst->inspection_station = src->inspection_station; dst->broken_vehicle = src->broken_vehicle; dst->broken_car = src->broken_car; @@ -924,7 +924,7 @@ namespace RCT2 dst->num_circuits = src->num_circuits; dst->CableLiftLoc = { src->cable_lift_x, src->cable_lift_y, src->cable_lift_z * COORDS_Z_STEP }; // pad_1FD; - dst->cable_lift = src->cable_lift; + dst->cable_lift = EntityId::FromUnderlying(src->cable_lift); // pad_208[0x58]; } @@ -1660,7 +1660,7 @@ namespace RCT2 { dst->Type = GetEntityTypeFromRCT2Sprite(src); dst->sprite_height_negative = src->sprite_height_negative; - dst->sprite_index = src->sprite_index; + dst->sprite_index = EntityId::FromUnderlying(src->sprite_index); dst->x = src->x; dst->y = src->y; dst->z = src->z; @@ -1784,7 +1784,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Vehicle>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Vehicle>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Vehicle>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); const auto& ride = _s6.rides[src->ride]; @@ -1832,9 +1832,9 @@ namespace RCT2 dst->SetTrackType(0); } - dst->next_vehicle_on_train = src->next_vehicle_on_train; - dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; - dst->next_vehicle_on_ride = src->next_vehicle_on_ride; + dst->next_vehicle_on_train = EntityId::FromUnderlying(src->next_vehicle_on_train); + dst->prev_vehicle_on_ride = EntityId::FromUnderlying(src->prev_vehicle_on_ride); + dst->next_vehicle_on_ride = EntityId::FromUnderlying(src->next_vehicle_on_ride); dst->var_44 = src->var_44; dst->mass = src->mass; dst->update_flags = src->update_flags; @@ -1853,7 +1853,7 @@ namespace RCT2 dst->sub_state = src->sub_state; for (size_t i = 0; i < std::size(src->peep); i++) { - dst->peep[i] = src->peep[i]; + dst->peep[i] = EntityId::FromUnderlying(src->peep[i]); dst->peep_tshirt_colours[i] = src->peep_tshirt_colours[i]; } dst->num_seats = src->num_seats; @@ -1901,7 +1901,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Guest>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Guest>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Guest>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityPeep(dst, src); @@ -1927,7 +1927,7 @@ namespace RCT2 dst->Photo2RideRef = RCT12RideIdToOpenRCT2RideId(src->photo2_ride_ref); dst->Photo3RideRef = RCT12RideIdToOpenRCT2RideId(src->photo3_ride_ref); dst->Photo4RideRef = RCT12RideIdToOpenRCT2RideId(src->photo4_ride_ref); - dst->GuestNextInQueue = src->next_in_queue; + dst->GuestNextInQueue = EntityId::FromUnderlying(src->next_in_queue); dst->TimeInQueue = src->time_in_queue; dst->CashInPocket = src->cash_in_pocket; dst->CashSpent = src->cash_spent; @@ -1975,7 +1975,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Staff>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Staff>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Staff>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityPeep(dst, src); @@ -1995,7 +1995,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::SteamParticle>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::SteamParticle>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::SteamParticle>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->time_to_move = src->time_to_move; @@ -2004,7 +2004,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::MoneyEffect>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::MoneyEffect>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::MoneyEffect>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->MoveDelay = src->move_delay; @@ -2017,7 +2017,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::VehicleCrashParticle>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::VehicleCrashParticle>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::VehicleCrashParticle>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->frame = src->frame; @@ -2036,7 +2036,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::ExplosionCloud>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::ExplosionCloud>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::ExplosionCloud>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->frame = src->frame; @@ -2044,7 +2044,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::ExplosionFlare>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::ExplosionFlare>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::ExplosionFlare>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->frame = src->frame; @@ -2052,7 +2052,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::CrashSplashParticle>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::CrashSplashParticle>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::CrashSplashParticle>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->frame = src->frame; @@ -2060,7 +2060,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::JumpingFountain>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::JumpingFountain>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::JumpingFountain>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->NumTicksAlive = src->num_ticks_alive; @@ -2076,7 +2076,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Balloon>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Balloon>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Balloon>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->popped = src->popped; @@ -2087,7 +2087,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Duck>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Duck>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Duck>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->frame = src->frame; @@ -2098,7 +2098,7 @@ namespace RCT2 template<> void S6Importer::ImportEntity<::Litter>(const RCT12SpriteBase& baseSrc) { - auto dst = CreateEntityAt<::Litter>(baseSrc.sprite_index); + auto dst = CreateEntityAt<::Litter>(EntityId::FromUnderlying(baseSrc.sprite_index)); auto src = static_cast(&baseSrc); ImportEntityCommonProperties(dst, src); dst->SubType = ::Litter::Type(src->type); diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 70cdbfebbe..ca49619f3d 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -60,7 +60,7 @@ Vehicle* cable_lift_segment_create( current->bank_rotation = 0; for (auto& peep : current->peep) { - peep = SPRITE_INDEX_NULL; + peep = EntityId::GetNull(); } current->TrackSubposition = VehicleTrackSubposition::Default; current->sprite_direction = direction << 3; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 954b436506..acf89f7218 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -281,7 +281,7 @@ Guest* Ride::GetQueueHeadGuest(StationIndex stationIndex) const { Guest* peep; Guest* result = nullptr; - uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; + auto spriteIndex = stations[stationIndex].LastPeepInQueue; while ((peep = TryGetEntity(spriteIndex)) != nullptr) { spriteIndex = peep->GuestNextInQueue; @@ -294,7 +294,7 @@ void Ride::UpdateQueueLength(StationIndex stationIndex) { uint16_t count = 0; Guest* peep; - uint16_t spriteIndex = stations[stationIndex].LastPeepInQueue; + auto spriteIndex = stations[stationIndex].LastPeepInQueue; while ((peep = TryGetEntity(spriteIndex)) != nullptr) { spriteIndex = peep->GuestNextInQueue; @@ -308,7 +308,7 @@ void Ride::QueueInsertGuestAtFront(StationIndex stationIndex, Guest* peep) assert(stationIndex < OpenRCT2::Limits::MaxStationsPerRide); assert(peep != nullptr); - peep->GuestNextInQueue = SPRITE_INDEX_NULL; + peep->GuestNextInQueue = EntityId::GetNull(); auto* queueHeadGuest = GetQueueHeadGuest(peep->CurrentRideStation); if (queueHeadGuest == nullptr) { @@ -809,7 +809,7 @@ void Ride::FormatStatusTo(Formatter& ft) const } else if ( mode == RideMode::Race && !(lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) - && race_winner != SPRITE_INDEX_NULL) + && !race_winner.IsNull()) { auto peep = GetEntity(race_winner); if (peep != nullptr) @@ -1431,7 +1431,7 @@ static void choose_random_train_to_breakdown_safe(Ride* ride) // Prevent crash caused by accessing SPRITE_INDEX_NULL on hacked rides. // This should probably be cleaned up on import instead. - while (ride->vehicles[ride->broken_vehicle] == SPRITE_INDEX_NULL && ride->broken_vehicle != 0) + while (ride->vehicles[ride->broken_vehicle].IsNull() && ride->broken_vehicle != 0) { --ride->broken_vehicle; } @@ -2004,7 +2004,7 @@ void ride_measurements_update() // For each vehicle for (int32_t j = 0; j < ride.num_vehicles; j++) { - uint16_t vehicleSpriteIdx = ride.vehicles[j]; + auto vehicleSpriteIdx = ride.vehicles[j]; auto vehicle = GetEntity(vehicleSpriteIdx); if (vehicle != nullptr) { @@ -3127,7 +3127,7 @@ static Vehicle* vehicle_create_car( vehicle->sound2_flags = 0; vehicle->sound1_id = OpenRCT2::Audio::SoundId::Null; vehicle->sound2_id = OpenRCT2::Audio::SoundId::Null; - vehicle->next_vehicle_on_train = SPRITE_INDEX_NULL; + vehicle->next_vehicle_on_train = EntityId::GetNull(); vehicle->var_C4 = 0; vehicle->animation_frame = 0; vehicle->animationState = 0; @@ -3138,7 +3138,7 @@ static Vehicle* vehicle_create_car( vehicle->seat_rotation = 4; for (size_t i = 0; i < std::size(vehicle->peep); i++) { - vehicle->peep[i] = SPRITE_INDEX_NULL; + vehicle->peep[i] = EntityId::GetNull(); } if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_DODGEM_CAR_PLACEMENT) @@ -3348,7 +3348,7 @@ static bool vehicle_create_trains(RideId rideIndex, const CoordsXYZ& trainsPos, for (int32_t i = 0; i <= OpenRCT2::Limits::MaxTrainsPerRide; i++) { - if (ride->vehicles[i] == SPRITE_INDEX_NULL) + if (ride->vehicles[i].IsNull()) { ride->vehicles[i] = train.head->sprite_index; break; @@ -3737,7 +3737,7 @@ static bool ride_create_cable_lift(RideId rideIndex, bool isApplying) Vehicle* current = cable_lift_segment_create( *ride, cableLiftLoc.x, cableLiftLoc.y, cableLiftLoc.z / 8, direction, var_44, remaining_distance, i == 0); - current->next_vehicle_on_train = SPRITE_INDEX_NULL; + current->next_vehicle_on_train = EntityId::GetNull(); if (i == 0) { head = current; @@ -5236,7 +5236,7 @@ uint32_t ride_customers_in_last_5_minutes(const Ride* ride) Vehicle* ride_get_broken_vehicle(const Ride* ride) { - uint16_t vehicleIndex = ride->vehicles[ride->broken_vehicle]; + auto vehicleIndex = ride->vehicles[ride->broken_vehicle]; Vehicle* vehicle = GetEntity(vehicleIndex); if (vehicle != nullptr) { diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 2159dfbdfe..512cef2cc9 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -53,7 +53,7 @@ struct RideStation uint16_t SegmentTime; // Time for train to reach the next station from this station. uint8_t QueueTime; uint16_t QueueLength; - uint16_t LastPeepInQueue; + EntityId LastPeepInQueue; static constexpr uint8_t NO_TRAIN = std::numeric_limits::max(); @@ -118,7 +118,7 @@ struct Ride std::string custom_name; uint16_t default_name_number; CoordsXY overall_view; - uint16_t vehicles[OpenRCT2::Limits::MaxTrainsPerRide + 1]; // Points to the first car in the train + EntityId vehicles[OpenRCT2::Limits::MaxTrainsPerRide + 1]; // Points to the first car in the train uint8_t depart_flags; uint8_t num_stations; uint8_t num_vehicles; @@ -209,18 +209,18 @@ struct Ride uint8_t slide_in_use; union { - uint16_t slide_peep; + EntityId slide_peep; uint16_t maze_tiles; }; uint8_t slide_peep_t_shirt_colour; uint8_t spiral_slide_progress; int32_t build_date; money16 upkeep_cost; - uint16_t race_winner; + EntityId race_winner; uint32_t music_position; uint8_t breakdown_reason_pending; uint8_t mechanic_status; - uint16_t mechanic; + EntityId mechanic; StationIndex inspection_station; uint8_t broken_vehicle; uint8_t broken_car; @@ -264,7 +264,7 @@ struct Ride StationIndex current_test_station; uint8_t num_circuits; CoordsXYZ CableLiftLoc; - uint16_t cable_lift; + EntityId cable_lift; // These two fields are used to warn users about issues. // Such issue can be hacked rides with incompatible options set. diff --git a/src/openrct2/ride/RideConstruction.cpp b/src/openrct2/ride/RideConstruction.cpp index 8a18168a0d..4401a728d4 100644 --- a/src/openrct2/ride/RideConstruction.cpp +++ b/src/openrct2/ride/RideConstruction.cpp @@ -161,7 +161,7 @@ static void ride_remove_cable_lift(Ride* ride) if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT) { ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CABLE_LIFT; - uint16_t spriteIndex = ride->cable_lift; + auto spriteIndex = ride->cable_lift; do { Vehicle* vehicle = GetEntity(spriteIndex); @@ -172,7 +172,7 @@ static void ride_remove_cable_lift(Ride* ride) vehicle->Invalidate(); spriteIndex = vehicle->next_vehicle_on_train; EntityRemove(vehicle); - } while (spriteIndex != SPRITE_INDEX_NULL); + } while (!spriteIndex.IsNull()); } } @@ -189,8 +189,8 @@ void Ride::RemoveVehicles() for (size_t i = 0; i <= OpenRCT2::Limits::MaxTrainsPerRide; i++) { - uint16_t spriteIndex = vehicles[i]; - while (spriteIndex != SPRITE_INDEX_NULL) + auto spriteIndex = vehicles[i]; + while (!spriteIndex.IsNull()) { Vehicle* vehicle = GetEntity(spriteIndex); if (vehicle == nullptr) @@ -202,7 +202,7 @@ void Ride::RemoveVehicles() EntityRemove(vehicle); } - vehicles[i] = SPRITE_INDEX_NULL; + vehicles[i] = EntityId::GetNull(); } for (size_t i = 0; i < OpenRCT2::Limits::MaxStationsPerRide; i++) diff --git a/src/openrct2/ride/TrainManager.h b/src/openrct2/ride/TrainManager.h index 301780c37c..e7e25f4697 100644 --- a/src/openrct2/ride/TrainManager.h +++ b/src/openrct2/ride/TrainManager.h @@ -7,6 +7,9 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ #pragma once + +#include "../Identifiers.h" + #include #include @@ -18,17 +21,17 @@ namespace TrainManager class View { private: - const std::list* vec; + const std::list* vec; class Iterator { private: - std::list::const_iterator iter; - std::list::const_iterator end; + std::list::const_iterator iter; + std::list::const_iterator end; Vehicle* Entity = nullptr; public: - Iterator(std::list::const_iterator _iter, std::list::const_iterator _end) + Iterator(std::list::const_iterator _iter, std::list::const_iterator _end) : iter(_iter) , end(_end) { diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index c719c4801b..cac50f6ec9 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -569,7 +569,7 @@ template<> bool EntityBase::Is() const * @param vehicleId Entity id of the vehicle that just crashed * @param crashId What the vehicle crashed into. Should be either "another_vehicle", "land", or "water" */ -static void InvokeVehicleCrashHook(const uint16_t vehicleId, const std::string_view crashId) +static void InvokeVehicleCrashHook(const EntityId vehicleId, const std::string_view crashId) { auto& hookEngine = OpenRCT2::GetContext()->GetScriptEngine().GetHookEngine(); if (hookEngine.HasSubscriptions(OpenRCT2::Scripting::HOOK_TYPE::VEHICLE_CRASH)) @@ -578,7 +578,7 @@ static void InvokeVehicleCrashHook(const uint16_t vehicleId, const std::string_v // Create event args object auto obj = OpenRCT2::Scripting::DukObject(ctx); - obj.Set("id", vehicleId); + obj.Set("id", vehicleId.ToUnderlying()); obj.Set("crashIntoType", crashId); // Call the subscriptions @@ -691,7 +691,7 @@ void Vehicle::MoveRelativeDistance(int32_t distance) ClearUpdateFlag(VEHICLE_UPDATE_FLAG_SINGLE_CAR_POSITION | VEHICLE_UPDATE_FLAG_COLLISION_DISABLED); } -Vehicle* try_get_vehicle(uint16_t spriteIndex) +Vehicle* try_get_vehicle(EntityId spriteIndex) { return TryGetEntity(spriteIndex); } @@ -763,7 +763,7 @@ namespace private: T* Current = nullptr; - uint16_t NextVehicleId = SPRITE_INDEX_NULL; + EntityId NextVehicleId = EntityId::GetNull(); }; } // namespace @@ -835,7 +835,7 @@ uint16_t Vehicle::GetSoundPriority() const for (const auto& vehicleSound : OpenRCT2::Audio::gVehicleSoundList) { - if (vehicleSound.id == sprite_index) + if (vehicleSound.id == sprite_index.ToUnderlying()) { // Vehicle sounds will get higher priority if they are already playing return result + 300; @@ -890,7 +890,7 @@ OpenRCT2::Audio::VehicleSoundParams Vehicle::CreateSoundParam(uint16_t priority) frequency += 11025; frequency += 16 * sound_vector_factor; param.frequency = static_cast(frequency); - param.id = sprite_index; + param.id = sprite_index.ToUnderlying(); param.volume = 0; if (x != LOCATION_NULL) @@ -1210,7 +1210,7 @@ void vehicle_sounds_update() vehicleSound->volume = tempvolume; panVol = std::max(0, panVol - tempvolume); - Vehicle* vehicle = GetEntity(vehicleSoundParams.id); + Vehicle* vehicle = GetEntity(EntityId::FromUnderlying(vehicleSoundParams.id)); if (vehicle != nullptr) { UpdateSound( @@ -2097,7 +2097,7 @@ void Vehicle::TrainReadyToDepart(uint8_t num_peeps_on_train, uint8_t num_used_se if (curRide->mode == RideMode::ForwardRotation || curRide->mode == RideMode::BackwardRotation) { uint8_t seat = ((-Pitch) / 8) & 0xF; - if (peep[seat] != SPRITE_INDEX_NULL) + if (!peep[seat].IsNull()) { curRide->stations[current_station].TrainAtStation = RideStation::NO_TRAIN; SetState(Vehicle::Status::UnloadingPassengers); @@ -2119,7 +2119,7 @@ void Vehicle::TrainReadyToDepart(uint8_t num_peeps_on_train, uint8_t num_used_se SetState(Vehicle::Status::WaitingForPassengers); } -static std::optional ride_get_train_index_from_vehicle(Ride* ride, uint16_t spriteIndex) +static std::optional ride_get_train_index_from_vehicle(Ride* ride, EntityId spriteIndex) { uint32_t trainIndex = 0; while (ride->vehicles[trainIndex] != spriteIndex) @@ -2384,7 +2384,7 @@ void Vehicle::UpdateWaitingToDepart() if (curRide->mode == RideMode::ForwardRotation || curRide->mode == RideMode::BackwardRotation) { uint8_t seat = ((-Pitch) >> 3) & 0xF; - if (peep[seat * 2] == SPRITE_INDEX_NULL) + if (peep[seat * 2].IsNull()) { if (num_peeps == 0) { @@ -2579,7 +2579,7 @@ struct rct_synchronised_vehicle { RideId ride_id; StationIndex stationIndex; - uint16_t vehicle_id; + EntityId vehicle_id; }; constexpr int32_t SYNCHRONISED_VEHICLE_COUNT = 16; @@ -2627,7 +2627,7 @@ static bool try_add_synchronised_station(const CoordsXYZ& coords) rct_synchronised_vehicle* sv = _lastSynchronisedVehicle; sv->ride_id = rideIndex; sv->stationIndex = stationIndex; - sv->vehicle_id = SPRITE_INDEX_NULL; + sv->vehicle_id = EntityId::GetNull(); _lastSynchronisedVehicle++; /* Ride vehicles are not on the track (e.g. ride is/was under @@ -2803,7 +2803,7 @@ static bool ride_station_can_depart_synchronised(const Ride& ride, StationIndex } } // There is no vehicle waiting at this station to sync with. - if (sv->vehicle_id == SPRITE_INDEX_NULL) + if (sv->vehicle_id.IsNull()) { // Check conditions for departing without all stations being in sync. if (_lastSynchronisedVehicle > &_synchronisedVehicles[1]) @@ -3528,8 +3528,8 @@ void Vehicle::UpdateCrashSetup() int32_t edx = velocity >> 10; Vehicle* lastVehicle = this; - uint16_t spriteId = sprite_index; - for (Vehicle* trainVehicle; spriteId != SPRITE_INDEX_NULL; spriteId = trainVehicle->next_vehicle_on_train) + auto spriteId = sprite_index; + for (Vehicle* trainVehicle; !spriteId.IsNull(); spriteId = trainVehicle->next_vehicle_on_train) { trainVehicle = GetEntity(spriteId); if (trainVehicle == nullptr) @@ -3999,12 +3999,12 @@ void Vehicle::UpdateUnloadingPassengers() if (curRide->mode == RideMode::ForwardRotation || curRide->mode == RideMode::BackwardRotation) { uint8_t seat = ((-Pitch) >> 3) & 0xF; - if (restraints_position == 255 && (peep[seat * 2] != SPRITE_INDEX_NULL)) + if (restraints_position == 255 && !peep[seat * 2].IsNull()) { next_free_seat -= 2; auto firstGuest = GetEntity(peep[seat * 2]); - peep[seat * 2] = SPRITE_INDEX_NULL; + peep[seat * 2] = EntityId::GetNull(); if (firstGuest != nullptr) { @@ -4013,7 +4013,7 @@ void Vehicle::UpdateUnloadingPassengers() } auto secondGuest = GetEntity(peep[seat * 2 + 1]); - peep[seat * 2 + 1] = SPRITE_INDEX_NULL; + peep[seat * 2 + 1] = EntityId::GetNull(); if (secondGuest != nullptr) { @@ -6164,7 +6164,7 @@ Vehicle* Vehicle::TrainHead() const prevVehicle = GetEntity(vehicle->prev_vehicle_on_ride); if (prevVehicle == nullptr) return nullptr; - if (prevVehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) + if (prevVehicle->next_vehicle_on_train.IsNull()) break; vehicle = prevVehicle; @@ -6176,15 +6176,16 @@ Vehicle* Vehicle::TrainHead() const Vehicle* Vehicle::TrainTail() const { const Vehicle* vehicle = this; - uint16_t spriteIndex; - while ((spriteIndex = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL) + EntityId spriteIndex = vehicle->next_vehicle_on_train; + while (!spriteIndex.IsNull()) { vehicle = GetEntity(spriteIndex); if (vehicle == nullptr) { return const_cast(this); } + spriteIndex = vehicle->next_vehicle_on_train; } return const_cast(vehicle); @@ -6249,8 +6250,7 @@ int32_t Vehicle::UpdateMotionDodgems() } } - uint16_t collideSprite = SPRITE_INDEX_NULL; - + auto collideSprite = EntityId::GetNull(); if (dodgems_collision_direction != 0) { uint8_t oldCollisionDirection = dodgems_collision_direction & 0x1E; @@ -6384,14 +6384,15 @@ static bool wouldCollideWithDodgemsTrackEdge( || coords.x + dodgemsCarRadius > rideRight || coords.y + dodgemsCarRadius > rideBottom; } -bool Vehicle::DodgemsCarWouldCollideAt(const CoordsXY& coords, uint16_t* collidedWith) const +// TODO: Return optional +bool Vehicle::DodgemsCarWouldCollideAt(const CoordsXY& coords, EntityId* collidedWith) const { auto trackType = GetTrackType(); if (wouldCollideWithDodgemsTrackEdge(coords, TrackLocation, trackType, (var_44 * 30) >> 9)) { if (collidedWith != nullptr) - *collidedWith = SPRITE_INDEX_NULL; + *collidedWith = EntityId::GetNull(); return true; } @@ -6979,7 +6980,7 @@ void Vehicle::UpdateSpinningCar() spinningInertia += 6; spinSpeed = dword_F64E08 >> spinningInertia; // Alternate the spin direction (roughly). Perhaps in future save a value to the track - if (sprite_index & 1) + if (sprite_index.ToUnderlying() & 1) { spin_speed -= spinSpeed; } @@ -7331,7 +7332,7 @@ void Vehicle::UpdateSceneryDoor() const int32_t direction = (GetTrackDirection() + trackCoordinates->rotation_end) & 3; AnimateSceneryDoor( - { wallCoords, static_cast(direction) }, TrackLocation, next_vehicle_on_train == SPRITE_INDEX_NULL); + { wallCoords, static_cast(direction) }, TrackLocation, next_vehicle_on_train.IsNull()); } template static void AnimateLandscapeDoor(TrackElement* trackElement, bool isLastVehicle) @@ -7368,7 +7369,7 @@ void Vehicle::UpdateLandscapeDoor() const auto* tileElement = map_get_track_element_at_from_ride(coords, ride); if (tileElement != nullptr && tileElement->GetType() == TileElementType::Track) { - AnimateLandscapeDoor(tileElement->AsTrack(), next_vehicle_on_train == SPRITE_INDEX_NULL); + AnimateLandscapeDoor(tileElement->AsTrack(), next_vehicle_on_train.IsNull()); } } @@ -7426,8 +7427,7 @@ void Vehicle::UpdateSceneryDoorBackwards() const int32_t direction = (GetTrackDirection() + trackCoordinates->rotation_begin) & 3; direction = direction_reverse(direction); - AnimateSceneryDoor( - { wallCoords, static_cast(direction) }, TrackLocation, next_vehicle_on_train == SPRITE_INDEX_NULL); + AnimateSceneryDoor({ wallCoords, static_cast(direction) }, TrackLocation, next_vehicle_on_train.IsNull()); } void Vehicle::UpdateLandscapeDoorBackwards() const @@ -7442,7 +7442,7 @@ void Vehicle::UpdateLandscapeDoorBackwards() const auto* tileElement = map_get_track_element_at_from_ride(coords, ride); if (tileElement != nullptr && tileElement->GetType() == TileElementType::Track) { - AnimateLandscapeDoor(tileElement->AsTrack(), next_vehicle_on_train == SPRITE_INDEX_NULL); + AnimateLandscapeDoor(tileElement->AsTrack(), next_vehicle_on_train.IsNull()); } } @@ -7532,7 +7532,7 @@ void Vehicle::UpdateReverserCarBogies() * @param z (dx) * @param otherVehicleIndex (bp) */ -bool Vehicle::UpdateMotionCollisionDetection(const CoordsXYZ& loc, uint16_t* otherVehicleIndex) +bool Vehicle::UpdateMotionCollisionDetection(const CoordsXYZ& loc, EntityId* otherVehicleIndex) { if (HasUpdateFlag(VEHICLE_UPDATE_FLAG_COLLISION_DISABLED)) return false; @@ -7861,7 +7861,7 @@ bool Vehicle::UpdateTrackMotionForwardsGetNewTrack(uint16_t trackType, Ride* cur if (tileElement->AsTrack()->IsBlockStart()) { - if (next_vehicle_on_train == SPRITE_INDEX_NULL) + if (next_vehicle_on_train.IsNull()) { tileElement->AsTrack()->SetBlockBrakeClosed(true); if (trackType == TrackElemType::BlockBrakes || trackType == TrackElemType::EndStation) @@ -8025,7 +8025,7 @@ bool Vehicle::UpdateTrackMotionForwardsGetNewTrack(uint16_t trackType, Ride* cur */ bool Vehicle::UpdateTrackMotionForwards(rct_ride_entry_vehicle* vehicleEntry, Ride* curRide, rct_ride_entry* rideEntry) { - uint16_t otherVehicleIndex = SPRITE_INDEX_NULL; + EntityId otherVehicleIndex = EntityId::GetNull(); loc_6DAEB9: auto trackType = GetTrackType(); if (trackType == TrackElemType::HeartLineTransferUp || trackType == TrackElemType::HeartLineTransferDown) @@ -8370,7 +8370,7 @@ bool Vehicle::UpdateTrackMotionBackwardsGetNewTrack(uint16_t trackType, Ride* cu { if (_vehicleVelocityF64E08 < 0) { - if (next_vehicle_on_train == SPRITE_INDEX_NULL) + if (next_vehicle_on_train.IsNull()) { trackType = tileElement->AsTrack()->GetTrackType(); const auto& ted = GetTrackElementDescriptor(trackType); @@ -8387,7 +8387,7 @@ bool Vehicle::UpdateTrackMotionBackwardsGetNewTrack(uint16_t trackType, Ride* cu if (HasUpdateFlag(VEHICLE_UPDATE_FLAG_ON_LIFT_HILL)) { ClearUpdateFlag(VEHICLE_UPDATE_FLAG_ON_LIFT_HILL); - if (next_vehicle_on_train == SPRITE_INDEX_NULL) + if (next_vehicle_on_train.IsNull()) { if (_vehicleVelocityF64E08 < 0) { @@ -8419,7 +8419,7 @@ bool Vehicle::UpdateTrackMotionBackwardsGetNewTrack(uint16_t trackType, Ride* cu */ bool Vehicle::UpdateTrackMotionBackwards(rct_ride_entry_vehicle* vehicleEntry, Ride* curRide, rct_ride_entry* rideEntry) { - uint16_t otherVehicleIndex = SPRITE_INDEX_NULL; + EntityId otherVehicleIndex = EntityId::GetNull(); while (true) { @@ -8566,7 +8566,7 @@ bool Vehicle::UpdateTrackMotionBackwards(rct_ride_entry_vehicle* vehicleEntry, R */ void Vehicle::UpdateTrackMotionMiniGolfVehicle(Ride* curRide, rct_ride_entry* rideEntry, rct_ride_entry_vehicle* vehicleEntry) { - uint16_t otherVehicleIndex = SPRITE_INDEX_NULL; + EntityId otherVehicleIndex = EntityId::GetNull(); TileElement* tileElement = nullptr; CoordsXYZ trackPos; int32_t direction{}; @@ -8935,7 +8935,7 @@ loc_6DCA9A: if (HasUpdateFlag(VEHICLE_UPDATE_FLAG_ON_LIFT_HILL)) { ClearUpdateFlag(VEHICLE_UPDATE_FLAG_ON_LIFT_HILL); - if (next_vehicle_on_train == SPRITE_INDEX_NULL) + if (next_vehicle_on_train.IsNull()) { if (_vehicleVelocityF64E08 < 0) { @@ -8981,7 +8981,7 @@ loc_6DCC2C: { if (_vehicleVelocityF64E08 >= 0) { - otherVehicleIndex = var_44; + otherVehicleIndex = EntityId::FromUnderlying(var_44); // Possibly wrong?. if (UpdateMotionCollisionDetection(trackPos, &otherVehicleIndex)) { goto loc_6DCD6B; @@ -9374,8 +9374,8 @@ int32_t Vehicle::UpdateTrackMotion(int32_t* outStation) // backwards. _vehicleFrontVehicle = vehicle; - uint16_t spriteId = vehicle->sprite_index; - while (spriteId != SPRITE_INDEX_NULL) + auto spriteId = vehicle->sprite_index; + while (!spriteId.IsNull()) { Vehicle* car = GetEntity(spriteId); if (car == nullptr) diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 7977c65153..d0ba04f143 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "../audio/audio.h" #include "../common.h" #include "../entity/EntityBase.h" @@ -120,13 +121,13 @@ struct Vehicle : EntityBase }; uint16_t TrackTypeAndDirection; CoordsXYZ TrackLocation; - uint16_t next_vehicle_on_train; + EntityId next_vehicle_on_train; // The previous vehicle on the same train or the last vehicle on the previous or only train. - uint16_t prev_vehicle_on_ride; + EntityId prev_vehicle_on_ride; // The next vehicle on the same train or the first vehicle on the next or only train - uint16_t next_vehicle_on_ride; + EntityId next_vehicle_on_ride; uint16_t var_44; uint16_t mass; @@ -150,7 +151,7 @@ struct Vehicle : EntityBase }; Status status; uint8_t sub_state; - uint16_t peep[32]; + EntityId peep[32]; uint8_t peep_tshirt_colours[32]; uint8_t num_seats; uint8_t num_peeps; @@ -173,7 +174,7 @@ struct Vehicle : EntityBase uint16_t var_C0; int16_t crash_y; uint16_t time_waiting; - uint16_t cable_lift_target; + EntityId cable_lift_target; }; uint8_t speed; uint8_t powered_acceleration; @@ -216,7 +217,7 @@ struct Vehicle : EntityBase void SetState(Vehicle::Status vehicleStatus, uint8_t subState = 0); bool IsGhost() const; void UpdateSoundParams(std::vector& vehicleSoundParamsList) const; - bool DodgemsCarWouldCollideAt(const CoordsXY& coords, uint16_t* spriteId) const; + bool DodgemsCarWouldCollideAt(const CoordsXY& coords, EntityId* spriteId) const; int32_t UpdateTrackMotion(int32_t* outStation); int32_t CableLiftUpdateTrackMotion(); GForces GetGForces() const; @@ -361,7 +362,7 @@ private: void UpdateTrackMotionMiniGolfVehicle(Ride* curRide, rct_ride_entry* rideEntry, rct_ride_entry_vehicle* vehicleEntry); bool UpdateTrackMotionForwardsGetNewTrack(uint16_t trackType, Ride* curRide, rct_ride_entry* rideEntry); bool UpdateTrackMotionBackwardsGetNewTrack(uint16_t trackType, Ride* curRide, uint16_t* progress); - bool UpdateMotionCollisionDetection(const CoordsXYZ& loc, uint16_t* otherVehicleIndex); + bool UpdateMotionCollisionDetection(const CoordsXYZ& loc, EntityId* otherVehicleIndex); void UpdateGoKartAttemptSwitchLanes(); void UpdateSceneryDoor() const; void UpdateSceneryDoorBackwards() const; @@ -514,7 +515,7 @@ enum #define VEHICLE_SEAT_PAIR_FLAG 0x80 #define VEHICLE_SEAT_NUM_MASK 0x7F -Vehicle* try_get_vehicle(uint16_t spriteIndex); +Vehicle* try_get_vehicle(EntityId spriteIndex); void vehicle_update_all(); void vehicle_sounds_update(); diff --git a/src/openrct2/ride/thrill/3dCinema.cpp b/src/openrct2/ride/thrill/3dCinema.cpp index ce8ed9cbd5..5be7aadac0 100644 --- a/src/openrct2/ride/thrill/3dCinema.cpp +++ b/src/openrct2/ride/thrill/3dCinema.cpp @@ -25,7 +25,7 @@ static void Paint3dCinemaDome( if (rideEntry == nullptr) return; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride.vehicles[0] != SPRITE_INDEX_NULL) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && !ride.vehicles[0].IsNull()) { session.InteractionType = ViewportInteractionItem::Entity; session.CurrentlyDrawnItem = GetEntity(ride.vehicles[0]); diff --git a/src/openrct2/ride/thrill/SwingingShip.cpp b/src/openrct2/ride/thrill/SwingingShip.cpp index 599ba55867..b68fecc534 100644 --- a/src/openrct2/ride/thrill/SwingingShip.cpp +++ b/src/openrct2/ride/thrill/SwingingShip.cpp @@ -101,7 +101,7 @@ static void PaintSwingingShipStructure( return; Vehicle* vehicle = nullptr; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride.vehicles[0] != SPRITE_INDEX_NULL) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && !ride.vehicles[0].IsNull()) { vehicle = GetEntity(ride.vehicles[0]); session.InteractionType = ViewportInteractionItem::Entity; diff --git a/src/openrct2/ride/thrill/Twist.cpp b/src/openrct2/ride/thrill/Twist.cpp index adb0af3980..bff5fa967e 100644 --- a/src/openrct2/ride/thrill/Twist.cpp +++ b/src/openrct2/ride/thrill/Twist.cpp @@ -34,7 +34,7 @@ static void paint_twist_structure( height += 7; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride.vehicles[0] != SPRITE_INDEX_NULL) + if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && !ride.vehicles[0].IsNull()) { vehicle = GetEntity(ride.vehicles[0]); diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index 64ba4bbc3a..c3da70094e 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -900,9 +900,9 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const Gam if (result.Error == GameActions::Status::Ok) { const auto actionResult = result.GetData(); - if (actionResult.StaffEntityId != SPRITE_INDEX_NULL) + if (!actionResult.StaffEntityId.IsNull()) { - obj.Set("peep", actionResult.StaffEntityId); + obj.Set("peep", actionResult.StaffEntityId.ToUnderlying()); } } } diff --git a/src/openrct2/scripting/bindings/entity/ScEntity.hpp b/src/openrct2/scripting/bindings/entity/ScEntity.hpp index cae3562a8d..7b4d9b03ad 100644 --- a/src/openrct2/scripting/bindings/entity/ScEntity.hpp +++ b/src/openrct2/scripting/bindings/entity/ScEntity.hpp @@ -29,10 +29,10 @@ namespace OpenRCT2::Scripting class ScEntity { protected: - uint16_t _id = SPRITE_INDEX_NULL; + EntityId _id{ EntityId::GetNull() }; public: - ScEntity(uint16_t id) + ScEntity(EntityId id) : _id(id) { } @@ -41,7 +41,7 @@ namespace OpenRCT2::Scripting int32_t id_get() const { auto entity = GetEntity(); - return entity != nullptr ? entity->sprite_index : 0; + return entity != nullptr ? entity->sprite_index.ToUnderlying() : EntityId::GetNull().ToUnderlying(); } std::string type_get() const diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.cpp b/src/openrct2/scripting/bindings/entity/ScGuest.cpp index fc5e715e93..bfbbc4c557 100644 --- a/src/openrct2/scripting/bindings/entity/ScGuest.cpp +++ b/src/openrct2/scripting/bindings/entity/ScGuest.cpp @@ -15,7 +15,7 @@ namespace OpenRCT2::Scripting { - ScGuest::ScGuest(uint16_t id) + ScGuest::ScGuest(EntityId id) : ScPeep(id) { } diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.hpp b/src/openrct2/scripting/bindings/entity/ScGuest.hpp index e387cb22d9..3c25b30109 100644 --- a/src/openrct2/scripting/bindings/entity/ScGuest.hpp +++ b/src/openrct2/scripting/bindings/entity/ScGuest.hpp @@ -18,7 +18,7 @@ namespace OpenRCT2::Scripting class ScGuest : public ScPeep { public: - ScGuest(uint16_t id); + ScGuest(EntityId id); static void Register(duk_context* ctx); diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.cpp b/src/openrct2/scripting/bindings/entity/ScLitter.cpp index 70f3118f7e..10cd481357 100644 --- a/src/openrct2/scripting/bindings/entity/ScLitter.cpp +++ b/src/openrct2/scripting/bindings/entity/ScLitter.cpp @@ -30,7 +30,7 @@ namespace OpenRCT2::Scripting { "empty_bowl_blue", Litter::Type::EmptyBowlBlue }, }); - ScLitter::ScLitter(uint16_t Id) + ScLitter::ScLitter(EntityId Id) : ScEntity(Id) { } diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.hpp b/src/openrct2/scripting/bindings/entity/ScLitter.hpp index 41b8b9f1e4..bc5ef1e82c 100644 --- a/src/openrct2/scripting/bindings/entity/ScLitter.hpp +++ b/src/openrct2/scripting/bindings/entity/ScLitter.hpp @@ -20,7 +20,7 @@ namespace OpenRCT2::Scripting class ScLitter : public ScEntity { public: - ScLitter(uint16_t Id); + ScLitter(EntityId Id); static void Register(duk_context* ctx); diff --git a/src/openrct2/scripting/bindings/entity/ScPeep.hpp b/src/openrct2/scripting/bindings/entity/ScPeep.hpp index 96173a3a29..d371e1a416 100644 --- a/src/openrct2/scripting/bindings/entity/ScPeep.hpp +++ b/src/openrct2/scripting/bindings/entity/ScPeep.hpp @@ -46,7 +46,7 @@ namespace OpenRCT2::Scripting class ScPeep : public ScEntity { public: - ScPeep(uint16_t id) + ScPeep(EntityId id) : ScEntity(id) { } diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.cpp b/src/openrct2/scripting/bindings/entity/ScStaff.cpp index 5f9b13bd10..4b57f53120 100644 --- a/src/openrct2/scripting/bindings/entity/ScStaff.cpp +++ b/src/openrct2/scripting/bindings/entity/ScStaff.cpp @@ -15,7 +15,7 @@ namespace OpenRCT2::Scripting { - ScStaff::ScStaff(uint16_t Id) + ScStaff::ScStaff(EntityId Id) : ScPeep(Id) { } diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.hpp b/src/openrct2/scripting/bindings/entity/ScStaff.hpp index 0102144075..d1c322cd8d 100644 --- a/src/openrct2/scripting/bindings/entity/ScStaff.hpp +++ b/src/openrct2/scripting/bindings/entity/ScStaff.hpp @@ -18,7 +18,7 @@ namespace OpenRCT2::Scripting class ScStaff : public ScPeep { public: - ScStaff(uint16_t Id); + ScStaff(EntityId Id); static void Register(duk_context* ctx); diff --git a/src/openrct2/scripting/bindings/entity/ScVehicle.cpp b/src/openrct2/scripting/bindings/entity/ScVehicle.cpp index d2f974335a..bf564ab0d2 100644 --- a/src/openrct2/scripting/bindings/entity/ScVehicle.cpp +++ b/src/openrct2/scripting/bindings/entity/ScVehicle.cpp @@ -49,7 +49,7 @@ namespace OpenRCT2::Scripting { "stopped_by_block_brake", Vehicle::Status::StoppedByBlockBrakes }, }); - ScVehicle::ScVehicle(uint16_t id) + ScVehicle::ScVehicle(EntityId id) : ScEntity(id) { } @@ -172,9 +172,9 @@ namespace OpenRCT2::Scripting auto vehicle = GetVehicle(); if (vehicle != nullptr) { - if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) + if (!vehicle->next_vehicle_on_train.IsNull()) { - return ToDuk(ctx, vehicle->next_vehicle_on_train); + return ToDuk(ctx, vehicle->next_vehicle_on_train.ToUnderlying()); } } return ToDuk(ctx, nullptr); @@ -187,11 +187,11 @@ namespace OpenRCT2::Scripting { if (value.type() == DukValue::Type::NUMBER) { - vehicle->next_vehicle_on_train = static_cast(value.as_int()); + vehicle->next_vehicle_on_train = EntityId::FromUnderlying(value.as_int()); } else { - vehicle->next_vehicle_on_train = SPRITE_INDEX_NULL; + vehicle->next_vehicle_on_train = EntityId::GetNull(); } } } @@ -199,7 +199,7 @@ namespace OpenRCT2::Scripting uint16_t ScVehicle::previousCarOnRide_get() const { auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->prev_vehicle_on_ride : 0; + return vehicle != nullptr ? vehicle->prev_vehicle_on_ride.ToUnderlying() : EntityId::GetNull().ToUnderlying(); } void ScVehicle::previousCarOnRide_set(uint16_t value) { @@ -207,14 +207,14 @@ namespace OpenRCT2::Scripting auto vehicle = GetVehicle(); if (vehicle != nullptr) { - vehicle->prev_vehicle_on_ride = value; + vehicle->prev_vehicle_on_ride = EntityId::FromUnderlying(value); } } uint16_t ScVehicle::nextCarOnRide_get() const { auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->next_vehicle_on_ride : 0; + return vehicle != nullptr ? vehicle->next_vehicle_on_ride.ToUnderlying() : EntityId::GetNull().ToUnderlying(); } void ScVehicle::nextCarOnRide_set(uint16_t value) { @@ -222,7 +222,7 @@ namespace OpenRCT2::Scripting auto vehicle = GetVehicle(); if (vehicle != nullptr) { - vehicle->next_vehicle_on_ride = value; + vehicle->next_vehicle_on_ride = EntityId::FromUnderlying(value); } } @@ -423,13 +423,13 @@ namespace OpenRCT2::Scripting for (size_t i = 0; i < std::size(vehicle->peep); i++) { auto peep = vehicle->peep[i]; - if (peep == SPRITE_INDEX_NULL) + if (peep.IsNull()) { result.push_back(ToDuk(ctx, nullptr)); } else { - result.push_back(ToDuk(ctx, peep)); + result.push_back(ToDuk(ctx, peep.ToUnderlying())); len = i + 1; } } diff --git a/src/openrct2/scripting/bindings/entity/ScVehicle.hpp b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp index c98cd5b3dc..743887f1c3 100644 --- a/src/openrct2/scripting/bindings/entity/ScVehicle.hpp +++ b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp @@ -19,7 +19,7 @@ namespace OpenRCT2::Scripting class ScVehicle : public ScEntity { public: - ScVehicle(uint16_t id); + ScVehicle(EntityId id); static void Register(duk_context* ctx); diff --git a/src/openrct2/scripting/bindings/ride/ScRide.cpp b/src/openrct2/scripting/bindings/ride/ScRide.cpp index 6e83c7d850..3150331a03 100644 --- a/src/openrct2/scripting/bindings/ride/ScRide.cpp +++ b/src/openrct2/scripting/bindings/ride/ScRide.cpp @@ -191,7 +191,10 @@ namespace OpenRCT2::Scripting auto ride = GetRide(); if (ride != nullptr) { - result.insert(result.begin(), std::begin(ride->vehicles), std::begin(ride->vehicles) + ride->num_vehicles); + for (auto& veh : ride->vehicles) + { + result.push_back(veh.ToUnderlying()); + } } return result; } diff --git a/src/openrct2/scripting/bindings/world/ScMap.cpp b/src/openrct2/scripting/bindings/world/ScMap.cpp index ef562464c9..c811d24c30 100644 --- a/src/openrct2/scripting/bindings/world/ScMap.cpp +++ b/src/openrct2/scripting/bindings/world/ScMap.cpp @@ -87,7 +87,7 @@ namespace OpenRCT2::Scripting { if (id >= 0 && id < MAX_ENTITIES) { - auto spriteId = static_cast(id); + auto spriteId = EntityId::FromUnderlying(id); auto sprite = GetEntity(spriteId); if (sprite != nullptr && sprite->Type != EntityType::Null) { @@ -112,7 +112,7 @@ namespace OpenRCT2::Scripting { for (auto trainHead : TrainManager::View()) { - for (auto carId = trainHead->sprite_index; carId != SPRITE_INDEX_NULL;) + for (auto carId = trainHead->sprite_index; !carId.IsNull();) { auto car = GetEntity(carId); result.push_back(GetObjectAsDukValue(_context, std::make_shared(carId))); diff --git a/src/openrct2/title/TitleSequence.cpp b/src/openrct2/title/TitleSequence.cpp index a5f9df4b97..600f876d03 100644 --- a/src/openrct2/title/TitleSequence.cpp +++ b/src/openrct2/title/TitleSequence.cpp @@ -371,7 +371,7 @@ static std::vector LegacyScriptRead(const std::vector& sc else if (_stricmp(token, "FOLLOW") == 0) { command.Type = TitleScript::Follow; - command.SpriteIndex = atoi(part1) & 0xFFFF; + command.SpriteIndex = EntityId::FromUnderlying(atoi(part1) & 0xFFFF); safe_strcpy(command.SpriteName, part2, USER_STRING_MAX_LENGTH); } else if (_stricmp(token, "WAIT") == 0) diff --git a/src/openrct2/title/TitleSequence.h b/src/openrct2/title/TitleSequence.h index 62c64d1593..893f23e4cc 100644 --- a/src/openrct2/title/TitleSequence.h +++ b/src/openrct2/title/TitleSequence.h @@ -32,7 +32,7 @@ struct TitleCommand uint8_t Zoom; // ZOOM struct // FOLLOW { - uint16_t SpriteIndex; + EntityId SpriteIndex; utf8 SpriteName[USER_STRING_MAX_LENGTH]; }; uint8_t Speed; // SPEED