OpenTTD

story.cpp
Go to the documentation of this file.
1 /* $Id: story.cpp 27560 2016-05-11 20:48:46Z matthijs $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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 */
9
12 #include "stdafx.h"
13 #include "story_base.h"
14 #include "core/pool_func.hpp"
15 #include "cmd_helper.h"
16 #include "command_func.h"
17 #include "company_base.h"
18 #include "company_func.h"
19 #include "string_func.h"
20 #include "date_func.h"
21 #include "tile_map.h"
22 #include "goal_type.h"
23 #include "goal_base.h"
24 #include "window_func.h"
25 #include "gui.h"
26
27 #include "safeguards.h"
28
29
30 StoryPageElementID _new_story_page_element_id;
31 StoryPageID _new_story_page_id;
32 uint32 _story_page_element_next_sort_value;
33 uint32 _story_page_next_sort_value;
34
35 StoryPageElementPool _story_page_element_pool("StoryPageElement");
36 StoryPagePool _story_page_pool("StoryPage");
37 INSTANTIATE_POOL_METHODS(StoryPageElement)
38 INSTANTIATE_POOL_METHODS(StoryPage)
39
40
50 static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text)
51 {
52 switch (type) {
53 case SPET_TEXT:
54 if (StrEmpty(text)) return false;
55 break;
56 case SPET_LOCATION:
57 if (StrEmpty(text)) return false;
58 if (!IsValidTile(tile)) return false;
59 break;
60 case SPET_GOAL:
61 if (!Goal::IsValidID((GoalID)reference)) return false;
62 /* Reject company specific goals on global pages */
63 if (StoryPage::Get(page_id)->company == INVALID_COMPANY && Goal::Get((GoalID)reference)->company != INVALID_COMPANY) return false;
64 break;
65 default:
66 return false;
67 }
68
69 return true;
70 }
71
80 static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32 reference, const char *text)
81 {
82 switch (pe.type) {
83 case SPET_TEXT:
84 pe.text = stredup(text);
85 break;
86 case SPET_LOCATION:
87 pe.text = stredup(text);
88 pe.referenced_id = tile;
89 break;
90 case SPET_GOAL:
91 pe.referenced_id = (GoalID)reference;
92 break;
93 default: NOT_REACHED();
94 }
95 }
96
107 CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
108 {
109 if (!StoryPage::CanAllocateItem()) return CMD_ERROR;
110
111 CompanyID company = (CompanyID)GB(p1, 0, 8);
112
113 if (_current_company != OWNER_DEITY) return CMD_ERROR;
114 if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
115
116 if (flags & DC_EXEC) {
117 if (_story_page_pool.items == 0) {
118 /* Initialize the next sort value variable. */
119 _story_page_next_sort_value = 0;
120 }
121
122 StoryPage *s = new StoryPage();
123 s->sort_value = _story_page_next_sort_value;
124 s->date = _date;
125 s->company = company;
126 if (StrEmpty(text)) {
127 s->title = NULL;
128 } else {
129 s->title = stredup(text);
130 }
131
132 InvalidateWindowClassesData(WC_STORY_BOOK, -1);
133 if (StoryPage::GetNumItems() == 1) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
134
135 _new_story_page_id = s->index;
136 _story_page_next_sort_value++;
137 }
138
139 return CommandCost();
140 }
141
153 CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
154 {
155 if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR;
156
157 StoryPageID page_id = (CompanyID)GB(p1, 0, 16);
158 StoryPageElementType type = Extract<StoryPageElementType, 16, 8>(p1);
159
160 /* Allow at most 128 elements per page. */
161 uint16 element_count = 0;
162 StoryPageElement *iter;
163 FOR_ALL_STORY_PAGE_ELEMENTS(iter) {
164 if (iter->page == page_id) element_count++;
165 }
166 if (element_count >= 128) return CMD_ERROR;
167
168 if (_current_company != OWNER_DEITY) return CMD_ERROR;
169 if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
170 if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
171
172 if (flags & DC_EXEC) {
173 if (_story_page_element_pool.items == 0) {
174 /* Initialize the next sort value variable. */
175 _story_page_element_next_sort_value = 0;
176 }
177
178 StoryPageElement *pe = new StoryPageElement();
179 pe->sort_value = _story_page_element_next_sort_value;
180 pe->type = type;
181 pe->page = page_id;
182 UpdateElement(*pe, tile, p2, text);
183
184 InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
185
186 _new_story_page_element_id = pe->index;
187 _story_page_element_next_sort_value++;
188 }
189
190 return CommandCost();
191 }
192
204 CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
205 {
206 StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16);
207
208 if (_current_company != OWNER_DEITY) return CMD_ERROR;
209 if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
210
211 StoryPageElement *pe = StoryPageElement::Get(page_element_id);
212 StoryPageID page_id = pe->page;
213 StoryPageElementType type = pe->type;
214
215 if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
216
217 if (flags & DC_EXEC) {
218 UpdateElement(*pe, tile, p2, text);
219 InvalidateWindowClassesData(WC_STORY_BOOK, pe->page);
220 }
221
222 return CommandCost();
223 }
224
234 CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
235 {
236 if (_current_company != OWNER_DEITY) return CMD_ERROR;
237 StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
238 if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
239
240 if (flags & DC_EXEC) {
241 StoryPage *p = StoryPage::Get(page_id);
242 free(p->title);
243 if (StrEmpty(text)) {
244 p->title = NULL;
245 } else {
246 p->title = stredup(text);
247 }
248
249 InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
250 }
251
252 return CommandCost();
253 }
254
264 CommandCost CmdSetStoryPageDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
265 {
266 if (_current_company != OWNER_DEITY) return CMD_ERROR;
267 StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
268 if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
269 Date date = (Date)p2;
270
271 if (flags & DC_EXEC) {
272 StoryPage *p = StoryPage::Get(page_id);
273 p->date = date;
274
275 InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
276 }
277
278 return CommandCost();
279 }
280
291 CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
292 {
293 if (_current_company != OWNER_DEITY) return CMD_ERROR;
294 StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
295 if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
296
297 if (flags & DC_EXEC) {
298 StoryPage *g = StoryPage::Get(page_id);
299 if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id);
300 }
301
302 return CommandCost();
303 }
313 CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
314 {
315 if (_current_company != OWNER_DEITY) return CMD_ERROR;
316 StoryPageID page_id = (StoryPageID)p1;
317 if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
318
319 if (flags & DC_EXEC) {
320 StoryPage *p = StoryPage::Get(page_id);
321
322 StoryPageElement *pe;
323 FOR_ALL_STORY_PAGE_ELEMENTS(pe) {
324 if (pe->page == p->index) {
325 delete pe;
326 }
327 }
328
329 delete p;
330
331 InvalidateWindowClassesData(WC_STORY_BOOK, -1);
332 if (StoryPage::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
333 }
334
335 return CommandCost();
336 }
337
347 CommandCost CmdRemoveStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
348 {
349 if (_current_company != OWNER_DEITY) return CMD_ERROR;
350 StoryPageElementID page_element_id = (StoryPageElementID)p1;
351 if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
352
353 if (flags & DC_EXEC) {
354 StoryPageElement *pe = StoryPageElement::Get(page_element_id);
355 StoryPageID page_id = pe->page;
356
357 delete pe;
358
359 InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
360 }
361
362 return CommandCost();
363 }
364
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
StoryPageElementType
StoryPageElementType
Definition: story_base.h:30
StoryPageElement::page
StoryPageID page
Id of the page which the page element belongs to.
Definition: story_base.h:49
Pool::PoolItem<&_story_page_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
date_func.h
Functions related to dates.
GoalID
uint16 GoalID
ID of a goal.
Definition: goal_type.h:34
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:25
StoryPageElement::sort_value
uint32 sort_value
A number that increases for every created story page element. Used for sorting. The id of a story pag...
Definition: story_base.h:48
StoryPage::date
Date date
Date when the page was created.
Definition: story_base.h:72
CmdUpdateStoryPageElement
CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update a new story page element.
Definition: story.cpp:204
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
StoryPage::title
char * title
Title of story page.
Definition: story_base.h:75
cmd_helper.h
Helper functions to extract data from command parameters.
CommandCost
Common return value for all commands.
Definition: command_type.h:25
_local_company
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:29
StoryPageElement
Struct about story page elements.
Definition: story_base.h:47
IsValidTile
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:154
StoryPageElement::referenced_id
uint32 referenced_id
Id of referenced object (location, goal etc.)
Definition: story_base.h:52
InvalidateWindowClassesData
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition: window.cpp:3238
CmdRemoveStoryPage
CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove a story page and associated story page elements.
Definition: story.cpp:313
StoryPage
Struct about stories, current and completed.
Definition: story_base.h:70
string_func.h
Functions related to low-level strings.
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size...
CmdRemoveStoryPageElement
CommandCost CmdRemoveStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove a story page element.
Definition: story.cpp:347
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:340
StoryPageElementID
uint16 StoryPageElementID
ID of a story page element.
Definition: story_type.h:17
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
safeguards.h
A number of safeguards to prevent using unsafe methods.
VerifyElementContentParameters
static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text)
This helper for Create/Update PageElement Cmd procedure verifies if the page element parameters are c...
Definition: story.cpp:50
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:126
Pool::items
size_t items
Number of used indexes (non-NULL)
Definition: pool_type.hpp:94
CmdSetStoryPageTitle
CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update title of a story page.
Definition: story.cpp:234
StoryPage::sort_value
uint32 sort_value
A number that increases for every created story page. Used for sorting. The id of a story page is the...
Definition: story_base.h:71
StoryPage::company
CompanyByte company
StoryPage is for a specific company; INVALID_COMPANY if it is global.
Definition: story_base.h:73
goal_type.h
basic types related to goals
CmdCreateStoryPageElement
CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Create a new story page element.
Definition: story.cpp:153
Pool
Base class for all pools.
Definition: pool_type.hpp:83
CmdSetStoryPageDate
CommandCost CmdSetStoryPageDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update date of a story page.
Definition: story.cpp:264
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
DC_EXEC
execute the given command
Definition: command_type.h:342
company_func.h
Functions related to companies.
CmdShowStoryPage
CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Display a story page for all clients that are allowed to view the story page.
Definition: story.cpp:291
UpdateElement
static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32 reference, const char *text)
This helper for Create/Update PageElement Cmd procedure updates a page element with new content data...
Definition: story.cpp:80
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
_current_company
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
Pool::PoolItem<&_story_page_pool >::GetNumItems
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:276
WC_STORY_BOOK
Story book; Window numbers:
Definition: window_type.h:291
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:34
CmdCreateStoryPage
CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Create a new story page.
Definition: story.cpp:107
goal_base.h
Goal base class.
Pool::PoolItem<&_story_page_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
SPET_TEXT
A text element.
Definition: story_base.h:31
SPET_GOAL
An element that references a goal.
Definition: story_base.h:33
command_func.h
Functions related to commands.
ShowStoryBook
void ShowStoryBook(CompanyID company, uint16 page_id=INVALID_STORY_PAGE)
Raise or create the story book window for company, at page page_id.
Definition: story_gui.cpp:766
WC_MAIN_TOOLBAR
Main toolbar (the long bar at the top); Window numbers:
Definition: window_type.h:53
Pool::PoolItem<&_goal_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
story_base.h
StoryPage base class.
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:16
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
SPET_LOCATION
An element that references a tile along with a one-line text.
Definition: story_base.h:32
StoryPageElement::text
char * text
Static content text of page element.
Definition: story_base.h:53
StoryPageElement::type
StoryPageElementTypeByte type
Type of page element.
Definition: story_base.h:50
tile_map.h
Map writing/reading functions for tiles.
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:20
window_func.h
Window functions not directly related to making/drawing windows.
gui.h
GUI functions that shouldn&#39;t be here.
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
StoryPageID
uint16 StoryPageID
ID of a story page.
Definition: story_type.h:18
INVALID_COMPANY
An invalid company.
Definition: company_type.h:32
InvalidateWindowData
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3220