OpenTTD
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");
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) {
99  } else {
101  }
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) {
131  } else {
133  }
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) {
162  } else {
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) {
195  } else {
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) {
223  } else {
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 
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 }
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:46
CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Ask a goal related question.
Definition: goal.cpp:242
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
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:154
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:3238
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:179
Destination is an industry.
Definition: goal_type.h:24
DoCommandFlag
List of flags for a command.
Definition: command_type.h:340
GoalType
Types of goal destinations.
Definition: goal_type.h:21
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:126
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:1137
execute the given command
Definition: command_type.h:342
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:119
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.
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
CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Update goal text of a goal.
Definition: goal.cpp:149
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 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:271
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:212
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:3220