# story.cpp

Go to the documentation of this file.

    00001 /* $Id: story.cpp 26306 2014-02-06 19:48:19Z zuu $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "story_base.h"
    00014 #include "core/pool_func.hpp"
    00015 #include "cmd_helper.h"
    00016 #include "command_func.h"
    00017 #include "company_base.h"
    00018 #include "company_func.h"
    00019 #include "string_func.h"
    00020 #include "date_func.h"
    00021 #include "tile_map.h"
    00022 #include "goal_type.h"
    00023 #include "goal_base.h"
    00024 #include "window_func.h"
    00025 #include "gui.h"
    00026
    00027
    00028 StoryPageElementID _new_story_page_element_id;
    00029 StoryPageID _new_story_page_id;
    00030 uint32 _story_page_element_next_sort_value;
    00031 uint32 _story_page_next_sort_value;
    00032
    00033 StoryPageElementPool _story_page_element_pool("StoryPageElement");
    00034 StoryPagePool _story_page_pool("StoryPage");
    00035 INSTANTIATE_POOL_METHODS(StoryPageElement)
    00036 INSTANTIATE_POOL_METHODS(StoryPage)
    00037
    00048 static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text)
    00049 {
    00050   switch (type) {
    00051     case SPET_TEXT:
    00052       if (StrEmpty(text)) return false;
    00053       break;
    00054     case SPET_LOCATION:
    00055       if (StrEmpty(text)) return false;
    00056       if (!IsValidTile(tile)) return false;
    00057       break;
    00058     case SPET_GOAL:
    00059       if (!Goal::IsValidID((GoalID)reference)) return false;
    00060       /* Reject company specific goals on global pages */
    00061       if (StoryPage::Get(page_id)->company == INVALID_COMPANY && Goal::Get((GoalID)reference)->company != INVALID_COMPANY) return false;
    00062       break;
    00063     default:
    00064       return false;
    00065   }
    00066
    00067   return true;
    00068 }
    00069
    00078 static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32 reference, const char *text)
    00079 {
    00080   switch (pe.type) {
    00081     case SPET_TEXT:
    00082       pe.text = strdup(text);
    00083       break;
    00084     case SPET_LOCATION:
    00085       pe.text = strdup(text);
    00086       pe.referenced_id = tile;
    00087       break;
    00088     case SPET_GOAL:
    00089       pe.referenced_id = (GoalID)reference;
    00090       break;
    00091     default: NOT_REACHED();
    00092   }
    00093 }
    00094
    00105 CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00106 {
    00107   if (!StoryPage::CanAllocateItem()) return CMD_ERROR;
    00108
    00109   CompanyID company = (CompanyID)GB(p1, 0, 8);
    00110
    00111   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00112   if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
    00113
    00114   if (flags & DC_EXEC) {
    00115     if (_story_page_pool.items == 0) {
    00116       /* Initialize the next sort value variable. */
    00117       _story_page_next_sort_value = 0;
    00118     }
    00119
    00120     StoryPage *s = new StoryPage();
    00121     s->sort_value = _story_page_next_sort_value;
    00122     s->date = _date;
    00123     s->company = company;
    00124     if (StrEmpty(text)) {
    00125       s->title = NULL;
    00126     } else {
    00127       s->title = strdup(text);
    00128     }
    00129
    00130     InvalidateWindowClassesData(WC_STORY_BOOK, -1);
    00131     if (StoryPage::GetNumItems() == 1) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
    00132
    00133     _new_story_page_id = s->index;
    00134     _story_page_next_sort_value++;
    00135   }
    00136
    00137   return CommandCost();
    00138 }
    00139
    00151 CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00152 {
    00153   if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR;
    00154
    00155   StoryPageID page_id = (CompanyID)GB(p1, 0, 16);
    00156   StoryPageElementType type = Extract<StoryPageElementType, 16, 8>(p1);
    00157
    00158   /* Allow at most 128 elements per page. */
    00159   uint16 element_count = 0;
    00160   StoryPageElement *iter;
    00161   FOR_ALL_STORY_PAGE_ELEMENTS(iter) {
    00162     if (iter->page == page_id) element_count++;
    00163   }
    00164   if (element_count >= 128) return CMD_ERROR;
    00165
    00166   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00167   if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
    00168   if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
    00169
    00170   if (flags & DC_EXEC) {
    00171     if (_story_page_element_pool.items == 0) {
    00172       /* Initialize the next sort value variable. */
    00173       _story_page_element_next_sort_value = 0;
    00174     }
    00175
    00176     StoryPageElement *pe = new StoryPageElement();
    00177     pe->sort_value = _story_page_element_next_sort_value;
    00178     pe->type = type;
    00179     pe->page = page_id;
    00180     UpdateElement(*pe, tile, p2, text);
    00181
    00182     InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
    00183
    00184     _new_story_page_element_id = pe->index;
    00185     _story_page_element_next_sort_value++;
    00186   }
    00187
    00188   return CommandCost();
    00189 }
    00190
    00202 CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00203 {
    00204   StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16);
    00205
    00206   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00207   if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
    00208
    00209   StoryPageElement *pe = StoryPageElement::Get(page_element_id);
    00210   StoryPageID page_id = pe->page;
    00211   StoryPageElementType type = pe->type;
    00212
    00213   if (!VerifyElementContentParameters(page_id, type, tile, p2, text)) return CMD_ERROR;
    00214
    00215   if (flags & DC_EXEC) {
    00216     UpdateElement(*pe, tile, p2, text);
    00217     InvalidateWindowClassesData(WC_STORY_BOOK, pe->page);
    00218   }
    00219
    00220   return CommandCost();
    00221 }
    00222
    00232 CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00233 {
    00234   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00235   StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
    00236   if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
    00237
    00238   if (flags & DC_EXEC) {
    00239     StoryPage *p = StoryPage::Get(page_id);
    00240     free(p->title);
    00241     if (StrEmpty(text)) {
    00242       p->title = NULL;
    00243     } else {
    00244       p->title = strdup(text);
    00245     }
    00246
    00247     InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
    00248   }
    00249
    00250   return CommandCost();
    00251 }
    00252
    00262 CommandCost CmdSetStoryPageDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00263 {
    00264   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00265   StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
    00266   if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
    00267   Date date = (Date)p2;
    00268
    00269   if (flags & DC_EXEC) {
    00270     StoryPage *p = StoryPage::Get(page_id);
    00271     p->date = date;
    00272
    00273     InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
    00274   }
    00275
    00276   return CommandCost();
    00277 }
    00278
    00289 CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00290 {
    00291   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00292   StoryPageID page_id = (StoryPageID)GB(p1, 0, 16);
    00293   if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
    00294
    00295   if (flags & DC_EXEC) {
    00296     StoryPage *g = StoryPage::Get(page_id);
    00297     if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id);
    00298   }
    00299
    00300   return CommandCost();
    00301 }
    00311 CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00312 {
    00313   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00314   StoryPageID page_id = (StoryPageID)p1;
    00315   if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;
    00316
    00317   if (flags & DC_EXEC) {
    00318     StoryPage *p = StoryPage::Get(page_id);
    00319
    00320     StoryPageElement *pe;
    00321     FOR_ALL_STORY_PAGE_ELEMENTS(pe) {
    00322       if (pe->page == p->index) {
    00323         delete pe;
    00324       }
    00325     }
    00326
    00327     delete p;
    00328
    00329     InvalidateWindowClassesData(WC_STORY_BOOK, -1);
    00330     if (StoryPage::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
    00331   }
    00332
    00333   return CommandCost();
    00334 }
    00335
    00345 CommandCost CmdRemoveStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00346 {
    00347   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00348   StoryPageElementID page_element_id = (StoryPageElementID)p1;
    00349   if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
    00350
    00351   if (flags & DC_EXEC) {
    00352     StoryPageElement *pe = StoryPageElement::Get(page_element_id);
    00353     StoryPageID page_id = pe->page;
    00354
    00355     delete pe;
    00356
    00357     InvalidateWindowClassesData(WC_STORY_BOOK, page_id);
    00358   }
    00359
    00360   return CommandCost();
    00361 }
    00362