From 09897c5fd68668c148859314f5e6a1f64dd4634b Mon Sep 17 00:00:00 2001 From: zuu Date: Sun, 21 Jul 2013 13:18:45 +0000 Subject: [PATCH] (svn r25620) -Fix (r25342): Save/load of story books were broken --- src/saveload/afterload.cpp | 1 + src/saveload/saveload.cpp | 3 ++- src/saveload/saveload_internal.h | 1 + src/saveload/story_sl.cpp | 24 ++++++++++++++++++++---- src/story.cpp | 22 ++++++++++++---------- src/story_base.h | 12 +++++++++--- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index d969a40fc2..a715c9162f 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2818,6 +2818,7 @@ bool AfterLoadGame() AfterLoadRoadStops(); AfterLoadLabelMaps(); AfterLoadCompanyStats(); + AfterLoadStoryBook(); GamelogPrintDebug(1); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 4f59486a9e..8f58ea3816 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -250,8 +250,9 @@ * 182 25296 * 183 25363 * 184 25508 + * 185 25620 */ -extern const uint16 SAVEGAME_VERSION = 184; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 185; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index 476a324f8c..74e5b9936d 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -31,6 +31,7 @@ void FixupTrainLengths(); void AfterLoadStations(); void AfterLoadRoadStops(); void AfterLoadLabelMaps(); +void AfterLoadStoryBook(); void AfterLoadLinkGraphs(); void AfterLoadCompanyStats(); void UpdateHousesAndTowns(); diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index 0ee5fe9471..310f96fcb8 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -14,10 +14,24 @@ #include "saveload.h" +/** Called after load to trash broken pages. */ +void AfterLoadStoryBook() +{ + if (IsSavegameVersionBefore(185)) { + /* Trash all story pages and page elements because + * they were saved with wrong data types. + */ + _story_page_element_pool.CleanPool(); + _story_page_pool.CleanPool(); + } +} + static const SaveLoad _story_page_elements_desc[] = { - SLE_VAR(StoryPageElement, sort_value, SLE_UINT16), + SLE_CONDVAR(StoryPageElement, sort_value, SLE_FILE_U16 | SLE_VAR_U32, 0, 184), + SLE_CONDVAR(StoryPageElement, sort_value, SLE_UINT32, 185, SL_MAX_VERSION), SLE_VAR(StoryPageElement, page, SLE_UINT16), - SLE_VAR(StoryPageElement, type, SLE_UINT16), + SLE_CONDVAR(StoryPageElement, type, SLE_FILE_U16 | SLE_VAR_U8, 0, 184), + SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, 185, SL_MAX_VERSION), SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32), SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_END() @@ -50,9 +64,11 @@ static void Load_STORY_PAGE_ELEMENT() } static const SaveLoad _story_pages_desc[] = { - SLE_VAR(StoryPage, sort_value, SLE_UINT16), + SLE_CONDVAR(StoryPage, sort_value, SLE_FILE_U16 | SLE_VAR_U32, 0, 184), + SLE_CONDVAR(StoryPage, sort_value, SLE_UINT32, 185, SL_MAX_VERSION), SLE_VAR(StoryPage, date, SLE_UINT32), - SLE_VAR(StoryPage, company, SLE_UINT16), + SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, 0, 184), + SLE_CONDVAR(StoryPage, company, SLE_UINT8, 185, SL_MAX_VERSION), SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_END() }; diff --git a/src/story.cpp b/src/story.cpp index 915f44da58..e4b1aa59e7 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -12,6 +12,7 @@ #include "stdafx.h" #include "story_base.h" #include "core/pool_func.hpp" +#include "cmd_helper.h" #include "command_func.h" #include "company_base.h" #include "company_func.h" @@ -44,7 +45,7 @@ INSTANTIATE_POOL_METHODS(StoryPage) * @param text The text parameter of the DoCommand proc * @return true, if and only if the given parameters are valid for the given page elment type and page id. */ -static bool VerifyElementContentParameters(uint32 page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text) +static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text) { switch (type) { case SPET_TEXT: @@ -140,7 +141,7 @@ CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - The page which the element belongs to. - * (bit 16 - 31) - Page element type + * (bit 16 - 23) - Page element type * @param p2 Id of referenced object * @param text Text content in case it is a text or location page element * @return the cost of this operation or an error @@ -150,7 +151,7 @@ CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR; StoryPageID page_id = (CompanyID)GB(p1, 0, 16); - StoryPageElementType type = (StoryPageElementType) GB(p1, 16, 16); + StoryPageElementType type = Extract(p1); /* Allow at most 128 elements per page. */ uint16 element_count = 0; @@ -221,7 +222,7 @@ CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 * Update title of a story page. * @param tile unused. * @param flags type of operation - * @param p1 StoryPageID to update. + * @param p1 = (bit 0 - 15) - StoryPageID to update. * @param p2 unused * @param text title text of the story page. * @return the cost of this operation or an error @@ -229,7 +230,7 @@ CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)p1; + StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -252,7 +253,7 @@ CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, * view the story page. * @param tile unused. * @param flags type of operation - * @param p1 StoryPageID to show. + * @param p1 = (bit 0 - 15) - StoryPageID to show. * @param p2 unused * @param text unused * @return the cost of this operation or an error @@ -260,11 +261,12 @@ CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (!StoryPage::IsValidID(p1)) return CMD_ERROR; + StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); + if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { - StoryPage *g = StoryPage::Get(p1); - if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, p1); + StoryPage *g = StoryPage::Get(page_id); + if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id); } return CommandCost(); @@ -273,7 +275,7 @@ CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * Remove a story page and associated story page elements. * @param tile unused. * @param flags type of operation - * @param p1 StoryPageID to remove. + * @param p1 = (bit 0 - 15) - StoryPageID to remove. * @param p2 unused. * @param text unused. * @return the cost of this operation or an error diff --git a/src/story_base.h b/src/story_base.h index edb89db7a2..d295671f14 100644 --- a/src/story_base.h +++ b/src/story_base.h @@ -28,11 +28,17 @@ extern uint32 _story_page_next_sort_value; * Each story page element is one of these types. */ enum StoryPageElementType { - SPET_TEXT, ///< A text element. + SPET_TEXT = 0, ///< A text element. SPET_LOCATION, ///< An element that references a tile along with a one-line text. SPET_GOAL, ///< An element that references a goal. + SPET_END, + INVALID_SPET = 0xFF, }; +/** Define basic enum properties */ +template <> struct EnumPropsT : MakeEnumPropsT {}; +typedef TinyEnumT StoryPageElementTypeByte; ///< typedefing-enumification of Direction + /** * Struct about story page elements. * Each StoryPage is composed of one or more page elements that provide @@ -40,8 +46,8 @@ enum StoryPageElementType { **/ struct StoryPageElement : StoryPageElementPool::PoolItem<&_story_page_element_pool> { uint32 sort_value; ///< A number that increases for every created story page element. Used for sorting. The id of a story page element is the pool index. - uint16 page; ///< Id of the page which the page element belongs to - StoryPageElementType type; ///< Type of page element + StoryPageID page; ///< Id of the page which the page element belongs to + StoryPageElementTypeByte type; ///< Type of page element uint32 referenced_id; ///< Id of referenced object (location, goal etc.) char *text; ///< Static content text of page element