From 1f5e9ac28521eed849a56cb7ec63b62823d14f76 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 20 May 2023 10:33:02 +0200 Subject: [PATCH] Clean up path additions entry index handling (#20177) * Clean up path additions entry index handling * Bump network version --- src/openrct2-ui/windows/TopToolbar.cpp | 4 +- .../actions/FootpathAdditionPlaceAction.cpp | 104 ++++++++---------- .../actions/FootpathAdditionPlaceAction.h | 2 +- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 6 +- .../bindings/world/ScTileElement.cpp | 4 +- src/openrct2/world/Footpath.cpp | 7 ++ src/openrct2/world/TileElement.h | 1 + 8 files changed, 62 insertions(+), 68 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 7aaeadb02a..80a5dea1fd 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1355,7 +1355,7 @@ private: SceneryRemoveGhostToolPlacement(); // 6e265b - auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction(loc, entryIndex + 1); + auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction(loc, entryIndex); footpathAdditionPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); footpathAdditionPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) { if (result->Error != GameActions::Status::Ok) @@ -2308,7 +2308,7 @@ private: if (gridPos.IsNull()) return; - auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction({ gridPos, z }, selectedScenery + 1); + auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction({ gridPos, z }, selectedScenery); footpathAdditionPlaceAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) { if (result->Error != GameActions::Status::Ok) diff --git a/src/openrct2/actions/FootpathAdditionPlaceAction.cpp b/src/openrct2/actions/FootpathAdditionPlaceAction.cpp index 950a77fb0b..fc3f78000a 100644 --- a/src/openrct2/actions/FootpathAdditionPlaceAction.cpp +++ b/src/openrct2/actions/FootpathAdditionPlaceAction.cpp @@ -25,14 +25,14 @@ FootpathAdditionPlaceAction::FootpathAdditionPlaceAction(const CoordsXYZ& loc, ObjectEntryIndex pathItemType) : _loc(loc) - , _pathItemType(pathItemType) + , _entryIndex(pathItemType) { } void FootpathAdditionPlaceAction::AcceptParameters(GameActionParameterVisitor& visitor) { visitor.Visit(_loc); - visitor.Visit("object", _pathItemType); + visitor.Visit("object", _entryIndex); } uint16_t FootpathAdditionPlaceAction::GetActionFlags() const @@ -44,7 +44,7 @@ void FootpathAdditionPlaceAction::Serialise(DataSerialiser& stream) { GameAction::Serialise(stream); - stream << DS_TAG(_loc) << DS_TAG(_pathItemType); + stream << DS_TAG(_loc) << DS_TAG(_entryIndex); } GameActions::Result FootpathAdditionPlaceAction::Query() const @@ -88,46 +88,44 @@ GameActions::Result FootpathAdditionPlaceAction::Query() const } // No change - if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAddition() == _pathItemType && !(pathElement->IsBroken())) + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAdditionEntryIndex() == _entryIndex + && !(pathElement->IsBroken())) { return res; } - if (_pathItemType != 0) + auto* pathAdditionEntry = OpenRCT2::ObjectManager::GetObjectEntry(_entryIndex); + if (pathAdditionEntry == nullptr) { - auto* pathAdditionEntry = OpenRCT2::ObjectManager::GetObjectEntry(_pathItemType - 1); - if (pathAdditionEntry == nullptr) - { - return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); - } - uint16_t sceneryFlags = pathAdditionEntry->flags; - - if ((sceneryFlags & PATH_ADDITION_FLAG_DONT_ALLOW_ON_SLOPE) && pathElement->IsSloped()) - { - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_ON_SLOPED_FOOTPATH); - } - - if ((sceneryFlags & PATH_ADDITION_FLAG_DONT_ALLOW_ON_QUEUE) && pathElement->IsQueue()) - { - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CANNOT_PLACE_THESE_ON_QUEUE_LINE_AREA); - } - - if (!(sceneryFlags & (PATH_ADDITION_FLAG_JUMPING_FOUNTAIN_WATER | PATH_ADDITION_FLAG_JUMPING_FOUNTAIN_SNOW)) - && (pathElement->GetEdges()) == 0x0F) - { - return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); - } - - if ((sceneryFlags & PATH_ADDITION_FLAG_IS_QUEUE_SCREEN) && !pathElement->IsQueue()) - { - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_PLACE_THESE_ON_QUEUE_AREA); - } - - res.Cost = pathAdditionEntry->price; + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } + uint16_t sceneryFlags = pathAdditionEntry->flags; + + if ((sceneryFlags & PATH_ADDITION_FLAG_DONT_ALLOW_ON_SLOPE) && pathElement->IsSloped()) + { + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_ON_SLOPED_FOOTPATH); + } + + if ((sceneryFlags & PATH_ADDITION_FLAG_DONT_ALLOW_ON_QUEUE) && pathElement->IsQueue()) + { + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CANNOT_PLACE_THESE_ON_QUEUE_LINE_AREA); + } + + if (!(sceneryFlags & (PATH_ADDITION_FLAG_JUMPING_FOUNTAIN_WATER | PATH_ADDITION_FLAG_JUMPING_FOUNTAIN_SNOW)) + && (pathElement->GetEdges()) == 0x0F) + { + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); + } + + if ((sceneryFlags & PATH_ADDITION_FLAG_IS_QUEUE_SCREEN) && !pathElement->IsQueue()) + { + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_PLACE_THESE_ON_QUEUE_AREA); + } + + res.Cost = pathAdditionEntry->price; // Should place a ghost? if (GetFlags() & GAME_COMMAND_FLAG_GHOST) @@ -157,23 +155,20 @@ GameActions::Result FootpathAdditionPlaceAction::Execute() const } // No change - if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAddition() == _pathItemType && !(pathElement->IsBroken()) - && !pathElement->AdditionIsGhost()) + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && pathElement->GetAdditionEntryIndex() == _entryIndex + && !(pathElement->IsBroken()) && !pathElement->AdditionIsGhost()) { return res; } - if (_pathItemType != 0) + auto* pathAdditionEntry = OpenRCT2::ObjectManager::GetObjectEntry(_entryIndex); + if (pathAdditionEntry == nullptr) { - auto* pathAdditionEntry = OpenRCT2::ObjectManager::GetObjectEntry(_pathItemType - 1); - if (pathAdditionEntry == nullptr) - { - return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); - } - - res.Cost = pathAdditionEntry->price; + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } + res.Cost = pathAdditionEntry->price; + if (GetFlags() & GAME_COMMAND_FLAG_GHOST) { pathElement->SetAdditionIsGhost(true); @@ -181,23 +176,14 @@ GameActions::Result FootpathAdditionPlaceAction::Execute() const else { FootpathInterruptPeeps(_loc); - } - - if ((_pathItemType != 0 && !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) - || (_pathItemType == 0 && pathElement->AdditionIsGhost())) - { pathElement->SetAdditionIsGhost(false); } - pathElement->SetAddition(_pathItemType); + pathElement->SetAdditionEntryIndex(_entryIndex); pathElement->SetIsBroken(false); - if (_pathItemType != 0) + if (pathAdditionEntry->flags & PATH_ADDITION_FLAG_IS_BIN) { - auto* pathAdditionEntry = OpenRCT2::ObjectManager::GetObjectEntry(_pathItemType - 1); - if (pathAdditionEntry != nullptr && pathAdditionEntry->flags & PATH_ADDITION_FLAG_IS_BIN) - { - pathElement->SetAdditionStatus(255); - } + pathElement->SetAdditionStatus(255); } MapInvalidateTileFull(_loc); return res; diff --git a/src/openrct2/actions/FootpathAdditionPlaceAction.h b/src/openrct2/actions/FootpathAdditionPlaceAction.h index eb3f5dcde3..bb1631e3aa 100644 --- a/src/openrct2/actions/FootpathAdditionPlaceAction.h +++ b/src/openrct2/actions/FootpathAdditionPlaceAction.h @@ -15,7 +15,7 @@ class FootpathAdditionPlaceAction final : public GameActionBaseSetHasQueueBanner(src2->HasQueueBanner()); dst2->SetEdges(src2->GetEdges()); dst2->SetCorners(src2->GetCorners()); - dst2->SetAddition(src2->GetAddition()); + dst2->SetAddition(0); dst2->SetAdditionIsGhost(false); dst2->SetAdditionStatus(src2->GetAdditionStatus()); @@ -1631,7 +1631,7 @@ namespace RCT1 dst2->SetRailingsEntryIndex(railingsEntryIndex); // Additions - ObjectEntryIndex additionType = dst2->GetAddition(); + ObjectEntryIndex additionType = src2->GetAddition(); if (additionType != RCT1_PATH_ADDITION_NONE) { ObjectEntryIndex normalisedType = RCT1::NormalisePathAddition(additionType); @@ -1640,7 +1640,7 @@ namespace RCT1 { dst2->SetIsBroken(true); } - dst2->SetAddition(entryIndex + 1); + dst2->SetAdditionEntryIndex(entryIndex); } return 1; } diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index 44fea35ab7..1fd3c55e88 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -1791,7 +1791,7 @@ namespace OpenRCT2::Scripting auto* ctx = scriptEngine.GetContext(); auto* el = _element->AsPath(); if (el != nullptr && el->HasAddition()) - duk_push_int(ctx, el->GetAddition() - 1); + duk_push_int(ctx, el->GetAdditionEntryIndex()); else duk_push_null(ctx); return DukValue::take_from_stack(ctx); @@ -1807,7 +1807,7 @@ namespace OpenRCT2::Scripting auto addition = value.as_int(); if (addition >= 0 && addition <= 254) { - el->SetAddition(addition + 1); + el->SetAdditionEntryIndex(addition); } } else diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 6bf81c8649..431761635a 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1628,6 +1628,7 @@ uint8_t PathElement::GetAddition() const ObjectEntryIndex PathElement::GetAdditionEntryIndex() const { + // `Additions` is set to 0 when there is no addition, so the value 1 corresponds with path addition slot 0, etc. return GetAddition() - 1; } @@ -1643,6 +1644,12 @@ void PathElement::SetAddition(uint8_t newAddition) Additions = newAddition; } +void PathElement::SetAdditionEntryIndex(ObjectEntryIndex entryIndex) +{ + // `Additions` is set to 0 when there is no addition, so the value 1 corresponds with path addition slot 0, etc. + Additions = entryIndex + 1; +} + bool PathElement::AdditionIsGhost() const { return (Flags2 & FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST) != 0; diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index b9cb7308c3..95f60bcc09 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -311,6 +311,7 @@ public: ObjectEntryIndex GetAdditionEntryIndex() const; const PathAdditionEntry* GetAdditionEntry() const; void SetAddition(uint8_t newAddition); + void SetAdditionEntryIndex(ObjectEntryIndex entryIndex); bool AdditionIsGhost() const; void SetAdditionIsGhost(bool isGhost);