diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 241b955304..71ff4b6d5a 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -82,6 +82,9 @@ * \li GSIndustry::GetProductionLevel * \li GSIndustry::SetProductionLevel * \li GSStoryPage::IsValidStoryPageElementType + * \li GSStoryPage::IsValidStoryPageButtonColour + * \li GSStoryPage::IsValidStoryPageButtonFlags + * \li GSStoryPage::IsValidStoryPageButtonCursor * * API removals: * \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore. diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index b99c703aa1..d2f963e76a 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -224,10 +224,32 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) return ScriptObject::Command::Do(story_page_element_id); } +/* static */ bool ScriptStoryPage::IsValidStoryPageButtonColour(StoryPageButtonColour colour) +{ + return ::IsValidColours((::Colours)colour); +} + +/* static */ bool ScriptStoryPage::IsValidStoryPageButtonFlags(StoryPageButtonFlags flags) +{ + /* Don't allow float left and right together */ + if ((flags & SPBF_FLOAT_LEFT) && (flags & SPBF_FLOAT_RIGHT)) return false; + /* Don't allow undefined flags */ + if (flags & ~(SPBF_FLOAT_LEFT | SPBF_FLOAT_RIGHT)) return false; + return true; +} + +/* static */ bool ScriptStoryPage::IsValidStoryPageButtonCursor(StoryPageButtonCursor cursor) +{ + return ::IsValidStoryPageButtonCursor((::StoryPageButtonCursor)cursor); +} + /* static */ ScriptStoryPage::StoryPageButtonFormatting ScriptStoryPage::MakePushButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags) { + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonColour(colour)); + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonFlags(flags)); + StoryPageButtonData data; - data.SetColour((Colours)colour); + data.SetColour((::Colours)colour); data.SetFlags((::StoryPageButtonFlags)flags); if (!data.ValidateColour()) return UINT32_MAX; if (!data.ValidateFlags()) return UINT32_MAX; @@ -236,8 +258,12 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ ScriptStoryPage::StoryPageButtonFormatting ScriptStoryPage::MakeTileButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags, StoryPageButtonCursor cursor) { + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonColour(colour)); + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonFlags(flags)); + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonCursor(cursor)); + StoryPageButtonData data; - data.SetColour((Colours)colour); + data.SetColour((::Colours)colour); data.SetFlags((::StoryPageButtonFlags)flags); data.SetCursor((::StoryPageButtonCursor)cursor); if (!data.ValidateColour()) return UINT32_MAX; @@ -248,8 +274,13 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ ScriptStoryPage::StoryPageButtonFormatting ScriptStoryPage::MakeVehicleButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags, StoryPageButtonCursor cursor, ScriptVehicle::VehicleType vehtype) { + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonColour(colour)); + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonFlags(flags)); + EnforcePrecondition(UINT32_MAX, IsValidStoryPageButtonCursor(cursor)); + EnforcePrecondition(UINT32_MAX, vehtype == ScriptVehicle::VT_INVALID || vehtype == ScriptVehicle::VT_RAIL || vehtype == ScriptVehicle::VT_ROAD || vehtype == ScriptVehicle::VT_WATER || vehtype == ScriptVehicle::VT_AIR); + StoryPageButtonData data; - data.SetColour((Colours)colour); + data.SetColour((::Colours)colour); data.SetFlags((::StoryPageButtonFlags)flags); data.SetCursor((::StoryPageButtonCursor)cursor); data.SetVehicleType((::VehicleType)vehtype); @@ -259,4 +290,3 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) if (!data.ValidateVehicleType()) return UINT32_MAX; return data.referenced_id; } - diff --git a/src/script/api/script_story_page.hpp b/src/script/api/script_story_page.hpp index edebc0bf1c..4e16876664 100644 --- a/src/script/api/script_story_page.hpp +++ b/src/script/api/script_story_page.hpp @@ -146,7 +146,7 @@ public: * Colour codes usable for story page button elements. * Place a colour value in the lowest 8 bits of the \c reference parameter to the button. */ - enum StoryPageButtonColour { + enum StoryPageButtonColour : byte { SPBC_DARK_BLUE = ::COLOUR_DARK_BLUE, SPBC_PALE_GREEN = ::COLOUR_PALE_GREEN, SPBC_PINK = ::COLOUR_PINK, @@ -320,11 +320,34 @@ public: */ static bool RemoveElement(StoryPageElementID story_page_element_id); + /** + * Check whether this is a valid story page button colour. + * @param colour The StoryPageButtonColour to check. + * @return True if and only if this story page button colour is valid. + */ + static bool IsValidStoryPageButtonColour(StoryPageButtonColour colour); + + /** + * Check whether this is a valid story page button flag. + * @param colour The StoryPageButtonFlags to check. + * @return True if and only if this story page button flag is valid. + */ + static bool IsValidStoryPageButtonFlags(StoryPageButtonFlags flags); + + /** + * Check whether this is a valid story page button cursor. + * @param colour The StoryPageButtonCursor to check. + * @return True if and only if this story page button cursor is valid. + */ + static bool IsValidStoryPageButtonCursor(StoryPageButtonCursor cursor); + /** * Create a reference value for SPET_BUTTON_PUSH element parameters. * @param colour The colour for the face of the button. * @param flags The formatting and layout flags for the button. * @return A reference value usable with the #NewElement and #UpdateElement functions. + * @pre IsValidStoryPageButtonColour(colour). + * @pre IsValidStoryPageButtonFlags(flags). */ static StoryPageButtonFormatting MakePushButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags); @@ -334,6 +357,9 @@ public: * @param flags The formatting and layout flags for the button. * @param cursor The mouse cursor to use when the player clicks the button and the game is ready for the player to select a tile. * @return A reference value usable with the #NewElement and #UpdateElement functions. + * @pre IsValidStoryPageButtonColour(colour). + * @pre IsValidStoryPageButtonFlags(flags). + * @pre IsValidStoryPageButtonCursor(cursor). */ static StoryPageButtonFormatting MakeTileButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags, StoryPageButtonCursor cursor); @@ -344,6 +370,10 @@ public: * @param cursor The mouse cursor to use when the player clicks the button and the game is ready for the player to select a vehicle. * @param vehtype The type of vehicle that will be selectable, or \c VT_INVALID to allow all types. * @return A reference value usable with the #NewElement and #UpdateElement functions. + * @pre IsValidStoryPageButtonColour(colour). + * @pre IsValidStoryPageButtonFlags(flags). + * @pre IsValidStoryPageButtonCursor(cursor). + * @pre vehtype == ScriptVehicle::VT_INVALID || vehtype == ScriptVehicle::VT_RAIL || vehtype == ScriptVehicle::VT_ROAD || vehtype == ScriptVehicle::VT_WATER || vehtype == ScriptVehicle::VT_AIR. */ static StoryPageButtonFormatting MakeVehicleButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags, StoryPageButtonCursor cursor, ScriptVehicle::VehicleType vehtype); }; diff --git a/src/story.cpp b/src/story.cpp index ad732f9d37..0b7f0f920b 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -66,13 +66,16 @@ static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElement break; case SPET_BUTTON_PUSH: if (!button_data.ValidateColour()) return false; + if (!button_data.ValidateFlags()) return false; return true; case SPET_BUTTON_TILE: if (!button_data.ValidateColour()) return false; + if (!button_data.ValidateFlags()) return false; if (!button_data.ValidateCursor()) return false; return true; case SPET_BUTTON_VEHICLE: if (!button_data.ValidateColour()) return false; + if (!button_data.ValidateFlags()) return false; if (!button_data.ValidateCursor()) return false; if (!button_data.ValidateVehicleType()) return false; return true;