summaryrefslogtreecommitdiff
path: root/src/story.cpp
diff options
context:
space:
mode:
authorzuu <zuu@openttd.org>2013-06-09 12:19:09 +0000
committerzuu <zuu@openttd.org>2013-06-09 12:19:09 +0000
commit9aa1bf026443ddc65ab4381e86c294943ddc30d8 (patch)
tree82af61f4b6f346bd71046a5d6fa6bab1f49b3d34 /src/story.cpp
parentbea60988c67b40fb5b3058990779a4d572511224 (diff)
downloadopenttd-9aa1bf026443ddc65ab4381e86c294943ddc30d8.tar.xz
(svn r25342) -Add: StoryPage data structures and GS API
Diffstat (limited to 'src/story.cpp')
-rw-r--r--src/story.cpp271
1 files changed, 271 insertions, 0 deletions
diff --git a/src/story.cpp b/src/story.cpp
new file mode 100644
index 000000000..3574cf525
--- /dev/null
+++ b/src/story.cpp
@@ -0,0 +1,271 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * 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.
+ * 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.
+ * 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/>.
+ */
+
+/** @file story.cpp Handling of stories. */
+
+#include "stdafx.h"
+#include "story_base.h"
+#include "core/pool_func.hpp"
+#include "command_func.h"
+#include "company_base.h"
+#include "company_func.h"
+#include "string_func.h"
+#include "date_func.h"
+#include "tile_map.h"
+#include "goal_type.h"
+#include "goal_base.h"
+
+
+StoryPageElementID _new_story_page_element_id;
+StoryPageID _new_story_page_id;
+uint32 _story_page_element_next_sort_value;
+uint32 _story_page_next_sort_value;
+
+StoryPageElementPool _story_page_element_pool("StoryPageElement");
+StoryPagePool _story_page_pool("StoryPage");
+INSTANTIATE_POOL_METHODS(StoryPageElement)
+INSTANTIATE_POOL_METHODS(StoryPage)
+
+/**
+ * This helper for Create/Update PageElement Cmd procedure verifies if the page
+ * element parameters are correct for the given page element type.
+ * @param page_id The page id of the page which the page element (will) belong to
+ * @param type The type of the page element to create/update
+ * @param tile The tile parameter of the DoCommand proc
+ * @param reference The reference parameter of the DoCommand proc (p2)
+ * @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)
+{
+ switch (type) {
+ case SPET_TEXT:
+ if (StrEmpty(text)) return false;
+ break;
+ case SPET_LOCATION:
+ if (StrEmpty(text)) return false;
+ if (!IsValidTile(tile)) return false;
+ break;
+ case SPET_GOAL:
+ if (!Goal::IsValidID((GoalID)reference)) return false;
+ /* Reject company specific goals on global pages */
+ if (StoryPage::Get(page_id)->company == INVALID_COMPANY && Goal::Get((GoalID)reference)->company != INVALID_COMPANY) return false;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * This helper for Create/Update PageElement Cmd procedure updates a page
+ * element with new content data.
+ * @param pe The page element to update
+ * @param tile The tile parameter of the DoCommand proc
+ * @param reference The reference parameter of the DoCommand proc (p2)
+ * @param text The text parameter of the DoCommand proc
+ */
+static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32 reference, const char *text)
+{
+ switch (pe.type) {
+ case SPET_TEXT:
+ pe.text = strdup(text);
+ break;
+ case SPET_LOCATION:
+ pe.text = strdup(text);
+ pe.referenced_id = tile;
+ break;
+ case SPET_GOAL:
+ pe.referenced_id = (GoalID)reference;
+ break;
+ }
+}
+
+/**
+ * Create a new story page.
+ * @param tile unused.
+ * @param flags type of operation
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0 - 7) - Company for which this story page belongs to.
+ * @param p2 unused.
+ * @param text Title of the story page. Null is allowed in wich case a generic page title is provided by OpenTTD.
+ * @return the cost of this operation or an error
+ */
+CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+ if (!StoryPage::CanAllocateItem()) return CMD_ERROR;
+
+ CompanyID company = (CompanyID)GB(p1, 0, 8);
+
+ if (_current_company != OWNER_DEITY) return CMD_ERROR;
+ if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ if (_story_page_pool.items == 0) {
+ /* Initialize the next sort value variable. */
+ _story_page_next_sort_value = 0;
+ }
+
+ StoryPage *s = new StoryPage();
+ s->sort_value = _story_page_next_sort_value;
+ s->date = _date;
+ s->company = company;
+ if (StrEmpty(text)) {
+ s->title = NULL;
+ } else {
+ s->title = strdup(text);
+ }
+
+ _new_story_page_id = s->index;
+ _story_page_next_sort_value++;
+ }
+
+ return CommandCost();
+}
+
+/**
+ * Create a new story page element.
+ * @param tile Tile location if it is a location page element, otherwise unused.
+ * @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
+ * @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
+ */
+CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+ if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR;
+
+ StoryPageID page_id = (CompanyID)GB(p1, 0, 16);
+ StoryPageElementType type = (StoryPageElementType) GB(p1, 16, 16);
+
+ /* Allow at most 128 elements per page. */
+ uint16 element_count = 0;
+ StoryPageElement *iter;
+ FOR_ALL_STORY_PAGE_ELEMENTS(iter) {
+ if (iter->page == page_id) element_count++;
+ }
+ if (element_count >= 128) return CMD_ERROR;
+
+ if (_current_company != OWNER_DEITY) return CMD_ERROR;
+ if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
+ if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ if (_story_page_element_pool.items == 0) {
+ /* Initialize the next sort value variable. */
+ _story_page_element_next_sort_value = 0;
+ }
+
+ StoryPageElement *pe = new StoryPageElement();
+ pe->sort_value = _story_page_element_next_sort_value;
+ pe->type = type;
+ pe->page = page_id;
+ UpdateElement(*pe, tile, p2, text);
+
+ _new_story_page_element_id = pe->index;
+ _story_page_element_next_sort_value++;
+ }
+
+ return CommandCost();
+}
+
+/**
+ * Update a new story page element.
+ * @param tile Tile location if it is a location page element, otherwise unused.
+ * @param flags type of operation
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0 - 15) - The page element to update.
+ * (bit 16 - 31) - unused
+ * @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
+ */
+CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+ StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16);
+
+ if (_current_company != OWNER_DEITY) return CMD_ERROR;
+ if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
+
+ StoryPageElement *pe = StoryPageElement::Get(page_element_id);
+ StoryPageID page_id = pe->page;
+ StoryPageElementType type = pe->type;
+
+ if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ UpdateElement(*pe, tile, p2, text);
+ }
+
+ return CommandCost();
+}
+
+/**
+ * Update title of a story page.
+ * @param tile unused.
+ * @param flags type of operation
+ * @param p1 StoryPageID to update.
+ * @param p2 unused
+ * @param text title text of the story page.
+ * @return the cost of this operation or an error
+ */
+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;
+ if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StoryPage *p = StoryPage::Get(page_id);
+ free(p->title);
+ if (StrEmpty(text)) {
+ p->title = NULL;
+ } else {
+ p->title = strdup(text);
+ }
+ }
+
+ return CommandCost();
+}
+
+/**
+ * Remove a story page and associated story page elements.
+ * @param tile unused.
+ * @param flags type of operation
+ * @param p1 StoryPageID to remove.
+ * @param p2 unused.
+ * @param text unused.
+ * @return the cost of this operation or an error
+ */
+CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+ if (_current_company != OWNER_DEITY) return CMD_ERROR;
+ StoryPageID page_id = (StoryPageID)p1;
+ if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
+
+ if (flags & DC_EXEC) {
+ StoryPage *p = StoryPage::Get(page_id);
+
+ StoryPageElement *pe;
+ FOR_ALL_STORY_PAGE_ELEMENTS(pe) {
+ if (pe->page == p->index) {
+ delete pe;
+ }
+ }
+
+ delete p;
+ }
+
+ return CommandCost();
+}
+