2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file script_story_page.cpp Implementation of ScriptStoryPage. */
10 #include "../../stdafx.h"
11 #include "script_story_page.hpp"
12 #include "script_error.hpp"
13 #include "script_industry.hpp"
14 #include "script_map.hpp"
15 #include "script_town.hpp"
16 #include "script_goal.hpp"
17 #include "../script_instance.hpp"
18 #include "../../story_base.h"
19 #include "../../goal_base.h"
20 #include "../../string_func.h"
21 #include "../../tile_map.h"
22 #include "../../story_cmd.h"
24 #include "../../safeguards.h"
26 static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type
)
28 return type
== SPET_TEXT
|| type
== SPET_LOCATION
|| type
== SPET_BUTTON_PUSH
|| type
== SPET_BUTTON_TILE
|| type
== SPET_BUTTON_VEHICLE
;
31 /* static */ bool ScriptStoryPage::IsValidStoryPage(StoryPageID story_page_id
)
33 return ::StoryPage::IsValidID(story_page_id
);
36 /* static */ bool ScriptStoryPage::IsValidStoryPageElement(StoryPageElementID story_page_element_id
)
38 return ::StoryPageElement::IsValidID(story_page_element_id
);
41 /* static */ bool ScriptStoryPage::IsValidStoryPageElementType(StoryPageElementType type
)
43 return type
== SPET_TEXT
|| type
== SPET_LOCATION
|| type
== SPET_GOAL
|| type
== SPET_BUTTON_PUSH
|| type
== SPET_BUTTON_TILE
|| type
== SPET_BUTTON_VEHICLE
;
46 /* static */ ScriptStoryPage::StoryPageID
ScriptStoryPage::New(ScriptCompany::CompanyID company
, Text
*title
)
48 CCountedPtr
<Text
> counter(title
);
50 EnforceDeityMode(STORY_PAGE_INVALID
);
51 EnforcePrecondition(STORY_PAGE_INVALID
, company
== ScriptCompany::COMPANY_INVALID
|| ScriptCompany::ResolveCompanyID(company
) != ScriptCompany::COMPANY_INVALID
);
54 if (company
== ScriptCompany::COMPANY_INVALID
) c
= INVALID_COMPANY
;
56 if (!ScriptObject::Command
<CMD_CREATE_STORY_PAGE
>::Do(&ScriptInstance::DoCommandReturnStoryPageID
,
57 (::CompanyID
)c
, title
!= nullptr ? title
->GetEncodedText() : std::string
{})) return STORY_PAGE_INVALID
;
59 /* In case of test-mode, we return StoryPageID 0 */
60 return (ScriptStoryPage::StoryPageID
)0;
63 /* static */ ScriptStoryPage::StoryPageElementID
ScriptStoryPage::NewElement(StoryPageID story_page_id
, StoryPageElementType type
, SQInteger reference
, Text
*text
)
65 CCountedPtr
<Text
> counter(text
);
67 ::StoryPageElementType btype
= static_cast<::StoryPageElementType
>(type
);
69 EnforceDeityMode(STORY_PAGE_ELEMENT_INVALID
);
70 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, IsValidStoryPage(story_page_id
));
71 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, IsValidStoryPageElementType(type
));
72 std::string encoded_text
;
73 if (StoryPageElementTypeRequiresText(btype
)) {
74 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, text
!= nullptr);
75 encoded_text
= text
->GetEncodedText();
76 EnforcePreconditionEncodedText(STORY_PAGE_ELEMENT_INVALID
, encoded_text
);
78 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, type
!= SPET_LOCATION
|| ::IsValidTile((::TileIndex
)reference
));
79 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, type
!= SPET_GOAL
|| ScriptGoal::IsValidGoal((ScriptGoal::GoalID
)reference
));
80 EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID
, type
!= SPET_GOAL
|| !(StoryPage::Get(story_page_id
)->company
== INVALID_COMPANY
&& Goal::Get(reference
)->company
!= INVALID_COMPANY
));
83 TileIndex reftile
= 0;
89 case SPET_BUTTON_PUSH
:
90 case SPET_BUTTON_TILE
:
91 case SPET_BUTTON_VEHICLE
:
100 if (!ScriptObject::Command
<CMD_CREATE_STORY_PAGE_ELEMENT
>::Do(&ScriptInstance::DoCommandReturnStoryPageElementID
,
102 (::StoryPageID
)story_page_id
, (::StoryPageElementType
)type
,
104 encoded_text
)) return STORY_PAGE_ELEMENT_INVALID
;
106 /* In case of test-mode, we return StoryPageElementID 0 */
107 return (ScriptStoryPage::StoryPageElementID
)0;
110 /* static */ bool ScriptStoryPage::UpdateElement(StoryPageElementID story_page_element_id
, SQInteger reference
, Text
*text
)
112 CCountedPtr
<Text
> counter(text
);
114 EnforceDeityMode(false);
115 EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id
));
117 StoryPageElement
*pe
= StoryPageElement::Get(story_page_element_id
);
118 StoryPage
*p
= StoryPage::Get(pe
->page
);
119 ::StoryPageElementType type
= pe
->type
;
121 std::string encoded_text
;
122 if (StoryPageElementTypeRequiresText(type
)) {
123 EnforcePrecondition(false, text
!= nullptr);
124 encoded_text
= text
->GetEncodedText();
125 EnforcePreconditionEncodedText(false, encoded_text
);
127 EnforcePrecondition(false, type
!= ::SPET_LOCATION
|| ::IsValidTile((::TileIndex
)reference
));
128 EnforcePrecondition(false, type
!= ::SPET_GOAL
|| ScriptGoal::IsValidGoal((ScriptGoal::GoalID
)reference
));
129 EnforcePrecondition(false, type
!= ::SPET_GOAL
|| !(p
->company
== INVALID_COMPANY
&& Goal::Get(reference
)->company
!= INVALID_COMPANY
));
132 TileIndex reftile
= 0;
134 case ::SPET_LOCATION
:
138 case ::SPET_BUTTON_PUSH
:
139 case ::SPET_BUTTON_TILE
:
140 case ::SPET_BUTTON_VEHICLE
:
149 return ScriptObject::Command
<CMD_UPDATE_STORY_PAGE_ELEMENT
>::Do(reftile
, story_page_element_id
, refid
, encoded_text
);
152 /* static */ SQInteger
ScriptStoryPage::GetPageSortValue(StoryPageID story_page_id
)
154 EnforcePrecondition(false, IsValidStoryPage(story_page_id
));
156 return StoryPage::Get(story_page_id
)->sort_value
;
159 /* static */ SQInteger
ScriptStoryPage::GetPageElementSortValue(StoryPageElementID story_page_element_id
)
161 EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id
));
163 return StoryPageElement::Get(story_page_element_id
)->sort_value
;
166 /* static */ bool ScriptStoryPage::SetTitle(StoryPageID story_page_id
, Text
*title
)
168 CCountedPtr
<Text
> counter(title
);
170 EnforcePrecondition(false, IsValidStoryPage(story_page_id
));
171 EnforceDeityMode(false);
173 return ScriptObject::Command
<CMD_SET_STORY_PAGE_TITLE
>::Do(story_page_id
, title
!= nullptr ? title
->GetEncodedText() : std::string
{});
176 /* static */ ScriptCompany::CompanyID
ScriptStoryPage::GetCompany(StoryPageID story_page_id
)
178 EnforcePrecondition(ScriptCompany::COMPANY_INVALID
, IsValidStoryPage(story_page_id
));
180 CompanyID c
= StoryPage::Get(story_page_id
)->company
;
181 ScriptCompany::CompanyID company
= c
== INVALID_COMPANY
? ScriptCompany::COMPANY_INVALID
: (ScriptCompany::CompanyID
)c
;
186 /* static */ ScriptDate::Date
ScriptStoryPage::GetDate(StoryPageID story_page_id
)
188 EnforcePrecondition(ScriptDate::DATE_INVALID
, IsValidStoryPage(story_page_id
));
189 EnforceDeityMode(ScriptDate::DATE_INVALID
);
191 return (ScriptDate::Date
)StoryPage::Get(story_page_id
)->date
.base();
194 /* static */ bool ScriptStoryPage::SetDate(StoryPageID story_page_id
, ScriptDate::Date date
)
196 EnforcePrecondition(false, IsValidStoryPage(story_page_id
));
197 EnforceDeityMode(false);
199 return ScriptObject::Command
<CMD_SET_STORY_PAGE_DATE
>::Do(story_page_id
, date
);
203 /* static */ bool ScriptStoryPage::Show(StoryPageID story_page_id
)
205 EnforcePrecondition(false, IsValidStoryPage(story_page_id
));
206 EnforceDeityMode(false);
208 return ScriptObject::Command
<CMD_SHOW_STORY_PAGE
>::Do(story_page_id
);
211 /* static */ bool ScriptStoryPage::Remove(StoryPageID story_page_id
)
213 EnforceDeityMode(false);
214 EnforcePrecondition(false, IsValidStoryPage(story_page_id
));
216 return ScriptObject::Command
<CMD_REMOVE_STORY_PAGE
>::Do(story_page_id
);
219 /* static */ bool ScriptStoryPage::RemoveElement(StoryPageElementID story_page_element_id
)
221 EnforceDeityMode(false);
222 EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id
));
224 return ScriptObject::Command
<CMD_REMOVE_STORY_PAGE_ELEMENT
>::Do(story_page_element_id
);
227 /* static */ ScriptStoryPage::StoryPageButtonFormatting
ScriptStoryPage::MakePushButtonReference(StoryPageButtonColour colour
, StoryPageButtonFlags flags
)
229 StoryPageButtonData data
;
230 data
.SetColour((Colours
)colour
);
231 data
.SetFlags((::StoryPageButtonFlags
)flags
);
232 if (!data
.ValidateColour()) return UINT32_MAX
;
233 if (!data
.ValidateFlags()) return UINT32_MAX
;
234 return data
.referenced_id
;
237 /* static */ ScriptStoryPage::StoryPageButtonFormatting
ScriptStoryPage::MakeTileButtonReference(StoryPageButtonColour colour
, StoryPageButtonFlags flags
, StoryPageButtonCursor cursor
)
239 StoryPageButtonData data
;
240 data
.SetColour((Colours
)colour
);
241 data
.SetFlags((::StoryPageButtonFlags
)flags
);
242 data
.SetCursor((::StoryPageButtonCursor
)cursor
);
243 if (!data
.ValidateColour()) return UINT32_MAX
;
244 if (!data
.ValidateFlags()) return UINT32_MAX
;
245 if (!data
.ValidateCursor()) return UINT32_MAX
;
246 return data
.referenced_id
;
249 /* static */ ScriptStoryPage::StoryPageButtonFormatting
ScriptStoryPage::MakeVehicleButtonReference(StoryPageButtonColour colour
, StoryPageButtonFlags flags
, StoryPageButtonCursor cursor
, ScriptVehicle::VehicleType vehtype
)
251 StoryPageButtonData data
;
252 data
.SetColour((Colours
)colour
);
253 data
.SetFlags((::StoryPageButtonFlags
)flags
);
254 data
.SetCursor((::StoryPageButtonCursor
)cursor
);
255 data
.SetVehicleType((::VehicleType
)vehtype
);
256 if (!data
.ValidateColour()) return UINT32_MAX
;
257 if (!data
.ValidateFlags()) return UINT32_MAX
;
258 if (!data
.ValidateCursor()) return UINT32_MAX
;
259 if (!data
.ValidateVehicleType()) return UINT32_MAX
;
260 return data
.referenced_id
;