OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

goal.cpp
Go to the documentation of this file.
1 /* $Id: goal.cpp 26509 2014-04-25 15:40:32Z rubidium $ */
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 "company_func.h"
14 #include "industry.h"
15 #include "town.h"
16 #include "window_func.h"
17 #include "goal_base.h"
18 #include "core/pool_func.hpp"
19 #include "game/game.hpp"
20 #include "command_func.h"
21 #include "company_base.h"
22 #include "story_base.h"
23 #include "string_func.h"
24 #include "gui.h"
25 #include "network/network.h"
26
27 #include "safeguards.h"
28
29
30 GoalID _new_goal_id;
31
32 GoalPool _goal_pool("Goal");
33 INSTANTIATE_POOL_METHODS(Goal)
34
35
46 CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
47 {
48 if (!Goal::CanAllocateItem()) return CMD_ERROR;
49
50 GoalType type = (GoalType)GB(p1, 0, 8);
51 CompanyID company = (CompanyID)GB(p1, 8, 8);
52
53 if (_current_company != OWNER_DEITY) return CMD_ERROR;
54 if (StrEmpty(text)) return CMD_ERROR;
55 if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
56
57 switch (type) {
58 case GT_NONE:
59 if (p2 != 0) return CMD_ERROR;
60 break;
61
62 case GT_TILE:
63 if (!IsValidTile(p2)) return CMD_ERROR;
64 break;
65
66 case GT_INDUSTRY:
67 if (!Industry::IsValidID(p2)) return CMD_ERROR;
68 break;
69
70 case GT_TOWN:
71 if (!Town::IsValidID(p2)) return CMD_ERROR;
72 break;
73
74 case GT_COMPANY:
75 if (!Company::IsValidID(p2)) return CMD_ERROR;
76 break;
77
78 case GT_STORY_PAGE: {
79 if (!StoryPage::IsValidID(p2)) return CMD_ERROR;
80 CompanyByte story_company = StoryPage::Get(p2)->company;
81 if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR;
82 break;
83 }
84
85 default: return CMD_ERROR;
86 }
87
88 if (flags & DC_EXEC) {
89 Goal *g = new Goal();
90 g->type = type;
91 g->dst = p2;
92 g->company = company;
93 g->text = stredup(text);
94 g->progress = NULL;
95 g->completed = false;
96
97 if (g->company == INVALID_COMPANY) {
98 InvalidateWindowClassesData(WC_GOALS_LIST);
99 } else {
100 InvalidateWindowData(WC_GOALS_LIST, g->company);
101 }
102 if (Goal::GetNumItems() == 1) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
103
104 _new_goal_id = g->index;
105 }
106
107 return CommandCost();
108 }
109
119 CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
120 {
121 if (_current_company != OWNER_DEITY) return CMD_ERROR;
122 if (!Goal::IsValidID(p1)) return CMD_ERROR;
123
124 if (flags & DC_EXEC) {
125 Goal *g = Goal::Get(p1);
126 CompanyID c = g->company;
127 delete g;
128
129 if (c == INVALID_COMPANY) {
130 InvalidateWindowClassesData(WC_GOALS_LIST);
131 } else {
132 InvalidateWindowData(WC_GOALS_LIST, c);
133 }
134 if (Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
135 }
136
137 return CommandCost();
138 }
139
149 CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
150 {
151 if (_current_company != OWNER_DEITY) return CMD_ERROR;
152 if (!Goal::IsValidID(p1)) return CMD_ERROR;
153 if (StrEmpty(text)) return CMD_ERROR;
154
155 if (flags & DC_EXEC) {
156 Goal *g = Goal::Get(p1);
157 free(g->text);
158 g->text = stredup(text);
159
160 if (g->company == INVALID_COMPANY) {
161 InvalidateWindowClassesData(WC_GOALS_LIST);
162 } else {
163 InvalidateWindowData(WC_GOALS_LIST, g->company);
164 }
165 }
166
167 return CommandCost();
168 }
169
179 CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
180 {
181 if (_current_company != OWNER_DEITY) return CMD_ERROR;
182 if (!Goal::IsValidID(p1)) return CMD_ERROR;
183
184 if (flags & DC_EXEC) {
185 Goal *g = Goal::Get(p1);
186 free(g->progress);
187 if (StrEmpty(text)) {
188 g->progress = NULL;
189 } else {
190 g->progress = stredup(text);
191 }
192
193 if (g->company == INVALID_COMPANY) {
194 InvalidateWindowClassesData(WC_GOALS_LIST);
195 } else {
196 InvalidateWindowData(WC_GOALS_LIST, g->company);
197 }
198 }
199
200 return CommandCost();
201 }
202
212 CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
213 {
214 if (_current_company != OWNER_DEITY) return CMD_ERROR;
215 if (!Goal::IsValidID(p1)) return CMD_ERROR;
216
217 if (flags & DC_EXEC) {
218 Goal *g = Goal::Get(p1);
219 g->completed = p2 == 1;
220
221 if (g->company == INVALID_COMPANY) {
222 InvalidateWindowClassesData(WC_GOALS_LIST);
223 } else {
224 InvalidateWindowData(WC_GOALS_LIST, g->company);
225 }
226 }
227
228 return CommandCost();
229 }
230
242 CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
243 {
244 uint16 uniqueid = (GoalType)GB(p1, 0, 16);
245 CompanyID company = (CompanyID)GB(p1, 16, 8);
246 byte type = GB(p1, 24, 8);
247
248 if (_current_company != OWNER_DEITY) return CMD_ERROR;
249 if (StrEmpty(text)) return CMD_ERROR;
250 if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
251 if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR;
252 if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR;
253 if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR;
254
255 if (flags & DC_EXEC) {
256 if ((company != INVALID_COMPANY && company == _local_company) || (company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowGoalQuestion(uniqueid, type, p2, text);
257 }
258
259 return CommandCost();
260 }
261
271 CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
272 {
273 if (p1 > UINT16_MAX) return CMD_ERROR;
274 if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR;
275
276 if (_current_company == OWNER_DEITY) {
277 /* It has been requested to close this specific question on all clients */
278 if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
279 return CommandCost();
280 }
281
282 if (_networking && _local_company == _current_company) {
283 /* Somebody in the same company answered the question. Close the window */
284 if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
285 if (!_network_server) return CommandCost();
286 }
287
288 if (flags & DC_EXEC) {
289 Game::NewEvent(new ScriptEventGoalQuestionAnswer(p1, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << p2)));
290 }
291
292 return CommandCost();
293 }