# goal.cpp

Go to the documentation of this file.

    00001 /* $Id: goal.cpp 26382 2014-02-27 21:53:14Z frosch $ */
    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 "company_func.h"
    00014 #include "industry.h"
    00015 #include "town.h"
    00016 #include "window_func.h"
    00017 #include "goal_base.h"
    00018 #include "core/pool_func.hpp"
    00019 #include "game/game.hpp"
    00020 #include "command_func.h"
    00021 #include "company_base.h"
    00022 #include "story_base.h"
    00023 #include "string_func.h"
    00024 #include "gui.h"
    00025 #include "network/network.h"
    00026
    00027
    00028 GoalID _new_goal_id;
    00029
    00030 GoalPool _goal_pool("Goal");
    00031 INSTANTIATE_POOL_METHODS(Goal)
    00032
    00033
    00044 CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00045 {
    00046   if (!Goal::CanAllocateItem()) return CMD_ERROR;
    00047
    00048   GoalType type = (GoalType)GB(p1, 0, 8);
    00049   CompanyID company = (CompanyID)GB(p1, 8, 8);
    00050
    00051   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00052   if (StrEmpty(text)) return CMD_ERROR;
    00053   if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
    00054
    00055   switch (type) {
    00056     case GT_NONE:
    00057       if (p2 != 0) return CMD_ERROR;
    00058       break;
    00059
    00060     case GT_TILE:
    00061       if (!IsValidTile(p2)) return CMD_ERROR;
    00062       break;
    00063
    00064     case GT_INDUSTRY:
    00065       if (!Industry::IsValidID(p2)) return CMD_ERROR;
    00066       break;
    00067
    00068     case GT_TOWN:
    00069       if (!Town::IsValidID(p2)) return CMD_ERROR;
    00070       break;
    00071
    00072     case GT_COMPANY:
    00073       if (!Company::IsValidID(p2)) return CMD_ERROR;
    00074       break;
    00075
    00076     case GT_STORY_PAGE: {
    00077       if (!StoryPage::IsValidID(p2)) return CMD_ERROR;
    00078       CompanyByte story_company = StoryPage::Get(p2)->company;
    00079       if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR;
    00080       break;
    00081     }
    00082
    00083     default: return CMD_ERROR;
    00084   }
    00085
    00086   if (flags & DC_EXEC) {
    00087     Goal *g = new Goal();
    00088     g->type = type;
    00089     g->dst = p2;
    00090     g->company = company;
    00091     g->text = strdup(text);
    00092     g->progress = NULL;
    00093     g->completed = false;
    00094
    00095     if (g->company == INVALID_COMPANY) {
    00096       InvalidateWindowClassesData(WC_GOALS_LIST);
    00097     } else {
    00098       InvalidateWindowData(WC_GOALS_LIST, g->company);
    00099     }
    00100     if (Goal::GetNumItems() == 1) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
    00101
    00102     _new_goal_id = g->index;
    00103   }
    00104
    00105   return CommandCost();
    00106 }
    00107
    00117 CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00118 {
    00119   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00120   if (!Goal::IsValidID(p1)) return CMD_ERROR;
    00121
    00122   if (flags & DC_EXEC) {
    00123     Goal *g = Goal::Get(p1);
    00124     CompanyID c = g->company;
    00125     delete g;
    00126
    00127     if (c == INVALID_COMPANY) {
    00128       InvalidateWindowClassesData(WC_GOALS_LIST);
    00129     } else {
    00130       InvalidateWindowData(WC_GOALS_LIST, c);
    00131     }
    00132     if (Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
    00133   }
    00134
    00135   return CommandCost();
    00136 }
    00137
    00147 CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00148 {
    00149   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00150   if (!Goal::IsValidID(p1)) return CMD_ERROR;
    00151   if (StrEmpty(text)) return CMD_ERROR;
    00152
    00153   if (flags & DC_EXEC) {
    00154     Goal *g = Goal::Get(p1);
    00155     free(g->text);
    00156     g->text = strdup(text);
    00157
    00158     if (g->company == INVALID_COMPANY) {
    00159       InvalidateWindowClassesData(WC_GOALS_LIST);
    00160     } else {
    00161       InvalidateWindowData(WC_GOALS_LIST, g->company);
    00162     }
    00163   }
    00164
    00165   return CommandCost();
    00166 }
    00167
    00177 CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00178 {
    00179   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00180   if (!Goal::IsValidID(p1)) return CMD_ERROR;
    00181
    00182   if (flags & DC_EXEC) {
    00183     Goal *g = Goal::Get(p1);
    00184     free(g->progress);
    00185     if (StrEmpty(text)) {
    00186       g->progress = NULL;
    00187     } else {
    00188       g->progress = strdup(text);
    00189     }
    00190
    00191     if (g->company == INVALID_COMPANY) {
    00192       InvalidateWindowClassesData(WC_GOALS_LIST);
    00193     } else {
    00194       InvalidateWindowData(WC_GOALS_LIST, g->company);
    00195     }
    00196   }
    00197
    00198   return CommandCost();
    00199 }
    00200
    00210 CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00211 {
    00212   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00213   if (!Goal::IsValidID(p1)) return CMD_ERROR;
    00214
    00215   if (flags & DC_EXEC) {
    00216     Goal *g = Goal::Get(p1);
    00217     g->completed = p2 == 1;
    00218
    00219     if (g->company == INVALID_COMPANY) {
    00220       InvalidateWindowClassesData(WC_GOALS_LIST);
    00221     } else {
    00222       InvalidateWindowData(WC_GOALS_LIST, g->company);
    00223     }
    00224   }
    00225
    00226   return CommandCost();
    00227 }
    00228
    00240 CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00241 {
    00242   uint16 uniqueid = (GoalType)GB(p1, 0, 16);
    00243   CompanyID company = (CompanyID)GB(p1, 16, 8);
    00244   byte type = GB(p1, 24, 8);
    00245
    00246   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00247   if (StrEmpty(text)) return CMD_ERROR;
    00248   if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
    00249   if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR;
    00250   if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR;
    00251   if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR;
    00252
    00253   if (flags & DC_EXEC) {
    00254     if ((company != INVALID_COMPANY && company == _local_company) || (company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowGoalQuestion(uniqueid, type, p2, text);
    00255   }
    00256
    00257   return CommandCost();
    00258 }
    00259
    00269 CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00270 {
    00271   if (p1 > UINT16_MAX) return CMD_ERROR;
    00272   if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR;
    00273
    00274   if (_current_company == OWNER_DEITY) {
    00275     /* It has been requested to close this specific question on all clients */
    00276     if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
    00277     return CommandCost();
    00278   }
    00279
    00280   if (_networking && _local_company == _current_company) {
    00281     /* Somebody in the same company answered the question. Close the window */
    00282     if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
    00283     if (!_network_server) return CommandCost();
    00284   }
    00285
    00286   if (flags & DC_EXEC) {
    00287     Game::NewEvent(new ScriptEventGoalQuestionAnswer(p1, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << p2)));
    00288   }
    00289
    00290   return CommandCost();
    00291 }