diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 91b0656fcb..8d5c0eb6ce 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.4.21 (in development) ------------------------------------------------------------------------ - Fix: [#4225] Ride Construction window offers non-existent banked sloped to level curve (original bug). +- Fix: [#10379] Banners outside the park can be renamed and modified (original bug). - Fix: [#23897] Reverse Freefall Coaster slope up to vertical track piece does not draw a vertical tunnel. 0.4.20 (2025-02-25) diff --git a/src/openrct2/actions/BannerSetNameAction.cpp b/src/openrct2/actions/BannerSetNameAction.cpp index 1ab6bb6889..1b069ee941 100644 --- a/src/openrct2/actions/BannerSetNameAction.cpp +++ b/src/openrct2/actions/BannerSetNameAction.cpp @@ -53,6 +53,28 @@ GameActions::Result BannerSetNameAction::Query() const return GameActions::Result( GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_ERR_BANNER_ELEMENT_NOT_FOUND); } + + TileElement* tileElement = BannerGetTileElement(_bannerIndex); + + if (tileElement == nullptr) + { + LOG_ERROR("Banner tile element not found for bannerIndex %d", _bannerIndex); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + } + + BannerElement* bannerElement = tileElement->AsBanner(); + CoordsXYZD loc = { banner->position.ToCoordsXY(), bannerElement->GetBaseZ(), bannerElement->GetPosition() }; + + if (!LocationValid(loc)) + { + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_OFF_EDGE_OF_MAP); + } + if (!MapCanBuildAt({ loc.x, loc.y, loc.z - 16 })) + { + return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_RENAME_BANNER, STR_LAND_NOT_OWNED_BY_PARK); + } + return GameActions::Result(); } diff --git a/src/openrct2/actions/BannerSetStyleAction.cpp b/src/openrct2/actions/BannerSetStyleAction.cpp index 7a8c96fa0a..7dd041fda1 100644 --- a/src/openrct2/actions/BannerSetStyleAction.cpp +++ b/src/openrct2/actions/BannerSetStyleAction.cpp @@ -11,6 +11,7 @@ #include "../Context.h" #include "../Diagnostic.h" +#include "../localisation/StringIdType.h" #include "../management/Finance.h" #include "../windows/Intent.h" #include "../world/Banner.h" @@ -47,14 +48,19 @@ void BannerSetStyleAction::Serialise(DataSerialiser& stream) GameActions::Result BannerSetStyleAction::Query() const { + StringId errorTitle = STR_CANT_REPAINT_THIS; + if (_type == BannerSetStyleType::NoEntry) + { + errorTitle = STR_CANT_RENAME_BANNER; + } + auto res = GameActions::Result(); auto banner = GetBanner(_bannerIndex); if (banner == nullptr) { LOG_ERROR("Banner not found for bannerIndex %d", _bannerIndex); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + return GameActions::Result(GameActions::Status::InvalidParameters, errorTitle, STR_ERR_BANNER_ELEMENT_NOT_FOUND); } res.Expenditure = ExpenditureType::Landscaping; @@ -66,8 +72,19 @@ GameActions::Result BannerSetStyleAction::Query() const if (tileElement == nullptr) { LOG_ERROR("Banner tile element not found for bannerIndex %d", _bannerIndex); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + return GameActions::Result(GameActions::Status::InvalidParameters, errorTitle, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + } + + BannerElement* bannerElement = tileElement->AsBanner(); + CoordsXYZ loc = { banner->position.ToCoordsXY(), bannerElement->GetBaseZ() }; + + if (!LocationValid(loc)) + { + return GameActions::Result(GameActions::Status::InvalidParameters, errorTitle, STR_OFF_EDGE_OF_MAP); + } + if (!MapCanBuildAt({ loc.x, loc.y, loc.z - 16 })) + { + return GameActions::Result(GameActions::Status::NotOwned, errorTitle, STR_LAND_NOT_OWNED_BY_PARK); } switch (_type) @@ -93,7 +110,7 @@ GameActions::Result BannerSetStyleAction::Query() const if (tileElement->AsBanner() == nullptr) { LOG_ERROR("Tile element was not a banner."); - return GameActions::Result(GameActions::Status::Unknown, STR_CANT_REPAINT_THIS, kStringIdNone); + return GameActions::Result(GameActions::Status::Unknown, STR_CANT_RENAME_BANNER, kStringIdNone); } break; default: diff --git a/src/openrct2/actions/SignSetNameAction.cpp b/src/openrct2/actions/SignSetNameAction.cpp index 64a4b150ef..11d1d2ae34 100644 --- a/src/openrct2/actions/SignSetNameAction.cpp +++ b/src/openrct2/actions/SignSetNameAction.cpp @@ -51,6 +51,27 @@ GameActions::Result SignSetNameAction::Query() const LOG_ERROR("Banner not found for bannerIndex %d", _bannerIndex); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_RENAME_SIGN, kStringIdNone); } + + TileElement* tileElement = BannerGetTileElement(_bannerIndex); + + if (tileElement == nullptr) + { + LOG_ERROR("Banner tile element not found for bannerIndex %d", _bannerIndex); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + } + + CoordsXYZ loc = { banner->position.ToCoordsXY(), tileElement->GetBaseZ() }; + + if (!LocationValid(loc)) + { + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_OFF_EDGE_OF_MAP); + } + if (!MapCanBuildAt({ loc.x, loc.y, loc.z - 16 })) + { + return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_RENAME_BANNER, STR_LAND_NOT_OWNED_BY_PARK); + } + return GameActions::Result(); } diff --git a/src/openrct2/actions/SignSetStyleAction.cpp b/src/openrct2/actions/SignSetStyleAction.cpp index 121d6ceddc..a97d50db5b 100644 --- a/src/openrct2/actions/SignSetStyleAction.cpp +++ b/src/openrct2/actions/SignSetStyleAction.cpp @@ -58,6 +58,8 @@ GameActions::Result SignSetStyleAction::Query() const return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, kStringIdNone); } + CoordsXYZ loc; + if (_isLarge) { TileElement* tileElement = BannerGetTileElement(_bannerIndex); @@ -72,6 +74,7 @@ GameActions::Result SignSetStyleAction::Query() const "Tile element has type %u, expected %d (LargeScenery)", tileElement->GetType(), TileElementType::LargeScenery); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, kStringIdNone); } + loc = { banner->position.ToCoordsXY(), tileElement->GetBaseZ() }; } else { @@ -82,6 +85,16 @@ GameActions::Result SignSetStyleAction::Query() const LOG_ERROR("Wall element not found for bannerIndex", _bannerIndex); return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, kStringIdNone); } + loc = { banner->position.ToCoordsXY(), wallElement->GetBaseZ() }; + } + + if (!LocationValid(loc)) + { + return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_RENAME_BANNER, STR_OFF_EDGE_OF_MAP); + } + if (!MapCanBuildAt({ loc.x, loc.y, loc.z - 16 })) + { + return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_RENAME_BANNER, STR_LAND_NOT_OWNED_BY_PARK); } return GameActions::Result();