diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index c524ab3eef..0a27d8104c 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -582,7 +582,7 @@ bool ViewportInteractionRightClick(const ScreenCoordsXY& screenCoords) ViewportInteractionRemoveLargeScenery(info.Element, info.Loc); break; case ViewportInteractionItem::Banner: - context_open_detail_window(WD_BANNER, info.Element->AsBanner()->GetIndex()); + context_open_detail_window(WD_BANNER, info.Element->AsBanner()->GetIndex().ToUnderlying()); break; } @@ -669,7 +669,7 @@ static void ViewportInteractionRemoveParkWall(TileElement* tileElement, const Co auto* wallEntry = tileElement->AsWall()->GetEntry(); if (wallEntry->scrolling_mode != SCROLLING_MODE_NONE) { - context_open_detail_window(WD_SIGN_SMALL, tileElement->AsWall()->GetBannerIndex()); + context_open_detail_window(WD_SIGN_SMALL, tileElement->AsWall()->GetBannerIndex().ToUnderlying()); } else { @@ -690,7 +690,7 @@ static void ViewportInteractionRemoveLargeScenery(TileElement* tileElement, cons if (sceneryEntry->scrolling_mode != SCROLLING_MODE_NONE) { auto bannerIndex = tileElement->AsLargeScenery()->GetBannerIndex(); - context_open_detail_window(WD_SIGN, bannerIndex); + context_open_detail_window(WD_SIGN, bannerIndex.ToUnderlying()); } else { diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index bcb64c179e..7482c8be4f 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -88,9 +88,14 @@ private: Invalidate(); } + BannerIndex GetBannerIndex() const + { + return BannerIndex::FromUnderlying(number); + } + BannerElement* GetBannerElement() { - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { return nullptr; @@ -109,7 +114,7 @@ private: { continue; } - if (bannerElement->GetIndex() == number) + if (bannerElement->GetIndex() == GetBannerIndex()) { return bannerElement; } @@ -131,7 +136,7 @@ public: void Initialise(rct_windownumber _number) { number = _number; - auto* banner = GetBanner(number); + auto* banner = GetBanner(BannerIndex::FromUnderlying(number)); auto* bannerElement = GetBannerElement(); if (bannerElement == nullptr) @@ -144,7 +149,7 @@ public: void OnMouseDown(rct_widgetindex widgetIndex) override { rct_widget* widget = &widgets[widgetIndex]; - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { Close(); @@ -177,7 +182,7 @@ public: void OnMouseUp(rct_widgetindex widgetIndex) override { - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { Close(); @@ -207,7 +212,7 @@ public: { textinput_cancel(); auto bannerSetStyle = BannerSetStyleAction( - BannerSetStyleType::NoEntry, number, banner->flags ^ BANNER_FLAG_NO_ENTRY); + BannerSetStyleType::NoEntry, GetBannerIndex(), banner->flags ^ BANNER_FLAG_NO_ENTRY); GameActions::Execute(&bannerSetStyle); break; } @@ -223,7 +228,7 @@ public: if (dropdownIndex == -1) break; - auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::PrimaryColour, number, dropdownIndex); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::PrimaryColour, GetBannerIndex(), dropdownIndex); GameActions::Execute(&bannerSetStyle); break; } @@ -231,7 +236,7 @@ public: { if (dropdownIndex == -1) break; - auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::TextColour, number, dropdownIndex + 1); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::TextColour, GetBannerIndex(), dropdownIndex + 1); GameActions::Execute(&bannerSetStyle); break; } @@ -242,7 +247,7 @@ public: { if (widgetIndex == WIDX_BANNER_TEXT) { - auto bannerSetNameAction = BannerSetNameAction(number, std::string(text)); + auto bannerSetNameAction = BannerSetNameAction(GetBannerIndex(), std::string(text)); GameActions::Execute(&bannerSetNameAction); } } @@ -265,7 +270,7 @@ public: void OnPrepareDraw() override { - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { return; diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index d7e8a463c2..1554c83416 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -59,9 +59,14 @@ class SignWindow final : public Window private: bool _isSmall = false; + BannerIndex GetBannerIndex() const + { + return BannerIndex::FromUnderlying(number); + } + void ShowTextInput() { - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner != nullptr) { auto bannerText = banner->GetText(); @@ -87,14 +92,14 @@ public: { number = windowNumber; _isSmall = isSmall; - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { return false; } auto signViewPosition = banner->position.ToCoordsXY().ToTileCentre(); - auto* tileElement = banner_get_tile_element(number); + auto* tileElement = banner_get_tile_element(GetBannerIndex()); if (tileElement == nullptr) return false; @@ -138,7 +143,7 @@ public: void OnMouseUp(rct_widgetindex widgetIndex) override { - auto* banner = GetBanner(number); + auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { Close(); @@ -151,7 +156,7 @@ public: break; case WIDX_SIGN_DEMOLISH: { - auto* tileElement = banner_get_tile_element(number); + auto* tileElement = banner_get_tile_element(GetBannerIndex()); if (tileElement == nullptr) { Close(); @@ -203,7 +208,7 @@ public: if (dropdownIndex == -1) return; list_information_type = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(number, dropdownIndex, var_492, !_isSmall); + auto signSetStyleAction = SignSetStyleAction(GetBannerIndex(), dropdownIndex, var_492, !_isSmall); GameActions::Execute(&signSetStyleAction); break; } @@ -212,7 +217,7 @@ public: if (dropdownIndex == -1) return; var_492 = dropdownIndex; - auto signSetStyleAction = SignSetStyleAction(number, list_information_type, dropdownIndex, !_isSmall); + auto signSetStyleAction = SignSetStyleAction(GetBannerIndex(), list_information_type, dropdownIndex, !_isSmall); GameActions::Execute(&signSetStyleAction); break; } @@ -227,7 +232,7 @@ public: { if (widgetIndex == WIDX_SIGN_TEXT && !text.empty()) { - auto signSetNameAction = SignSetNameAction(number, std::string(text)); + auto signSetNameAction = SignSetNameAction(GetBannerIndex(), std::string(text)); GameActions::Execute(&signSetNameAction); } } @@ -288,7 +293,7 @@ public: { RemoveViewport(); - auto banner = GetBanner(number); + auto banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { return; diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index e1236a8729..9b5a039a01 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -2356,8 +2356,8 @@ static void WindowTileInspectorScrollpaint(rct_window* w, rct_drawpixelinfo* dpi break; case TILE_ELEMENT_TYPE_BANNER: snprintf( - buffer, sizeof(buffer), "%s (%d)", language_get_string(STR_BANNER_WINDOW_TITLE), - tileElement->AsBanner()->GetIndex()); + buffer, sizeof(buffer), "%s (%u)", language_get_string(STR_BANNER_WINDOW_TITLE), + tileElement->AsBanner()->GetIndex().ToUnderlying()); typeName = buffer; break; default: diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 08d2369e4d..32c01e4d84 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2005,7 +2005,7 @@ static void WindowTopToolbarSceneryToolDown(const ScreenCoordsXY& windowPos, rct { auto data = result->GetData(); OpenRCT2::Audio::Play3D(OpenRCT2::Audio::SoundId::PlaceItem, result->Position); - context_open_detail_window(WD_BANNER, data.bannerId); + context_open_detail_window(WD_BANNER, data.bannerId.ToUnderlying()); } }); GameActions::Execute(&bannerPlaceAction); diff --git a/src/openrct2/Identifiers.h b/src/openrct2/Identifiers.h index d4e2f1c557..aa008e87d9 100644 --- a/src/openrct2/Identifiers.h +++ b/src/openrct2/Identifiers.h @@ -15,3 +15,5 @@ #include using ParkEntranceIndex = TIdentifier::max(), struct ParkEntranceIndexTag>; + +using BannerIndex = TIdentifier::max(), struct BannerIndexTag>; diff --git a/src/openrct2/ParkFile.cpp b/src/openrct2/ParkFile.cpp index 2bba172259..4b08dae306 100644 --- a/src/openrct2/ParkFile.cpp +++ b/src/openrct2/ParkFile.cpp @@ -983,9 +983,9 @@ namespace OpenRCT2 cs.Write(static_cast(numBanners)); [[maybe_unused]] size_t numWritten = 0; - for (BannerIndex i = 0; i < MAX_BANNERS; i++) + for (BannerIndex::UnderlyingType i = 0; i < MAX_BANNERS; i++) { - auto banner = GetBanner(i); + auto banner = GetBanner(BannerIndex::FromUnderlying(i)); if (banner != nullptr) { ReadWriteBanner(version, cs, *banner); @@ -1001,9 +1001,9 @@ namespace OpenRCT2 { std::vector banners; cs.ReadWriteVector(banners, [version, &cs](Banner& banner) { ReadWriteBanner(version, cs, banner); }); - for (size_t i = 0; i < banners.size(); i++) + for (BannerIndex::UnderlyingType i = 0; i < banners.size(); i++) { - auto bannerIndex = static_cast(i); + auto bannerIndex = BannerIndex::FromUnderlying(i); auto banner = GetOrCreateBanner(bannerIndex); if (banner != nullptr) { diff --git a/src/openrct2/actions/BannerPlaceAction.h b/src/openrct2/actions/BannerPlaceAction.h index 3afc75ea50..54c945e42c 100644 --- a/src/openrct2/actions/BannerPlaceAction.h +++ b/src/openrct2/actions/BannerPlaceAction.h @@ -13,7 +13,7 @@ struct BannerPlaceActionResult { - BannerIndex bannerId = BANNER_INDEX_NULL; + BannerIndex bannerId = BannerIndex::GetNull(); }; class BannerPlaceAction final : public GameActionBase diff --git a/src/openrct2/actions/BannerRemoveAction.cpp b/src/openrct2/actions/BannerRemoveAction.cpp index eff4cc43cb..2495ad3ebd 100644 --- a/src/openrct2/actions/BannerRemoveAction.cpp +++ b/src/openrct2/actions/BannerRemoveAction.cpp @@ -62,7 +62,7 @@ GameActions::Result BannerRemoveAction::Query() const } auto bannerIndex = bannerElement->GetIndex(); - if (bannerIndex == BANNER_INDEX_NULL) + if (bannerIndex == BannerIndex::GetNull()) { log_error("Invalid banner index. index = ", bannerIndex); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REMOVE_THIS, STR_NONE); @@ -101,7 +101,7 @@ GameActions::Result BannerRemoveAction::Execute() const } auto bannerIndex = bannerElement->GetIndex(); - if (bannerIndex == BANNER_INDEX_NULL) + if (bannerIndex == BannerIndex::GetNull()) { log_error("Invalid banner index. index = ", bannerIndex); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REMOVE_THIS, STR_NONE); diff --git a/src/openrct2/actions/BannerSetNameAction.h b/src/openrct2/actions/BannerSetNameAction.h index 42ea2b99bb..a129753a75 100644 --- a/src/openrct2/actions/BannerSetNameAction.h +++ b/src/openrct2/actions/BannerSetNameAction.h @@ -14,7 +14,7 @@ class BannerSetNameAction final : public GameActionBase { private: - BannerIndex _bannerIndex{ BANNER_INDEX_NULL }; + BannerIndex _bannerIndex{ BannerIndex::GetNull() }; std::string _name; public: diff --git a/src/openrct2/actions/BannerSetStyleAction.h b/src/openrct2/actions/BannerSetStyleAction.h index 0a6beef6a6..06b86031b0 100644 --- a/src/openrct2/actions/BannerSetStyleAction.h +++ b/src/openrct2/actions/BannerSetStyleAction.h @@ -25,7 +25,7 @@ class BannerSetStyleAction final : public GameActionBase(value); } + template void Visit(std::string_view name, TIdentifier& param) + { + auto value = param.ToUnderlying(); + Visit(name, value); + param = TIdentifier::FromUnderlying(value); + } + template void Visit(std::string_view name, NetworkObjectId_t& param) { Visit(name, param.id); diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.h b/src/openrct2/actions/LargeSceneryPlaceAction.h index 07f9d38330..4eb294bd79 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.h +++ b/src/openrct2/actions/LargeSceneryPlaceAction.h @@ -17,7 +17,7 @@ struct LargeSceneryPlaceActionResult { uint8_t GroundFlags{ 0 }; int32_t firstTileHeight{ 0 }; - BannerIndex bannerId = BANNER_INDEX_NULL; + BannerIndex bannerId = BannerIndex::GetNull(); }; class LargeSceneryPlaceAction final : public GameActionBase diff --git a/src/openrct2/actions/SignSetNameAction.h b/src/openrct2/actions/SignSetNameAction.h index 4d69ceeffe..07019484eb 100644 --- a/src/openrct2/actions/SignSetNameAction.h +++ b/src/openrct2/actions/SignSetNameAction.h @@ -14,7 +14,7 @@ class SignSetNameAction final : public GameActionBase { private: - BannerIndex _bannerIndex{ BANNER_INDEX_NULL }; + BannerIndex _bannerIndex{ BannerIndex::GetNull() }; std::string _name; public: diff --git a/src/openrct2/actions/SignSetStyleAction.h b/src/openrct2/actions/SignSetStyleAction.h index 246ce8d23b..990554c669 100644 --- a/src/openrct2/actions/SignSetStyleAction.h +++ b/src/openrct2/actions/SignSetStyleAction.h @@ -14,7 +14,7 @@ class SignSetStyleAction final : public GameActionBase { private: - BannerIndex _bannerIndex{ BANNER_INDEX_NULL }; + BannerIndex _bannerIndex{ BannerIndex::GetNull() }; uint8_t _mainColour{}; uint8_t _textColour{}; bool _isLarge{}; diff --git a/src/openrct2/actions/WallPlaceAction.cpp b/src/openrct2/actions/WallPlaceAction.cpp index 6fb3b83f3c..1d6053c34b 100644 --- a/src/openrct2/actions/WallPlaceAction.cpp +++ b/src/openrct2/actions/WallPlaceAction.cpp @@ -371,7 +371,7 @@ GameActions::Result WallPlaceAction::Execute() const wallElement->SetAcrossTrack(wallAcrossTrack); wallElement->SetEntryIndex(_wallType); - wallElement->SetBannerIndex(banner != nullptr ? banner->id : BANNER_INDEX_NULL); + wallElement->SetBannerIndex(banner != nullptr ? banner->id : BannerIndex::GetNull()); if (wallEntry->flags & WALL_SCENERY_HAS_TERNARY_COLOUR) { @@ -385,7 +385,7 @@ GameActions::Result WallPlaceAction::Execute() const res.Cost = wallEntry->price; - const auto bannerId = banner != nullptr ? banner->id : BANNER_INDEX_NULL; + const auto bannerId = banner != nullptr ? banner->id : BannerIndex::GetNull(); res.SetData(WallPlaceActionResult{ wallElement->GetBaseZ(), bannerId }); return res; diff --git a/src/openrct2/actions/WallPlaceAction.h b/src/openrct2/actions/WallPlaceAction.h index 094d813b5a..fdca3e5099 100644 --- a/src/openrct2/actions/WallPlaceAction.h +++ b/src/openrct2/actions/WallPlaceAction.h @@ -18,7 +18,7 @@ struct WallPlaceActionResult { int32_t BaseHeight{}; - BannerIndex BannerId = BANNER_INDEX_NULL; + BannerIndex BannerId = BannerIndex::GetNull(); }; class WallPlaceAction final : public GameActionBase diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index e4855f5068..ea0aa1536e 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -839,3 +839,24 @@ template<> struct DataSerializerTraits_t stream->Write(msg, strlen(msg)); } }; + +template struct DataSerializerTraits_t> +{ + static void encode(OpenRCT2::IStream* stream, const TIdentifier& id) + { + stream->WriteValue(ByteSwapBE(id.ToUnderlying())); + } + + static void decode(OpenRCT2::IStream* stream, TIdentifier& id) + { + auto temp = ByteSwapBE(stream->ReadValue()); + id = TIdentifier::FromUnderlying(temp); + } + + static void log(OpenRCT2::IStream* stream, const TIdentifier& id) + { + char msg[128] = {}; + snprintf(msg, sizeof(msg), "Id(%u)", static_cast(id.ToUnderlying())); + stream->Write(msg, strlen(msg)); + } +}; diff --git a/src/openrct2/core/Identifier.hpp b/src/openrct2/core/Identifier.hpp index 22fe9b0981..e93f8f17ae 100644 --- a/src/openrct2/core/Identifier.hpp +++ b/src/openrct2/core/Identifier.hpp @@ -32,6 +32,8 @@ private: } public: + using UnderlyingType = T; + constexpr TIdentifier() = default; static constexpr TIdentifier GetNull() noexcept @@ -63,4 +65,14 @@ public: { return _handle != other; } + + constexpr bool operator==(const TIdentifier& other) const noexcept + { + return _handle == other._handle; + } + + constexpr bool operator!=(const TIdentifier& other) const noexcept + { + return _handle != other._handle; + } }; diff --git a/src/openrct2/core/OrcaStream.hpp b/src/openrct2/core/OrcaStream.hpp index fbc330ae51..e5efb77ac9 100644 --- a/src/openrct2/core/OrcaStream.hpp +++ b/src/openrct2/core/OrcaStream.hpp @@ -12,6 +12,7 @@ #include "../world/Location.hpp" #include "Crypt.h" #include "FileStream.h" +#include "Identifier.hpp" #include "MemoryStream.h" #include @@ -312,6 +313,21 @@ namespace OpenRCT2 } } + template void ReadWrite(TIdentifier& value) + { + if (_mode == Mode::READING) + { + T temp{}; + ReadWrite(temp); + value = TIdentifier::FromUnderlying(temp); + } + else + { + auto temp = value.ToUnderlying(); + ReadWrite(temp); + } + } + void ReadWrite(bool& value) { uint8_t value8 = value ? 1 : 0; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index aaae9dc72b..3a370e732d 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1790,7 +1790,7 @@ namespace RCT1 wallElement->SetPrimaryColour(colourA); wallElement->SetSecondaryColour(colourB); wallElement->SetTertiaryColour(colourC); - wallElement->SetBannerIndex(BANNER_INDEX_NULL); + wallElement->SetBannerIndex(BannerIndex::GetNull()); wallElement->SetAcrossTrack(false); wallElement->SetAnimationIsBackwards(false); wallElement->SetSlope(edgeSlope); @@ -1826,20 +1826,20 @@ namespace RCT1 if (index < std::size(_s4.banners)) { auto srcBanner = &_s4.banners[index]; - auto dstBanner = GetOrCreateBanner(index); + auto dstBanner = GetOrCreateBanner(BannerIndex::FromUnderlying(index)); if (dstBanner == nullptr) { - dst2->SetIndex(BANNER_INDEX_NULL); + dst2->SetIndex(BannerIndex::GetNull()); } else { ImportBanner(dstBanner, srcBanner); - dst2->SetIndex(index); + dst2->SetIndex(BannerIndex::FromUnderlying(index)); } } else { - dst2->SetIndex(BANNER_INDEX_NULL); + dst2->SetIndex(BannerIndex::GetNull()); } return 1; } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index df1dd8ac9e..3245943627 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -520,14 +520,14 @@ namespace RCT2 // This scenario breaks pathfinding. Create passages between the worlds. (List is grouped by neighbouring // tiles.) // clang-format off - FixLandOwnershipTilesWithOwnership( - { - { 67, 94 }, { 68, 94 }, { 69, 94 }, - { 58, 24 }, { 58, 25 }, { 58, 26 }, { 58, 27 }, { 58, 28 }, { 58, 29 }, { 58, 30 }, { 58, 31 }, { 58, 32 }, - { 26, 44 }, { 26, 45 }, - { 32, 79 }, { 32, 80 }, { 32, 81 }, - }, - OWNERSHIP_OWNED); + FixLandOwnershipTilesWithOwnership( + { + { 67, 94 }, { 68, 94 }, { 69, 94 }, + { 58, 24 }, { 58, 25 }, { 58, 26 }, { 58, 27 }, { 58, 28 }, { 58, 29 }, { 58, 30 }, { 58, 31 }, { 58, 32 }, + { 26, 44 }, { 26, 45 }, + { 32, 79 }, { 32, 80 }, { 32, 81 }, + }, + OWNERSHIP_OWNED); // clang-format on } else if (String::Equals(gScenarioFileName, "N America - Extreme Hawaiian Island.SC6")) @@ -1364,7 +1364,7 @@ namespace RCT2 dst2->SetAnimationIsBackwards(src2->AnimationIsBackwards()); // Import banner information - dst2->SetBannerIndex(BANNER_INDEX_NULL); + dst2->SetBannerIndex(BannerIndex::GetNull()); auto entry = dst2->GetEntry(); if (entry != nullptr && entry->scrolling_mode != SCROLLING_MODE_NONE) { @@ -1372,15 +1372,15 @@ namespace RCT2 if (bannerIndex < std::size(_s6.banners)) { auto srcBanner = &_s6.banners[bannerIndex]; - auto dstBanner = GetOrCreateBanner(bannerIndex); + auto dstBanner = GetOrCreateBanner(BannerIndex::FromUnderlying(bannerIndex)); if (dstBanner == nullptr) { - dst2->SetBannerIndex(BANNER_INDEX_NULL); + dst2->SetBannerIndex(BannerIndex::GetNull()); } else { ImportBanner(dstBanner, srcBanner); - dst2->SetBannerIndex(src2->GetBannerIndex()); + dst2->SetBannerIndex(BannerIndex::FromUnderlying(src2->GetBannerIndex())); } } } @@ -1397,7 +1397,7 @@ namespace RCT2 dst2->SetSecondaryColour(src2->GetSecondaryColour()); // Import banner information - dst2->SetBannerIndex(BANNER_INDEX_NULL); + dst2->SetBannerIndex(BannerIndex::GetNull()); auto entry = dst2->GetEntry(); if (entry != nullptr && entry->scrolling_mode != SCROLLING_MODE_NONE) { @@ -1405,15 +1405,15 @@ namespace RCT2 if (bannerIndex < std::size(_s6.banners)) { auto srcBanner = &_s6.banners[bannerIndex]; - auto dstBanner = GetOrCreateBanner(bannerIndex); + auto dstBanner = GetOrCreateBanner(BannerIndex::FromUnderlying(bannerIndex)); if (dstBanner == nullptr) { - dst2->SetBannerIndex(BANNER_INDEX_NULL); + dst2->SetBannerIndex(BannerIndex::GetNull()); } else { ImportBanner(dstBanner, srcBanner); - dst2->SetBannerIndex(src2->GetBannerIndex()); + dst2->SetBannerIndex(BannerIndex::FromUnderlying(src2->GetBannerIndex())); } } } @@ -1431,20 +1431,20 @@ namespace RCT2 if (bannerIndex < std::size(_s6.banners)) { auto srcBanner = &_s6.banners[bannerIndex]; - auto dstBanner = GetOrCreateBanner(bannerIndex); + auto dstBanner = GetOrCreateBanner(BannerIndex::FromUnderlying(bannerIndex)); if (dstBanner == nullptr) { - dst2->SetIndex(BANNER_INDEX_NULL); + dst2->SetIndex(BannerIndex::GetNull()); } else { ImportBanner(dstBanner, srcBanner); - dst2->SetIndex(bannerIndex); + dst2->SetIndex(BannerIndex::FromUnderlying(bannerIndex)); } } else { - dst2->SetIndex(BANNER_INDEX_NULL); + dst2->SetIndex(BannerIndex::GetNull()); } break; } diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index 1cdd6952f5..c00b4a2f09 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -1034,35 +1034,36 @@ namespace OpenRCT2::Scripting { auto ctx = GetContext()->GetScriptEngine().GetContext(); BannerIndex idx = _element->GetBannerIndex(); - if (idx == BANNER_INDEX_NULL) + if (idx == BannerIndex::GetNull()) duk_push_null(ctx); else - duk_push_int(ctx, idx); + duk_push_int(ctx, idx.ToUnderlying()); return DukValue::take_from_stack(ctx); } void ScTileElement::bannerIndex_set(uint16_t value) { ThrowIfGameStateNotMutable(); + switch (_element->GetType()) { case TILE_ELEMENT_TYPE_LARGE_SCENERY: { auto el = _element->AsLargeScenery(); - el->SetBannerIndex(value); + el->SetBannerIndex(BannerIndex::FromUnderlying(value)); Invalidate(); break; } case TILE_ELEMENT_TYPE_WALL: { auto el = _element->AsWall(); - el->SetBannerIndex(value); + el->SetBannerIndex(BannerIndex::FromUnderlying(value)); Invalidate(); break; } case TILE_ELEMENT_TYPE_BANNER: { auto el = _element->AsBanner(); - el->SetIndex(value); + el->SetIndex(BannerIndex::FromUnderlying(value)); Invalidate(); break; } diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index 77c5ecbb03..962479ea52 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -10,6 +10,7 @@ #pragma once #include "../common.h" +#include "../core/Identifier.hpp" #include "../interface/Window.h" #include @@ -54,6 +55,12 @@ public: Intent* putExtra(uint32_t key, int32_t value); Intent* putExtra(uint32_t key, std::string value); Intent* putExtra(uint32_t key, close_callback value); + + template Intent* putExtra(uint32_t key, const TIdentifier& value) + { + const auto val = value.ToUnderlying(); + return putExtra(key, static_cast(val)); + } }; enum diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 98b5c77457..6021e8226d 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -113,22 +113,22 @@ static ride_id_t banner_get_ride_index_at(const CoordsXYZ& bannerCoords) static BannerIndex BannerGetNewIndex() { - for (BannerIndex bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) + for (BannerIndex::UnderlyingType bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) { if (bannerIndex < _banners.size()) { if (_banners[bannerIndex].IsNull()) { - return bannerIndex; + return BannerIndex::FromUnderlying(bannerIndex); } } else { _banners.emplace_back(); - return static_cast(_banners.size() - 1); + return BannerIndex::FromUnderlying(bannerIndex); } } - return BANNER_INDEX_NULL; + return BannerIndex::GetNull(); } /** @@ -238,12 +238,13 @@ ride_id_t banner_get_closest_ride_index(const CoordsXYZ& mapPos) void banner_reset_broken_index() { - for (BannerIndex bannerIndex = 0; bannerIndex < _banners.size(); bannerIndex++) + for (BannerIndex::UnderlyingType index = 0; index < _banners.size(); index++) { - auto tileElement = banner_get_tile_element(bannerIndex); + const auto bannerId = BannerIndex::FromUnderlying(index); + auto tileElement = banner_get_tile_element(bannerId); if (tileElement == nullptr) { - auto banner = GetBanner(bannerIndex); + auto banner = GetBanner(bannerId); if (banner != nullptr) { banner->type = BANNER_NULL; @@ -266,13 +267,14 @@ void fix_duplicated_banners() for (auto* bannerElement : OpenRCT2::TileElementsView(bannerPos)) { auto bannerIndex = bannerElement->GetIndex(); - if (bannerIndex == BANNER_INDEX_NULL) + if (bannerIndex == BannerIndex::GetNull()) continue; - if (activeBanners[bannerIndex]) + const auto index = bannerIndex.ToUnderlying(); + if (activeBanners[index]) { log_info( - "Duplicated banner with index %d found at x = %d, y = %d and z = %d.", bannerIndex, x, y, + "Duplicated banner with index %d found at x = %d, y = %d and z = %d.", index, x, y, bannerElement->base_height); // Banner index is already in use by another banner, so duplicate it @@ -282,7 +284,7 @@ void fix_duplicated_banners() log_error("Failed to create new banner."); continue; } - Guard::Assert(!activeBanners[newBanner->id]); + Guard::Assert(!activeBanners[index]); // Copy over the original banner, but update the location const auto* oldBanner = GetBanner(bannerIndex); @@ -299,7 +301,7 @@ void fix_duplicated_banners() } // Mark banner index as in-use - activeBanners[bannerIndex] = true; + activeBanners[index] = true; } } } @@ -383,9 +385,10 @@ void UnlinkAllBannersForRide(ride_id_t rideId) Banner* GetBanner(BannerIndex id) { - if (id < _banners.size()) + const auto index = id.ToUnderlying(); + if (index < _banners.size()) { - auto banner = &_banners[id]; + auto banner = &_banners[index]; if (banner != nullptr && !banner->IsNull()) { return banner; @@ -396,14 +399,15 @@ Banner* GetBanner(BannerIndex id) Banner* GetOrCreateBanner(BannerIndex id) { - if (id < MAX_BANNERS) + const auto index = id.ToUnderlying(); + if (index < MAX_BANNERS) { - if (id >= _banners.size()) + if (index >= _banners.size()) { - _banners.resize(id + 1); + _banners.resize(index + 1); } // Create the banner - auto& banner = _banners[id]; + auto& banner = _banners[index]; banner.id = id; return &banner; } diff --git a/src/openrct2/world/Banner.h b/src/openrct2/world/Banner.h index e4ad35c2ec..4be4ddb115 100644 --- a/src/openrct2/world/Banner.h +++ b/src/openrct2/world/Banner.h @@ -9,6 +9,7 @@ #pragma once +#include "../Identifiers.h" #include "../common.h" #include "../ride/RideTypes.h" #include "Location.hpp" @@ -19,17 +20,14 @@ class Formatter; struct TileElement; struct WallElement; -using BannerIndex = uint16_t; - constexpr ObjectEntryIndex BANNER_NULL = OBJECT_ENTRY_INDEX_NULL; constexpr size_t MAX_BANNERS = 8192; -constexpr BannerIndex BANNER_INDEX_NULL = static_cast(-1); constexpr uint8_t SCROLLING_MODE_NONE = 255; struct Banner { - BannerIndex id = BANNER_INDEX_NULL; + BannerIndex id = BannerIndex::GetNull(); ObjectEntryIndex type = BANNER_NULL; uint8_t flags{}; std::string text; diff --git a/src/openrct2/world/TileElement.cpp b/src/openrct2/world/TileElement.cpp index 8599c899aa..4a5354bbc6 100644 --- a/src/openrct2/world/TileElement.cpp +++ b/src/openrct2/world/TileElement.cpp @@ -37,7 +37,7 @@ BannerIndex TileElement::GetBannerIndex() const { auto* sceneryEntry = AsLargeScenery()->GetEntry(); if (sceneryEntry == nullptr || sceneryEntry->scrolling_mode == SCROLLING_MODE_NONE) - return BANNER_INDEX_NULL; + return BannerIndex::GetNull(); return AsLargeScenery()->GetBannerIndex(); } @@ -45,14 +45,14 @@ BannerIndex TileElement::GetBannerIndex() const { auto* wallEntry = AsWall()->GetEntry(); if (wallEntry == nullptr || wallEntry->scrolling_mode == SCROLLING_MODE_NONE) - return BANNER_INDEX_NULL; + return BannerIndex::GetNull(); return AsWall()->GetBannerIndex(); } case TILE_ELEMENT_TYPE_BANNER: return AsBanner()->GetIndex(); default: - return BANNER_INDEX_NULL; + return BannerIndex::GetNull(); } } @@ -81,7 +81,7 @@ void TileElement::RemoveBannerEntry() auto banner = GetBanner(bannerIndex); if (banner != nullptr) { - window_close_by_number(WC_BANNER, bannerIndex); + window_close_by_number(WC_BANNER, bannerIndex.ToUnderlying()); DeleteBanner(banner->id); } } diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 924ed2b9df..7a50ac4dc0 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -328,7 +328,7 @@ namespace OpenRCT2::TileInspector { // Check if the element to be pasted refers to a banner index auto bannerIndex = element.GetBannerIndex(); - if (bannerIndex != BANNER_INDEX_NULL) + if (bannerIndex != BannerIndex::GetNull()) { // The element to be pasted refers to a banner index - make a copy of it auto newBanner = CreateBanner();