OpenTTD Source: src/command_func.h Source File

OpenTTD Source 15.0-RC2

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
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
30void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data);
31
32bool IsValidCommand(Commands cmd);
33 CommandFlags GetCommandFlags(Commands cmd);
34std::string_view GetCommandName(Commands cmd);
35bool IsCommandAllowedWhilePaused(Commands cmd);
36
37template <Commands Tcmd>
38constexpr CommandFlags GetCommandFlags()
39{
40 return CommandTraits<Tcmd>::flags;
41}
42
48 static constexpr inline DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
49{
50 DoCommandFlags flags = {};
51 if (cmd_flags.Test(CommandFlag::NoWater)) flags.Set(DoCommandFlag::NoWater);
52 if (cmd_flags.Test(CommandFlag::Auto)) flags.Set(DoCommandFlag::Auto);
53 if (cmd_flags.Test(CommandFlag::AllTiles)) flags.Set(DoCommandFlag::AllTiles);
54 return flags;
55}
56
58 struct RecursiveCommandCounter {
59 RecursiveCommandCounter() noexcept { _counter++; }
60 ~RecursiveCommandCounter() noexcept { _counter--; }
61
63 bool IsTopLevel() const { return _counter == 1; }
64private:
65 static int _counter;
66};
67
68#if defined(__GNUC__) && !defined(__clang__)
69/*
70 * We cast specialized function pointers to a generic one, but don't use the
71 * converted value to call the function, which is safe, except that GCC
72 * helpfully thinks it is not.
73 *
74 * "Any pointer to function can be converted to a pointer to a different function type.
75 * Calling the function through a pointer to a different function type is undefined,
76 * but converting such pointer back to pointer to the original function type yields
77 * the pointer to the original function." */
78# pragma GCC diagnostic push
79# pragma GCC diagnostic ignored "-Wcast-function-type"
80# define SILENCE_GCC_FUNCTION_POINTER_CAST
81#endif
82
83 template <Commands TCmd, typename T, bool THasTile> struct CommandHelper;
84
85 class CommandHelperBase {
86protected:
87 static void InternalDoBefore(bool top_level, bool test);
88 static void InternalDoAfter(CommandCost &res, DoCommandFlags flags, bool top_level, bool test);
89 static std::tuple<bool, bool, bool> InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command);
90 static void InternalPostResult(CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd);
91 static bool InternalExecutePrepTest(CommandFlags cmd_flags, TileIndex tile, Backup<CompanyID> &cur_company);
92 static std::tuple<bool, bool, bool> InternalExecuteValidateTestAndPrepExec(CommandCost &res, CommandFlags cmd_flags, bool estimate_only, bool network_command, Backup<CompanyID> &cur_company);
93 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);
94 static void LogCommandExecution(Commands cmd, StringID err_message, const CommandDataBuffer &args, bool failed);
95};
96
104template <Commands Tcmd, typename Tret, typename... Targs>
105 struct CommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...), true> : protected CommandHelperBase {
106private:
108 static inline CommandCost &ExtractCommandCost(Tret &ret)
109 {
110 if constexpr (std::is_same_v<Tret, CommandCost>) {
111 return ret;
112 } else {
113 return std::get<0>(ret);
114 }
115 }
116
118 static inline Tret MakeResult(const CommandCost &cost)
119 {
120 Tret ret{};
121 ExtractCommandCost(ret) = cost;
122 return ret;
123 }
124
125public:
139 static Tret Do(DoCommandFlags flags, Targs... args)
140 {
141 if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, std::tuple<Targs...>>>) {
142 /* Do not even think about executing out-of-bounds tile-commands. */
143 TileIndex tile = std::get<0>(std::make_tuple(args...));
144 if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && !flags.Test(DoCommandFlag::AllTiles)))) return MakeResult(CMD_ERROR);
145 }
146
147 RecursiveCommandCounter counter{};
148
149 /* Only execute the test call if it's toplevel, or we're not execing. */
150 if (counter.IsTopLevel() || !flags.Test(DoCommandFlag::Execute)) {
151 InternalDoBefore(counter.IsTopLevel(), true);
152 Tret res = CommandTraits<Tcmd>::proc(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), args...);
153 InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), true); // Can modify res.
154
155 if (ExtractCommandCost(res).Failed() || !flags.Test(DoCommandFlag::Execute)) return res;
156 }
157
158 /* Execute the command here. All cost-relevant functions set the expenses type
159 * themselves to the cost object at some point. */
160 InternalDoBefore(counter.IsTopLevel(), false);
161 Tret res = CommandTraits<Tcmd>::proc(flags, args...);
162 InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), false);
163
164 return res;
165 }
166
172 static inline bool Post(StringID err_message, Targs... args) { return Post<CommandCallback>(err_message, nullptr, std::forward<Targs>(args)...); }
178 template <typename Tcallback>
179 static inline bool Post(Tcallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward<Targs>(args)...); }
184 static inline bool Post(Targs... args) { return Post<CommandCallback>((StringID)0, nullptr, std::forward<Targs>(args)...); }
185
196 template <typename Tcallback>
197 static bool Post(StringID err_message, Tcallback *callback, Targs... args)
198 {
199 return InternalPost(err_message, callback, true, false, std::forward_as_tuple(args...));
200 }
201
210 template <typename Tcallback>
211 static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, std::tuple<Targs...> args)
212 {
213 return InternalPost(err_message, callback, my_cmd, true, std::move(args));
214 }
215
223 static void SendNet(StringID err_message, CompanyID company, Targs... args)
224 {
225 auto args_tuple = std::forward_as_tuple(args...);
226
227 ::NetworkSendCommand(Tcmd, err_message, nullptr, company, EndianBufferWriter<CommandDataBuffer>::FromValue(args_tuple));
228 }
229
240 template <typename Tcallback>
241 static Tret Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple<Targs...> args)
242 {
243 return Execute(err_message, reinterpret_cast<CommandCallback *>(reinterpret_cast<void(*)()>(callback)), my_cmd, estimate_only, false, location, std::move(args));
244 }
245
246protected:
248 template <class T>
249 static inline void SetClientIdHelper([[maybe_unused]] T &data)
250 {
251 if constexpr (std::is_same_v<ClientID, T>) {
252 if (data == INVALID_CLIENT_ID) data = CLIENT_ID_SERVER;
253 }
254 }
255
257 template <class Ttuple, size_t... Tindices>
258 static inline void SetClientIds(Ttuple &values, std::index_sequence<Tindices...>)
259 {
260 ((SetClientIdHelper(std::get<Tindices>(values))), ...);
261 }
262
264 template <template <typename...> typename Tt, typename T1, typename... Ts>
265 static inline Tt<Ts...> RemoveFirstTupleElement(const Tt<T1, Ts...> &tuple)
266 {
267 return std::apply([](auto &&, const auto&... args) { return std::tie(args...); }, tuple);
268 }
269
270 template <typename Tcallback>
271 static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, std::tuple<Targs...> args)
272 {
273 /* Where to show the message? */
274 TileIndex tile{};
275 if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args)>>) {
276 tile = std::get<0>(args);
277 }
278
279 return InternalPost(err_message, callback, my_cmd, network_command, tile, std::move(args));
280 }
281
282 template <typename Tcallback>
283 static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple<Targs...> args)
284 {
285 /* Do not even think about executing out-of-bounds tile-commands. */
286 if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && !GetCommandFlags<Tcmd>().Test(CommandFlag::AllTiles)))) return false;
287
288 auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags<Tcmd>(), tile, err_message, network_command);
289 if (err) return false;
290
291 /* Only set client IDs when the command does not come from the network. */
292 if (!network_command && GetCommandFlags<Tcmd>().Test(CommandFlag::ClientID)) SetClientIds(args, std::index_sequence_for<Targs...>{});
293
294 Tret res = Execute(err_message, reinterpret_cast<CommandCallback *>(reinterpret_cast<void(*)()>(callback)), my_cmd, estimate_only, network_command, tile, args);
295 InternalPostResult(ExtractCommandCost(res), tile, estimate_only, only_sending, err_message, my_cmd);
296
297 if (!estimate_only && !only_sending && callback != nullptr) {
298 if constexpr (std::is_same_v<Tcallback, CommandCallback>) {
299 /* Callback that doesn't need any command arguments. */
300 callback(Tcmd, ExtractCommandCost(res), tile);
301 } else if constexpr (std::is_same_v<Tcallback, CommandCallbackData>) {
302 /* Generic callback that takes packed arguments as a buffer. */
303 if constexpr (std::is_same_v<Tret, CommandCost>) {
304 callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), {});
305 } else {
306 callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), EndianBufferWriter<CommandDataBuffer>::FromValue(RemoveFirstTupleElement(res)));
307 }
308 } else if constexpr (!std::is_same_v<Tret, CommandCost> && std::is_same_v<Tcallback *, typename CommandTraits<Tcmd>::RetCallbackProc>) {
309 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res));
310 } else {
311 /* Callback with arguments. We assume that the tile is only interesting if it actually is in the command arguments. */
312 if constexpr (std::is_same_v<Tret, CommandCost>) {
313 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd, res), args));
314 } else {
315 std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res, args));
316 }
317 }
318 }
319
320 return ExtractCommandCost(res).Succeeded();
321 }
322
324 template <class T>
325 static inline bool ClientIdIsSet([[maybe_unused]] T &data)
326 {
327 if constexpr (std::is_same_v<ClientID, T>) {
328 return data != INVALID_CLIENT_ID;
329 } else {
330 return true;
331 }
332 }
333
335 template <class Ttuple, size_t... Tindices>
336 static inline bool AllClientIdsSet(Ttuple &values, std::index_sequence<Tindices...>)
337 {
338 return (ClientIdIsSet(std::get<Tindices>(values)) && ...);
339 }
340
341 template <class Ttuple>
342 static inline Money ExtractAdditionalMoney([[maybe_unused]] Ttuple &values)
343 {
344 if constexpr (std::is_same_v<std::tuple_element_t<1, Tret>, Money>) {
345 return std::get<1>(values);
346 } else {
347 return {};
348 }
349 }
350
351 static Tret Execute(StringID err_message, CommandCallback *callback, bool, bool estimate_only, bool network_command, TileIndex tile, std::tuple<Targs...> args)
352 {
353 /* Prevent recursion; it gives a mess over the network */
354 RecursiveCommandCounter counter{};
355 assert(counter.IsTopLevel());
356
357 /* Command flags are used internally */
358 constexpr CommandFlags cmd_flags = GetCommandFlags<Tcmd>();
359
360 if constexpr (cmd_flags.Test(CommandFlag::ClientID)) {
361 /* Make sure arguments are properly set to a ClientID also when processing external commands. */
362 assert(AllClientIdsSet(args, std::index_sequence_for<Targs...>{}));
363 }
364
365 Backup<CompanyID> cur_company(_current_company);
366 if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) {
367 cur_company.Trash();
368 return MakeResult(CMD_ERROR);
369 }
370
371 /* Test the command. */
372 DoCommandFlags flags = CommandFlagsToDCFlags(cmd_flags);
373 Tret res = std::apply(CommandTraits<Tcmd>::proc, std::tuple_cat(std::make_tuple(flags), args));
374
375 auto [exit_test, desync_log, send_net] = InternalExecuteValidateTestAndPrepExec(ExtractCommandCost(res), cmd_flags, estimate_only, network_command, cur_company);
376 if (exit_test) {
377 if (desync_log) LogCommandExecution(Tcmd, err_message, EndianBufferWriter<CommandDataBuffer>::FromValue(args), true);
378 cur_company.Restore();
379 return res;
380 }
381
382 /* If we are in network, and the command is not from the network
383 * send it to the command-queue and abort execution. */
384 if (send_net) {
385 ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, EndianBufferWriter<CommandDataBuffer>::FromValue(args));
386 cur_company.Restore();
387
388 /* Don't return anything special here; no error, no costs.
389 * This way it's not handled by DoCommand and only the
390 * actual execution of the command causes messages. Also
391 * reset the storages as we've not executed the command. */
392 return {};
393 }
394
395 if (desync_log) LogCommandExecution(Tcmd, err_message, EndianBufferWriter<CommandDataBuffer>::FromValue(args), false);
396
397 /* Actually try and execute the command. */
398 Tret res2 = std::apply(CommandTraits<Tcmd>::proc, std::tuple_cat(std::make_tuple(flags | DoCommandFlag::Execute), args));
399
400 /* Convention: If the second result element is of type Money,
401 * this is the additional cash required for the command. */
402 Money additional_money{};
403 if constexpr (!std::is_same_v<Tret, CommandCost>) { // No short-circuiting for 'if constexpr'.
404 additional_money = ExtractAdditionalMoney(res2);
405 }
406
407 if constexpr (std::is_same_v<Tret, CommandCost>) {
408 return InternalExecuteProcessResult(Tcmd, cmd_flags, res, res2, additional_money, tile, cur_company);
409 } else {
410 std::get<0>(res2) = InternalExecuteProcessResult(Tcmd, cmd_flags, ExtractCommandCost(res), ExtractCommandCost(res2), additional_money, tile, cur_company);
411 return res2;
412 }
413 }
414};
415
423template <Commands Tcmd, typename Tret, typename... Targs>
424 struct CommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...), false> : CommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...), true>
425{
426 /* Do not allow Post without explicit location. */
427 static inline bool Post(StringID err_message, Targs... args) = delete;
428 template <typename Tcallback>
429 static inline bool Post(Tcallback *callback, Targs... args) = delete;
430 static inline bool Post(Targs... args) = delete;
431 template <typename Tcallback>
432 static bool Post(StringID err_message, Tcallback *callback, Targs... args) = delete;
433
440 static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post<CommandCallback>(err_message, nullptr, location, std::forward<Targs>(args)...); }
447 template <typename Tcallback>
448 static inline bool Post(Tcallback *callback, TileIndex location, Targs... args) { return Post((StringID)0, callback, location, std::forward<Targs>(args)...); }
454 static inline bool Post(TileIndex location, Targs... args) { return Post<CommandCallback>((StringID)0, nullptr, location, std::forward<Targs>(args)...); }
455
464 template <typename Tcallback>
465 static inline bool Post(StringID err_message, Tcallback *callback, TileIndex location, Targs... args)
466 {
467 return CommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...), true>::InternalPost(err_message, callback, true, false, location, std::forward_as_tuple(args...));
468 }
469};
470
471#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
472# pragma GCC diagnostic pop
473#endif
474
475template <Commands Tcmd>
476using Command = CommandHelper<Tcmd, typename CommandTraits<Tcmd>::ProcType, !GetCommandFlags<Tcmd>().Test(CommandFlag::Location)>;
477
478#endif /* COMMAND_FUNC_H */
backup_type.hpp
Class for backupping variables and making sure they are restored later.
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandHelperBase
Definition command_func.h:85
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:207
CommandHelperBase::InternalPostResult
static void InternalPostResult(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:238
CommandHelperBase::InternalDoBefore
static void InternalDoBefore(bool top_level, bool test)
Prepare for calling a command proc.
Definition command.cpp:169
CommandHelperBase::LogCommandExecution
static void LogCommandExecution(Commands cmd, StringID err_message, const CommandDataBuffer &args, bool failed)
Helper to make a desync log for a command.
Definition command.cpp:261
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:342
CommandHelperBase::InternalDoAfter
static void InternalDoAfter(CommandCost &res, DoCommandFlags flags, bool top_level, bool test)
Process result after calling a command proc.
Definition command.cpp:182
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:302
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:272
EndianBufferWriter
Endian-aware buffer adapter that always writes values in little endian order.
Definition endian_buffer.hpp:24
EnumBitSet< CommandFlag, uint16_t >
OverflowSafeInt< int64_t >
GetCommandFlags
CommandFlags GetCommandFlags(Commands cmd)
This function mask the parameter with CMD_ID_MASK and returns the flags which belongs to the given co...
Definition command.cpp:118
IsCommandAllowedWhilePaused
bool IsCommandAllowedWhilePaused(Commands cmd)
Returns whether the command is allowed while the game is paused.
Definition command.cpp:144
CommandFlagsToDCFlags
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
Definition command_func.h:48
GetCommandName
std::string_view GetCommandName(Commands cmd)
This function mask the parameter with CMD_ID_MASK and returns the name which belongs to the given com...
Definition command.cpp:132
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition command_func.h:28
IsValidCommand
bool IsValidCommand(Commands cmd)
This function range-checks a cmd.
Definition command.cpp:106
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:195
command_type.h
Types related to commands.
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:495
DoCommandFlag::Auto
@ Auto
don't allow building on structures
DoCommandFlag::NoWater
@ NoWater
don't allow building on water
DoCommandFlag::Execute
@ Execute
execute the given command
DoCommandFlag::AllTiles
@ AllTiles
allow this command also on MP_VOID tiles
CommandFlag::Auto
@ Auto
set the DoCommandFlag::Auto flag on this command
CommandFlag::NoWater
@ NoWater
set the DoCommandFlag::NoWater flag on this command
CommandFlag::AllTiles
@ AllTiles
allow this command also on MP_VOID tiles
CommandFlag::ClientID
@ ClientID
set p2 with the ClientID of the sending client.
CommandFlag::Location
@ Location
the command has implicit location argument.
CommandDataBuffer
std::vector< uint8_t > CommandDataBuffer
Storage buffer for serialized command data.
Definition command_type.h:481
Commands
Commands
List of commands.
Definition command_type.h:196
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
company_type.h
Types related to companies.
endian_buffer.hpp
Endian-aware buffer.
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:409
SetClientIdHelper
static void SetClientIdHelper(T &data, ClientID client_id)
Helper to process a single ClientID argument.
Definition network_command.cpp:400
network_type.h
Types used for networking.
INVALID_CLIENT_ID
@ INVALID_CLIENT_ID
Client is not part of anything.
Definition network_type.h:44
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition network_type.h:45
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
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:20
Backup
Class to backup a specific variable and restore it later.
Definition backup_type.hpp:21
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:454
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:465
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), false >::Post
static bool Post(StringID err_message, TileIndex location, Targs... args)
Shortcut for Post when not using a callback.
Definition command_func.h:440
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), false >::Post
static bool Post(Tcallback *callback, TileIndex location, Targs... args)
Shortcut for Post when not using an error message.
Definition command_func.h:448
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:197
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::Do
static Tret Do(DoCommandFlags flags, Targs... args)
This function executes a given command with the parameters from the #CommandProc parameter list.
Definition command_func.h:139
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::ClientIdIsSet
static bool ClientIdIsSet(T &data)
Helper to process a single ClientID argument.
Definition command_func.h:325
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:172
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::SetClientIdHelper
static void SetClientIdHelper(T &data)
Helper to process a single ClientID argument.
Definition command_func.h:249
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:211
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:241
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:223
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:179
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::RemoveFirstTupleElement
static Tt< Ts... > RemoveFirstTupleElement(const Tt< T1, Ts... > &tuple)
Remove the first element of a tuple.
Definition command_func.h:265
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::MakeResult
static Tret MakeResult(const CommandCost &cost)
Make a command proc result from a CommandCost.
Definition command_func.h:118
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:184
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:336
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, Targs...), true >::ExtractCommandCost
static CommandCost & ExtractCommandCost(Tret &ret)
Extract the CommandCost from a command proc result.
Definition command_func.h:108
CommandHelper< Tcmd, Tret(*)(DoCommandFlags, 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:258
CommandHelper
Definition command_func.h:83
CommandTraits
Defines the traits of a command.
Definition command_type.h:464
Map::Size
static uint Size()
Get the size of the map.
Definition map_func.h:290
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
RecursiveCommandCounter
Helper class to keep track of command nesting level.
Definition command_func.h:58
RecursiveCommandCounter::IsTopLevel
bool IsTopLevel() const
Are we in the top-level command execution?
Definition command_func.h:63
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
tile_map.h
Map writing/reading functions for tiles.
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
TileIndex
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:87