OpenTTD Source: src/command_func.h Source File

OpenTTD Source 13.2.1

command_func.h
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10 #ifndef COMMAND_FUNC_H
11 #define COMMAND_FUNC_H
12
13 #include "command_type.h"
14 #include "network/network_type.h"
15 #include "company_type.h"
16 #include "company_func.h"
17 #include "core/backup_type.hpp"
18 #include "misc/endian_buffer.hpp"
19 #include "tile_map.h"
20
28 static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
29
38 #define return_cmd_error(errcode) return CommandCost(errcode);
39
40 void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data);
41
42 bool IsValidCommand(Commands cmd);
43 CommandFlags GetCommandFlags(Commands cmd);
44 const char *GetCommandName(Commands cmd);
45 Money GetAvailableMoneyForCommand();
46 bool IsCommandAllowedWhilePaused(Commands cmd);
47
48 template <Commands Tcmd>
49 constexpr CommandFlags GetCommandFlags()
50 {
51 return CommandTraits<Tcmd>::flags;
52 }
53
59 static constexpr inline DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags)
60 {
61 DoCommandFlag flags = DC_NONE;
62 if (cmd_flags & CMD_NO_WATER) flags |= DC_NO_WATER;
63 if (cmd_flags & CMD_AUTO) flags |= DC_AUTO;
64 if (cmd_flags & CMD_ALL_TILES) flags |= DC_ALL_TILES;
65 return flags;
66 }
67
69 struct RecursiveCommandCounter {
70 RecursiveCommandCounter() noexcept { _counter++; }
71 ~RecursiveCommandCounter() noexcept { _counter--; }
72
74 bool IsTopLevel() const { return _counter == 1; }
75 private:
76 static int _counter;
77 };
78
79 #if defined(__GNUC__) && !defined(__clang__)
80 /*
81 * We cast specialized function pointers to a generic one, but don't use the
82 * converted value to call the function, which is safe, except that GCC
83 * helpfully thinks it is not.
84 *
85 * "Any pointer to function can be converted to a pointer to a different function type.
86 * Calling the function through a pointer to a different function type is undefined,
87 * but converting such pointer back to pointer to the original function type yields
88 * the pointer to the original function." */
89 # pragma GCC diagnostic push
90 # pragma GCC diagnostic ignored "-Wcast-function-type"
91 # define SILENCE_GCC_FUNCTION_POINTER_CAST
92 #endif
93
94 template<Commands TCmd, typename T, bool THasTile> struct CommandHelper;
95
96 class CommandHelperBase {
97 protected:
98 static void InternalDoBefore(bool top_level, bool test);
99 static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test);
100 static std::tuple<bool, bool, bool> InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command);
101 static void InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd);
102 static bool InternalExecutePrepTest(CommandFlags cmd_flags, TileIndex tile, Backup<CompanyID> &cur_company);
103 static std::tuple<bool, bool, bool> InternalExecuteValidateTestAndPrepExec(CommandCost &res, CommandFlags cmd_flags, bool estimate_only, bool network_command, Backup<CompanyID> &cur_company);
104 static CommandCost InternalExecuteProcessResult(Commands cmd, CommandFlags cmd_flags, const CommandCost &res_test, const CommandCost &res_exec, Money extra_cash, TileIndex tile, Backup<CompanyID> &cur_company);
105 static void LogCommandExecution(Commands cmd, StringID err_message, TileIndex tile, const CommandDataBuffer &args, bool failed);
106 };
107
115 template <Commands Tcmd, typename Tret, typename... Targs>
116 struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true> : protected CommandHelperBase {
117 private:
119 static inline CommandCost &ExtractCommandCost(Tret &ret)
120 {
121 if constexpr (std::is_same_v<Tret, CommandCost>) {
122 return ret;
123 } else {
124 return std::get<0>(ret);
125 }
126 }
127
129 static inline Tret MakeResult(const CommandCost &cost)
130 {
131 Tret ret{};
132 ExtractCommandCost(ret) = cost;
133 return ret;
134 }
135
136 public:
150 static Tret Do(DoCommandFlag flags, Targs... args)
151 {
152 if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, std::tuple<Targs...>>>) {
153 /* Do not even think about executing out-of-bounds tile-commands. */
154 TileIndex tile = std::get<0>(std::make_tuple(args...));
155 if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return MakeResult(CMD_ERROR);
156 }
157
158 RecursiveCommandCounter counter{};
159
160 /* Only execute the test call if it's toplevel, or we're not execing. */
161 if (counter.IsTopLevel() || !(flags & DC_EXEC)) {
162 InternalDoBefore(counter.IsTopLevel(), true);
163 Tret res = CommandTraits<Tcmd>::proc(flags & ~DC_EXEC, args...);
164 InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), true); // Can modify res.
165
166 if (ExtractCommandCost(res).Failed() || !(flags & DC_EXEC)) return res;
167 }
168
169 /* Execute the command here. All cost-relevant functions set the expenses type
170 * themselves to the cost object at some point. */
171 InternalDoBefore(counter.IsTopLevel(), false);
172 Tret res = CommandTraits<Tcmd>::proc(flags, args...);
173 InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), false);
174
175 return res;
176 }
177
183 static inline bool Post(StringID err_message, Targs... args) { return Post<CommandCallback>(err_message, nullptr, std::forward<Targs>(args)...); }
189 template <typename Tcallback>
190 static inline bool Post(Tcallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward<Targs>(args)...); }
195 static inline bool Post(Targs... args) { return Post<CommandCallback>((StringID)0, nullptr, std::forward<Targs>(args)...); }
196
207 template <typename Tcallback>
208 static bool Post(StringID err_message, Tcallback *callback, Targs... args)
209 {
210 return InternalPost(err_message, callback, true, false, std::forward_as_tuple(args...));
211 }
212
221 template <typename Tcallback>
222 static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, std::tuple<Targs...> args)
223 {
224 return InternalPost(err_message, callback, my_cmd, true, std::move(args));
225 }
226
234 static void SendNet(StringID err_message, CompanyID company, Targs... args)
235 {
236 auto args_tuple = std::forward_as_tuple(args...);
237
238 ::NetworkSendCommand(Tcmd, err_message, nullptr, company, EndianBufferWriter<CommandDataBuffer>::FromValue(args_tuple));
239 }
240
251 template <typename Tcallback>
252 static Tret Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple<Targs...> args)
253 {
254 return Execute(err_message, reinterpret_cast<CommandCallback *>(callback), my_cmd, estimate_only, false, location, std::move(args));
255 }
256
257 protected:
259 template <class T>
260 static inline void SetClientIdHelper(T &data)
261 {
262 if constexpr (std::is_same_v<ClientID, T>) {
263 if (data == INVALID_CLIENT_ID) data = CLIENT_ID_SERVER;
264 }
265 }
266
268 template<class Ttuple, size_t... Tindices>
269 static inline void SetClientIds(Ttuple &values, std::index_sequence<Tindices...>)
270 {
271 ((SetClientIdHelper(std::get<Tindices>(values))), ...);
272 }
273
275 template <template <typename...> typename Tt, typename T1, typename... Ts>
276 static inline Tt<Ts...> RemoveFirstTupleElement(const Tt<T1, Ts...> &tuple)
277 {
278 return std::apply([](auto &&, const auto&... args) { return std::tie(args...); }, tuple);
279 }
280
281 template <typename Tcallback>
282 static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, std::tuple<Targs...> args)
283 {
284 /* Where to show the message? */
285 TileIndex tile{};
286 if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args)>>) {
287 tile = std::get<0>(args);
288 }
289
290 return InternalPost(err_message, callback, my_cmd, network_command, tile, std::move(args));
291 }
292
293 template <typename Tcallback>
294 static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple<Targs...> args)
295 {
296 /* Do not even think about executing out-of-bounds tile-commands. */
297 if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (GetCommandFlags<Tcmd>() & CMD_ALL_TILES) == 0))) return false;
298
299 auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags<Tcmd>(), tile, err_message, network_command);
300 if (err) return false;
301
302 /* Only set client IDs when the command does not come from the network. */
303 if (!network_command && GetCommandFlags<Tcmd>() & CMD_CLIENT_ID) SetClientIds(args, std::index_sequence_for<Targs...>{});
304
305 Tret res = Execute(err_message, reinterpret_cast<CommandCallback *>(callback), my_cmd, estimate_only, network_command, tile, args);
306 InternalPostResult(ExtractCommandCost(res), tile, estimate_only, only_sending, err_message, my_cmd);
307
308 if (!estimate_only && !only_sending && callback != nullptr) {
309 if constexpr (std::is_same_v<Tcallback, CommandCallback>) {
310 /* Callback that doesn't need any command arguments. */
311 callback(Tcmd, ExtractCommandCost(res), tile);
312 } else if constexpr (std::is_same_v<Tcallback, CommandCallbackData>) {
313 /* Generic callback that takes packed arguments as a buffer. */
314 if constexpr (std::is_same_v<Tret, CommandCost>) {
315 callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), {});
316 } else {
317 callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), EndianBufferWriter<CommandDataBuffer>::FromValue(RemoveFirstTupleElement(res)));
318 }
319 } else if constexpr (!std::is_same_v<Tret, CommandCost> && std::is_same_v<Tcallback *, typename CommandTraits<Tcmd>::RetCallbackProc>) {
320 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res));
321 } else {
322 /* Callback with arguments. We assume that the tile is only interesting if it actually is in the command arguments. */
323 if constexpr (std::is_same_v<Tret, CommandCost>) {
324 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd, res), args));
325 } else {
326 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res, args));
327 }
328 }
329 }
330
331 return ExtractCommandCost(res).Succeeded();
332 }
333
335 template <class T>
336 static inline bool ClientIdIsSet(T &data)
337 {
338 if constexpr (std::is_same_v<ClientID, T>) {
339 return data != INVALID_CLIENT_ID;
340 } else {
341 return true;
342 }
343 }
344
346 template<class Ttuple, size_t... Tindices>
347 static inline bool AllClientIdsSet(Ttuple &values, std::index_sequence<Tindices...>)
348 {
349 return (ClientIdIsSet(std::get<Tindices>(values)) && ...);
350 }
351
352 template<class Ttuple>
353 static inline Money ExtractAdditionalMoney(Ttuple &values)
354 {
355 if constexpr (std::is_same_v<std::tuple_element_t<1, Tret>, Money>) {
356 return std::get<1>(values);
357 } else {
358 return {};
359 }
360 }
361
362 static Tret Execute(StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, std::tuple<Targs...> args)
363 {
364 /* Prevent recursion; it gives a mess over the network */
365 RecursiveCommandCounter counter{};
366 assert(counter.IsTopLevel());
367
368 /* Command flags are used internally */
369 constexpr CommandFlags cmd_flags = GetCommandFlags<Tcmd>();
370
371 if constexpr ((cmd_flags & CMD_CLIENT_ID) != 0) {
372 /* Make sure arguments are properly set to a ClientID also when processing external commands. */
373 assert(AllClientIdsSet(args, std::index_sequence_for<Targs...>{}));
374 }
375
376 Backup<CompanyID> cur_company(_current_company, FILE_LINE);
377 if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) {
378 cur_company.Trash();
379 return MakeResult(CMD_ERROR);
380 }
381
382 /* Test the command. */
383 DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags);
384 Tret res = std::apply(CommandTraits<Tcmd>::proc, std::tuple_cat(std::make_tuple(flags), args));
385
386 auto [exit_test, desync_log, send_net] = InternalExecuteValidateTestAndPrepExec(ExtractCommandCost(res), cmd_flags, estimate_only, network_command, cur_company);
387 if (exit_test) {
388 if (desync_log) LogCommandExecution(Tcmd, err_message, tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args), true);
389 cur_company.Restore();
390 return res;
391 }
392
393 /* If we are in network, and the command is not from the network
394 * send it to the command-queue and abort execution. */
395 if (send_net) {
396 ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, EndianBufferWriter<CommandDataBuffer>::FromValue(args));
397 cur_company.Restore();
398
399 /* Don't return anything special here; no error, no costs.
400 * This way it's not handled by DoCommand and only the
401 * actual execution of the command causes messages. Also
402 * reset the storages as we've not executed the command. */
403 return {};
404 }
405
406 if (desync_log) LogCommandExecution(Tcmd, err_message, tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args), false);
407
408 /* Actually try and execute the command. */
409 Tret res2 = std::apply(CommandTraits<Tcmd>::proc, std::tuple_cat(std::make_tuple(flags | DC_EXEC), args));
410
411 /* Convention: If the second result element is of type Money,
412 * this is the additional cash required for the command. */
413 Money additional_money{};
414 if constexpr (!std::is_same_v<Tret, CommandCost>) { // No short-circuiting for 'if constexpr'.
415 additional_money = ExtractAdditionalMoney(res2);
416 }
417
418 if constexpr (std::is_same_v<Tret, CommandCost>) {
419 return InternalExecuteProcessResult(Tcmd, cmd_flags, res, res2, additional_money, tile, cur_company);
420 } else {
421 std::get<0>(res2) = InternalExecuteProcessResult(Tcmd, cmd_flags, ExtractCommandCost(res), ExtractCommandCost(res2), additional_money, tile, cur_company);
422 return res2;
423 }
424 }
425 };
426
434 template <Commands Tcmd, typename Tret, typename... Targs>
435 struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), false> : CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true>
436 {
437 /* Do not allow Post without explicit location. */
438 static inline bool Post(StringID err_message, Targs... args) = delete;
439 template <typename Tcallback>
440 static inline bool Post(Tcallback *callback, Targs... args) = delete;
441 static inline bool Post(Targs... args) = delete;
442 template <typename Tcallback>
443 static bool Post(StringID err_message, Tcallback *callback, Targs... args) = delete;
444
451 static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post<CommandCallback>(err_message, nullptr, location, std::forward<Targs>(args)...); }
458 template <typename Tcallback>
459 static inline bool Post(Tcallback *callback, TileIndex location, Targs... args) { return Post((StringID)0, callback, location, std::forward<Targs>(args)...); }
465 static inline bool Post(TileIndex location, Targs... args) { return Post<CommandCallback>((StringID)0, nullptr, location, std::forward<Targs>(args)...); }
466
475 template <typename Tcallback>
476 static inline bool Post(StringID err_message, Tcallback *callback, TileIndex location, Targs... args)
477 {
478 return CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true>::InternalPost(err_message, callback, true, false, location, std::forward_as_tuple(args...));
479 }
480 };
481
482 #ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
483 # pragma GCC diagnostic pop
484 #endif
485
486 template <Commands Tcmd>
487 using Command = CommandHelper<Tcmd, typename CommandTraits<Tcmd>::ProcType, (GetCommandFlags<Tcmd>() & CMD_LOCATION) == 0>;
488
489 #endif /* COMMAND_FUNC_H */
SetClientIdHelper
static void SetClientIdHelper(T &data, [[maybe_unused]] ClientID client_id)
Helper to process a single ClientID argument.
Definition: network_command.cpp:461
GetCommandName
const char * GetCommandName(Commands cmd)
Definition: command.cpp:134
GetCommandFlags
CommandFlags GetCommandFlags(Commands cmd)
Definition: command.cpp:120
INVALID_CLIENT_ID
@ INVALID_CLIENT_ID
Client is not part of anything.
Definition: network_type.h:48
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), false >::Post
static bool Post(TileIndex location, Targs... args)
Shortcut for Post when not using a callback or an error message.
Definition: command_func.h:465
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:28
Commands
Commands
List of commands.
Definition: command_type.h:176
IsCommandAllowedWhilePaused
bool IsCommandAllowedWhilePaused(Commands cmd)
Returns whether the command is allowed while the game is paused.
Definition: command.cpp:146
CommandDataBuffer
std::vector< byte > CommandDataBuffer
Storage buffer for serialized command data.
Definition: command_type.h:451
IsValidCommand
bool IsValidCommand(Commands cmd)
Definition: command.cpp:108
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
CommandFlagsToDCFlags
static constexpr DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
Definition: command_func.h:59
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::MakeResult
static Tret MakeResult(const CommandCost &cost)
Make a command proc result from a CommandCost.
Definition: command_func.h:129
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::SetClientIds
static void SetClientIds(Ttuple &values, std::index_sequence< Tindices... >)
Set all invalid ClientID's to the proper value.
Definition: command_func.h:269
CMD_LOCATION
@ CMD_LOCATION
the command has implicit location argument.
Definition: command_type.h:389
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::AllClientIdsSet
static bool AllClientIdsSet(Ttuple &values, std::index_sequence< Tindices... >)
Check if all ClientID arguments are set to valid values.
Definition: command_func.h:347
CommandHelperBase::InternalExecuteValidateTestAndPrepExec
static std::tuple< bool, bool, bool > InternalExecuteValidateTestAndPrepExec(CommandCost &res, CommandFlags cmd_flags, bool estimate_only, bool network_command, Backup< CompanyID > &cur_company)
Validate result of test run and prepare for real execution.
Definition: command.cpp:319
TileIndex
The index/ID of a Tile.
Definition: tile_type.h:85
CommandHelperBase::InternalDoBefore
static void InternalDoBefore(bool top_level, bool test)
Prepare for calling a command proc.
Definition: command.cpp:186
DC_NO_WATER
@ DC_NO_WATER
don't allow building on water
Definition: command_type.h:360
DC_ALL_TILES
@ DC_ALL_TILES
allow this command also on MP_VOID tiles
Definition: command_type.h:366
CommandCallback
void CommandCallback(Commands cmd, const CommandCost &result, TileIndex tile)
Define a callback function for the client, after the command is finished.
Definition: command_type.h:465
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
DC_EXEC
@ DC_EXEC
execute the given command
Definition: command_type.h:357
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:355
CommandTraits
Defines the traits of a command.
Definition: command_type.h:434
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::RemoveFirstTupleElement
static Tt< Ts... > RemoveFirstTupleElement(const Tt< T1, Ts... > &tuple)
Remove the first element of a tuple.
Definition: command_func.h:276
endian_buffer.hpp
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), false >::Post
static bool Post(StringID err_message, Tcallback *callback, TileIndex location, Targs... args)
Post variant that takes a TileIndex (for error window location and text effects) for commands that do...
Definition: command_func.h:476
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Post
static bool Post(StringID err_message, Targs... args)
Shortcut for the long Post when not using a callback.
Definition: command_func.h:183
CommandFlags
CommandFlags
Command flags for the command table _command_proc_table.
Definition: command_type.h:377
tile_map.h
MapSize
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
CommandHelperBase::InternalExecutePrepTest
static bool InternalExecutePrepTest(CommandFlags cmd_flags, TileIndex tile, Backup< CompanyID > &cur_company)
Prepare for the test run of a command proc call.
Definition: command.cpp:289
CommandCost
Common return value for all commands.
Definition: command_type.h:24
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::SendNet
static void SendNet(StringID err_message, CompanyID company, Targs... args)
Prepare a command to be send over the network.
Definition: command_func.h:234
CMD_AUTO
@ CMD_AUTO
set the DC_AUTO flag on this command
Definition: command_type.h:381
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::ClientIdIsSet
static bool ClientIdIsSet(T &data)
Helper to process a single ClientID argument.
Definition: command_func.h:336
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Post
static bool Post(StringID err_message, Tcallback *callback, Targs... args)
Top-level network safe command execution for the current company.
Definition: command_func.h:208
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), false >::Post
static bool Post(StringID err_message, TileIndex location, Targs... args)
Shortcut for Post when not using an error message.
Definition: command_func.h:451
CMD_CLIENT_ID
@ CMD_CLIENT_ID
set p2 with the ClientID of the sending client.
Definition: command_type.h:385
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::ExtractCommandCost
static CommandCost & ExtractCommandCost(Tret &ret)
Extract the CommandCost from a command proc result.
Definition: command_func.h:119
IsValidTile
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:161
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition: network_type.h:49
CommandHelperBase::InternalDoAfter
static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test)
Process result after calling a command proc.
Definition: command.cpp:199
CommandHelperBase::InternalPostBefore
static std::tuple< bool, bool, bool > InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command)
Decide what to do with the command depending on current game state.
Definition: command.cpp:224
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Unsafe
static Tret Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple< Targs... > args)
Top-level network safe command execution without safety checks.
Definition: command_func.h:252
RecursiveCommandCounter::IsTopLevel
bool IsTopLevel() const
Are we in the top-level command execution?
Definition: command_func.h:74
command_type.h
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), false >::Post
static bool Post(Tcallback *callback, TileIndex location, Targs... args)
Shortcut for Post when not using a callback.
Definition: command_func.h:459
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Do
static Tret Do(DoCommandFlag flags, Targs... args)
This function executes a given command with the parameters from the #CommandProc parameter list.
Definition: command_func.h:150
CommandHelperBase::InternalPostResult
static void InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd)
Process result of executing a command, possibly displaying any error to the player.
Definition: command.cpp:254
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
CommandHelperBase::InternalExecuteProcessResult
static CommandCost InternalExecuteProcessResult(Commands cmd, CommandFlags cmd_flags, const CommandCost &res_test, const CommandCost &res_exec, Money extra_cash, TileIndex tile, Backup< CompanyID > &cur_company)
Process the result of a command test run and execution run.
Definition: command.cpp:359
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
CMD_NO_WATER
@ CMD_NO_WATER
set the DC_NO_WATER flag on this command
Definition: command_type.h:384
NetworkSendCommand
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data)
Prepare a DoCommand to be send over the network.
Definition: network_command.cpp:266
CMD_ALL_TILES
@ CMD_ALL_TILES
allow this command also on MP_VOID tiles
Definition: command_type.h:382
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::SetClientIdHelper
static void SetClientIdHelper(T &data)
Helper to process a single ClientID argument.
Definition: command_func.h:260
CommandHelperBase::LogCommandExecution
static void LogCommandExecution(Commands cmd, StringID err_message, TileIndex tile, const CommandDataBuffer &args, bool failed)
Helper to make a desync log for a command.
Definition: command.cpp:277
DC_AUTO
@ DC_AUTO
don't allow building on structures
Definition: command_type.h:358
company_func.h
CommandHelper
Definition: command_func.h:94
OverflowSafeInt< int64 >
GetAvailableMoneyForCommand
Money GetAvailableMoneyForCommand()
Definition: command.cpp:173
EndianBufferWriter
Endian-aware buffer adapter that always writes values in little endian order.
Definition: endian_buffer.hpp:28
DC_NONE
@ DC_NONE
no flag is set
Definition: command_type.h:356
CommandHelperBase
Definition: command_func.h:96
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Post
static bool Post(Tcallback *callback, Targs... args)
Shortcut for the long Post when not using an error message.
Definition: command_func.h:190
company_type.h
RecursiveCommandCounter
Helper class to keep track of command nesting level.
Definition: command_func.h:69
SetClientIds
static void SetClientIds(Ttuple &values, ClientID client_id, std::index_sequence< Tindices... >)
Set all invalid ClientID's to the proper value.
Definition: network_command.cpp:470
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::Post
static bool Post(Targs... args)
Shortcut for the long Post when not using a callback or an error message.
Definition: command_func.h:195
network_type.h
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:17
CommandHelper< Tcmd, Tret(*)(DoCommandFlag, Targs...), true >::PostFromNet
static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, std::tuple< Targs... > args)
Execute a command coming from the network.
Definition: command_func.h:222
backup_type.hpp