OpenTTD
goal.cpp
Go to the documentation of this file.
1 /* $Id$ */
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 #include "network/network_base.h"
27 #include "network/network_func.h"
28 
29 #include "safeguards.h"
30 
31 
32 GoalID _new_goal_id;
33 
34 GoalPool _goal_pool("Goal");
36 
37 
48 CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
49 {
50  if (!Goal::CanAllocateItem()) return CMD_ERROR;
51 
52  GoalType type = (GoalType)GB(p1, 0, 8);
53  CompanyID company = (CompanyID)GB(p1, 8, 8);
54 
55  if (_current_company != OWNER_DEITY) return CMD_ERROR;
56  if (StrEmpty(text)) return CMD_ERROR;
57  if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
58 
59  switch (type) {
60  case GT_NONE:
61  if (p2 != 0) return CMD_ERROR;
62  break;
63 
64  case GT_TILE:
65  if (!IsValidTile(p2)) return CMD_ERROR;
66  break;
67 
68  case GT_INDUSTRY:
69  if (!Industry::IsValidID(p2)) return CMD_ERROR;
70  break;
71 
72  case GT_TOWN:
73  if (!Town::IsValidID(p2)) return CMD_ERROR;
74  break;
75 
76  case GT_COMPANY:
77  if (!Company::IsValidID(p2)) return CMD_ERROR;
78  break;
79 
80  case GT_STORY_PAGE: {
81  if (!StoryPage::IsValidID(p2)) return CMD_ERROR;
82  CompanyByte story_company = StoryPage::Get(p2)->company;
83  if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR;
84  break;
85  }
86 
87  default: return CMD_ERROR;
88  }
89 
90  if (flags & DC_EXEC) {
91  Goal *g = new Goal();
92  g->type = type;
93  g->dst = p2;
94  g->company = company;
95  g->text = stredup(text);
96  g->progress = NULL;
97  g->completed = false;
98 
99  if (g->company == INVALID_COMPANY) {
101  } else {
103  }
105 
106  _new_goal_id = g->index;
107  }
108 
109  return CommandCost();
110 }
111 
121 CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
122 {
123  if (_current_company != OWNER_DEITY) return CMD_ERROR;
124  if (!Goal::IsValidID(p1)) return CMD_ERROR;
125 
126  if (flags & DC_EXEC) {
127  Goal *g = Goal::Get(p1);
128  CompanyID c = g->company;
129  delete g;
130 
131  if (c == INVALID_COMPANY) {
133  } else {
135  }
137  }
138 
139  return CommandCost();
140 }
141 
151 CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
152 {
153  if (_current_company != OWNER_DEITY) return CMD_ERROR;
154  if (!Goal::IsValidID(p1)) return CMD_ERROR;
155  if (StrEmpty(text)) return CMD_ERROR;
156 
157  if (flags & DC_EXEC) {
158  Goal *g = Goal::Get(p1);
159  free(g->text);
160  g->text = stredup(text);
161 
162  if (g->company == INVALID_COMPANY) {
164  } else {
166  }
167  }
168 
169  return CommandCost();
170 }
171 
181 CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
182 {
183  if (_current_company != OWNER_DEITY) return CMD_ERROR;
184  if (!Goal::IsValidID(p1)) return CMD_ERROR;
185 
186  if (flags & DC_EXEC) {
187  Goal *g = Goal::Get(p1);
188  free(g->progress);
189  if (StrEmpty(text)) {
190  g->progress = NULL;
191  } else {
192  g->progress = stredup(text);
193  }
194 
195  if (g->company == INVALID_COMPANY) {
197  } else {
199  }
200  }
201 
202  return CommandCost();
203 }
204 
214 CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
215 {
216  if (_current_company != OWNER_DEITY) return CMD_ERROR;
217  if (!Goal::IsValidID(p1)) return CMD_ERROR;
218 
219  if (flags & DC_EXEC) {
220  Goal *g = Goal::Get(p1);
221  g->completed = p2 == 1;
222 
223  if (g->company == INVALID_COMPANY) {
225  } else {
227  }
228  }
229 
230  return CommandCost();
231 }
232 
246 CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
247 {
248  uint16 uniqueid = (GoalType)GB(p1, 0, 16);
249  CompanyID company = (CompanyID)GB(p1, 16, 8);
250 #ifdef ENABLE_NETWORK
251  ClientIndex client = (ClientIndex)GB(p1, 16, 8);
252 #endif
253  byte type = GB(p1, 24, 2);
254  bool is_client = HasBit(p1, 31);
255 
256  if (_current_company != OWNER_DEITY) return CMD_ERROR;
257  if (StrEmpty(text)) return CMD_ERROR;
258  if (is_client) {
259 #ifdef ENABLE_NETWORK
260  if (!NetworkClientInfo::IsValidID(client)) return CMD_ERROR;
261 #else
262  return CMD_ERROR;
263 #endif
264  } else {
265  if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
266  }
267  if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR;
268  if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR;
269  if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR;
270 
271  if (flags & DC_EXEC) {
272  if (is_client) {
273 #ifdef ENABLE_NETWORK
274  if (NetworkClientInfo::Get(client)->client_id != _network_own_client_id) return CommandCost();
275 #endif
276  } else {
277  if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost();
278  if (company != INVALID_COMPANY && company != _local_company) return CommandCost();
279  }
280  ShowGoalQuestion(uniqueid, type, p2, text);
281  }
282 
283  return CommandCost();
284 }
285 
295 CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
296 {
297  if (p1 > UINT16_MAX) return CMD_ERROR;
298  if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR;
299 
300  if (_current_company == OWNER_DEITY) {
301  /* It has been requested to close this specific question on all clients */
302  if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
303  return CommandCost();
304  }
305 
307  /* Somebody in the same company answered the question. Close the window */
308  if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1);
309  if (!_network_server) return CommandCost();
310  }
311 
312  if (flags & DC_EXEC) {
313  Game::NewEvent(new ScriptEventGoalQuestionAnswer(p1, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << p2)));
314  }
315 
316  return CommandCost();
317 }
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:134
Definition of stuff that is very close to a company, like the company struct itself.
bool _networking
are we in networking mode?
Definition: network.cpp:56
CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Create a new goal.
Definition: goal.cpp:48
CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Ask a goal related question.
Definition: goal.cpp:246
Destination is a story page.
Definition: goal_type.h:27
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
Destination is a company.
Definition: goal_type.h:26
uint16 GoalID
ID of a goal.
Definition: goal_type.h:34
Popup with a set of buttons, designed to ask the user a question from a GameScript.
Definition: window_type.h:132
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:25
Destination is a town.
Definition: goal_type.h:25
Destination is not linked.
Definition: goal_type.h:22
Struct about goals, current and completed.
Definition: goal_base.h:23
Goals list; Window numbers:
Definition: window_type.h:285
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
Base core network types and some helper functions to access them.
Common return value for all commands.
Definition: command_type.h:25
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
GoalTypeID dst
Index of type.
Definition: goal_base.h:26
The object is owned by a superuser / goal script.
Definition: company_type.h:29
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:163
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:3297
Functions related to low-level strings.
Some methods of Pool are placed here in order to reduce compilation time and binary size...
CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update progress text of a goal.
Definition: goal.cpp:181
Destination is an industry.
Definition: goal_type.h:24
DoCommandFlag
List of flags for a command.
Definition: command_type.h:343
GoalType
Types of goal destinations.
Definition: goal_type.h:21
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:63
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:138
Basic functions/variables used all over the place.
Destination is a tile.
Definition: goal_type.h:23
GoalTypeByte type
Type of the goal.
Definition: goal_base.h:25
Base class for all pools.
Definition: pool_type.hpp:83
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1143
execute the given command
Definition: command_type.h:345
Functions related to companies.
CompanyByte company
Goal is for a specific company; INVALID_COMPANY if it is global.
Definition: goal_base.h:24
char * progress
Progress text of the goal.
Definition: goal_base.h:28
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:276
bool completed
Is the goal completed or not?
Definition: goal_base.h:29
void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question)
Display a goal question.
Definition: goal_gui.cpp:489
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove a goal.
Definition: goal.cpp:121
Goal base class.
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
static uint CountBits(T value)
Counts the number of set bits in a variable.
Base functions for all Games.
Functions related to commands.
Network functions used by other parts of OpenTTD.
bool _network_server
network-server is active
Definition: network.cpp:57
Main toolbar (the long bar at the top); Window numbers:
Definition: window_type.h:53
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
uint8 ClientIndex
Indices into the client tables.
Definition: network_type.h:50
CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update goal text of a goal.
Definition: goal.cpp:151
StoryPage base class.
Base of all industries.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static const uint32 GOAL_QUESTION_BUTTON_COUNT
Amount of buttons available.
Definition: goal_type.h:17
Base of the town class.
CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Reply to a goal question.
Definition: goal.cpp:295
char * text
Text of the goal.
Definition: goal_base.h:27
static const byte GOAL_QUESTION_TYPE_COUNT
Amount of question types.
Definition: goal_type.h:18
Owner
Enum for all companies/owners.
Definition: company_type.h:20
Window functions not directly related to making/drawing windows.
CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update completed state of a goal.
Definition: goal.cpp:214
GUI functions that shouldn&#39;t be here.
An invalid company.
Definition: company_type.h:32
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:3279