Command: Replace binary_length field with auxiliary data

Use for CMD_ADD_PLAN_LINE
pull/461/head
Jonathan G Rennison 2 years ago
parent b0329ec77a
commit f32733ef22

@ -12,6 +12,7 @@
#include "error.h"
#include "gui.h"
#include "command_func.h"
#include "command_aux.h"
#include "network/network_type.h"
#include "network/network.h"
#include "genworld.h"
@ -565,7 +566,7 @@ enum CommandLogEntryFlag : uint16 {
CLEF_ESTIMATE_ONLY = 0x08, ///< estimate only
CLEF_ONLY_SENDING = 0x10, ///< only sending
CLEF_MY_CMD = 0x20, ///< locally generated command
CLEF_BINARY = 0x40, ///< binary_length is > 0
CLEF_AUX_DATA = 0x40, ///< have auxiliary data
CLEF_SCRIPT = 0x80, ///< command run by AI/game script
CLEF_TWICE = 0x100, ///< command logged twice (only sending and execution)
CLEF_RANDOM = 0x200, ///< command changed random seed
@ -648,7 +649,7 @@ static void DumpSubCommandLog(char *&buffer, const char *last, const CommandLog
}
buffer += seprintf(buffer, last, " | %c%c%c%c%c%c%c%c%c%c%c | ",
fc(CLEF_ORDER_BACKUP, 'o'), fc(CLEF_RANDOM, 'r'), fc(CLEF_TWICE, '2'),
fc(CLEF_SCRIPT, 'a'), fc(CLEF_BINARY, 'b'), fc(CLEF_MY_CMD, 'm'), fc(CLEF_ONLY_SENDING, 's'),
fc(CLEF_SCRIPT, 'a'), fc(CLEF_AUX_DATA, 'b'), fc(CLEF_MY_CMD, 'm'), fc(CLEF_ONLY_SENDING, 's'),
fc(CLEF_ESTIMATE_ONLY, 'e'), fc(CLEF_TEXT, 't'), fc(CLEF_GENERATING_WORLD, 'g'), fc(CLEF_CMD_FAILED, 'f'));
buffer += seprintf(buffer, last, " %7d x %7d, p1: 0x%08X, p2: 0x%08X, ",
TileX(entry.tile), TileY(entry.tile), entry.p1, entry.p2);
@ -756,17 +757,15 @@ bool IsCommandAllowedWhilePaused(uint32 cmd)
static int _docommand_recursive = 0;
struct cmd_text_info_dumper {
const char *CommandTextInfo(const char *text, uint32 binary_length)
const char *CommandTextInfo(const char *text, const CommandAuxiliaryBase *aux_data)
{
char *b = this->buffer;
const char *last = lastof(this->buffer);
if (text) {
b += seprintf(b, last, ", text");
b += seprintf(b, last, ", text: length: %u", (uint) strlen(text));
}
if (binary_length) {
b += seprintf(b, last, ", bin length: %u", binary_length);
} else if (text) {
b += seprintf(b, last, ", str length: %u", (uint) strlen(text));
if (aux_data) {
b += seprintf(b, last, ", aux data");
}
return this->buffer;
}
@ -789,10 +788,10 @@ private:
* @see CommandProc
* @return the cost
*/
CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoCommandFlag flags, uint32 cmd, const char *text, uint32 binary_length)
CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoCommandFlag flags, uint32 cmd, const char *text, const CommandAuxiliaryBase *aux_data)
{
SCOPE_INFO_FMT([=], "DoCommand: tile: %X (%d x %d), p1: 0x%X, p2: 0x%X, p3: " OTTD_PRINTFHEX64 ", flags: 0x%X, company: %s, cmd: 0x%X (%s)%s",
tile, TileX(tile), TileY(tile), p1, p2, p3, flags, scope_dumper().CompanyInfo(_current_company), cmd, GetCommandName(cmd), cmd_text_info_dumper().CommandTextInfo(text, binary_length));
tile, TileX(tile), TileY(tile), p1, p2, p3, flags, scope_dumper().CompanyInfo(_current_company), cmd, GetCommandName(cmd), cmd_text_info_dumper().CommandTextInfo(text, aux_data));
CommandCost res;
@ -808,7 +807,7 @@ CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoComma
if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) {
if (_docommand_recursive == 1) _cleared_object_areas.clear();
SetTownRatingTestMode(true);
res = command.Execute(tile, flags & ~DC_EXEC, p1, p2, p3, text, binary_length);
res = command.Execute(tile, flags & ~DC_EXEC, p1, p2, p3, text, aux_data);
SetTownRatingTestMode(false);
if (res.Failed()) {
goto error;
@ -830,7 +829,7 @@ CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoComma
/* Execute the command here. All cost-relevant functions set the expenses type
* themselves to the cost object at some point */
if (_docommand_recursive == 1) _cleared_object_areas.clear();
res = command.Execute(tile, flags, p1, p2, p3, text, binary_length);
res = command.Execute(tile, flags, p1, p2, p3, text, aux_data);
if (res.Failed()) {
error:
_docommand_recursive--;
@ -909,10 +908,10 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
* @param binary_length The length of binary data in text
* @return \c true if the command succeeded, else \c false.
*/
bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, uint32 binary_length, bool my_cmd)
bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, const CommandAuxiliaryBase *aux_data, bool my_cmd)
{
SCOPE_INFO_FMT([=], "DoCommandP: tile: %X (%d x %d), p1: 0x%X, p2: 0x%X, p3: 0x" OTTD_PRINTFHEX64 ", company: %s, cmd: 0x%X (%s), my_cmd: %d%s",
tile, TileX(tile), TileY(tile), p1, p2, p3, scope_dumper().CompanyInfo(_current_company), cmd, GetCommandName(cmd), my_cmd, cmd_text_info_dumper().CommandTextInfo(text, binary_length));
tile, TileX(tile), TileY(tile), p1, p2, p3, scope_dumper().CompanyInfo(_current_company), cmd, GetCommandName(cmd), my_cmd, cmd_text_info_dumper().CommandTextInfo(text, aux_data));
/* Cost estimation is generally only done when the
* local user presses shift while doing something.
@ -945,15 +944,15 @@ bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, C
GameRandomSeedChecker random_state;
uint order_backup_update_counter = OrderBackup::GetUpdateCounter();
CommandCost res = DoCommandPInternal(tile, p1, p2, p3, cmd, callback, text, my_cmd, estimate_only, binary_length);
CommandCost res = DoCommandPInternal(tile, p1, p2, p3, cmd, callback, text, my_cmd, estimate_only, aux_data);
CommandLogEntryFlag log_flags;
log_flags = CLEF_NONE;
if (binary_length == 0 && !StrEmpty(text)) log_flags |= CLEF_TEXT;
if (!StrEmpty(text)) log_flags |= CLEF_TEXT;
if (estimate_only) log_flags |= CLEF_ESTIMATE_ONLY;
if (only_sending) log_flags |= CLEF_ONLY_SENDING;
if (my_cmd) log_flags |= CLEF_MY_CMD;
if (binary_length > 0) log_flags |= CLEF_BINARY;
if (aux_data != nullptr) log_flags |= CLEF_AUX_DATA;
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
if (order_backup_update_counter != OrderBackup::GetUpdateCounter()) log_flags |= CLEF_ORDER_BACKUP;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
@ -988,20 +987,20 @@ bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, C
return res.Succeeded();
}
CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length)
CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, const CommandAuxiliaryBase *aux_data)
{
GameRandomSeedChecker random_state;
uint order_backup_update_counter = OrderBackup::GetUpdateCounter();
CommandCost res = DoCommandPInternal(tile, p1, p2, p3, cmd, callback, text, my_cmd, estimate_only, binary_length);
CommandCost res = DoCommandPInternal(tile, p1, p2, p3, cmd, callback, text, my_cmd, estimate_only, aux_data);
CommandLogEntryFlag log_flags;
log_flags = CLEF_SCRIPT;
if (binary_length == 0 && !StrEmpty(text)) log_flags |= CLEF_TEXT;
if (!StrEmpty(text)) log_flags |= CLEF_TEXT;
if (estimate_only) log_flags |= CLEF_ESTIMATE_ONLY;
if (_networking && !(cmd & CMD_NETWORK_COMMAND)) log_flags |= CLEF_ONLY_SENDING;
if (my_cmd) log_flags |= CLEF_MY_CMD;
if (binary_length > 0) log_flags |= CLEF_BINARY;
if (aux_data != nullptr) log_flags |= CLEF_AUX_DATA;
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
if (order_backup_update_counter != OrderBackup::GetUpdateCounter()) log_flags |= CLEF_ORDER_BACKUP;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
@ -1063,7 +1062,7 @@ void EnqueueDoCommandP(CommandContainer cmd)
* @param estimate_only whether to give only the estimate or also execute the command
* @return the command cost of this function.
*/
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length)
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, const CommandAuxiliaryBase *aux_data)
{
/* Prevent recursion; it gives a mess over the network */
assert(_docommand_recursive == 0);
@ -1113,13 +1112,13 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3,
_cleared_object_areas.clear();
SetTownRatingTestMode(true);
BasePersistentStorageArray::SwitchMode(PSM_ENTER_TESTMODE);
CommandCost res = command.Execute(tile, flags, p1, p2, p3, text, binary_length);
CommandCost res = command.Execute(tile, flags, p1, p2, p3, text, aux_data);
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_TESTMODE);
SetTownRatingTestMode(false);
if (!random_state.Check()) {
std::string msg = stdstr_fmt("Random seed changed in test command: company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\" %X (%s)",
(int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, binary_length, GetCommandName(cmd));
std::string msg = stdstr_fmt("Random seed changed in test command: company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\"%s (%s)",
(int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, aux_data != nullptr ? ", aux data present" : "", GetCommandName(cmd));
DEBUG(desync, 0, "msg: date{%08x; %02x; %02x}; %s", _date, _date_fract, _tick_skip_counter, msg.c_str());
LogDesyncMsg(std::move(msg));
}
@ -1137,8 +1136,8 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3,
if (!_networking || _generating_world || (cmd & CMD_NETWORK_COMMAND) != 0) {
/* Log the failed command as well. Just to be able to be find
* causes of desyncs due to bad command test implementations. */
DEBUG(desync, 1, "cmdf: date{%08x; %02x; %02x}; company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\" %X (%s)",
_date, _date_fract, _tick_skip_counter, (int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, binary_length, GetCommandName(cmd));
DEBUG(desync, 1, "cmdf: date{%08x; %02x; %02x}; company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\"%s (%s)",
_date, _date_fract, _tick_skip_counter, (int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, aux_data != nullptr ? ", aux data present" : "", GetCommandName(cmd));
}
cur_company.Restore();
return_dcpi(res);
@ -1149,7 +1148,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3,
* send it to the command-queue and abort execution
*/
if (_networking && !_generating_world && !(cmd & CMD_NETWORK_COMMAND)) {
NetworkSendCommand(tile, p1, p2, p3, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company, binary_length);
NetworkSendCommand(tile, p1, p2, p3, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company, aux_data);
cur_company.Restore();
/* Don't return anything special here; no error, no costs.
@ -1158,14 +1157,14 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3,
* reset the storages as we've not executed the command. */
return_dcpi(CommandCost());
}
DEBUG(desync, 1, "cmd: date{%08x; %02x; %02x}; company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\" %X (%s)",
_date, _date_fract, _tick_skip_counter, (int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, binary_length, GetCommandName(cmd));
DEBUG(desync, 1, "cmd: date{%08x; %02x; %02x}; company: %02x; tile: %06x (%u x %u); p1: %08x; p2: %08x; p3: " OTTD_PRINTFHEX64PAD "; cmd: %08x; \"%s\"%s(%s)",
_date, _date_fract, _tick_skip_counter, (int)_current_company, tile, TileX(tile), TileY(tile), p1, p2, p3, cmd & ~CMD_NETWORK_COMMAND, text, aux_data != nullptr ? ", aux data present" : "", GetCommandName(cmd));
/* Actually try and execute the command. If no cost-type is given
* use the construction one */
_cleared_object_areas.clear();
BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND);
CommandCost res2 = command.Execute(tile, flags | DC_EXEC, p1, p2, p3, text, binary_length);
CommandCost res2 = command.Execute(tile, flags | DC_EXEC, p1, p2, p3, text, aux_data);
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND);
if (cmd_id == CMD_COMPANY_CTRL) {

@ -32,7 +32,7 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
*/
#define return_cmd_error(errcode) return CommandCost(errcode);
CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoCommandFlag flags, uint32 cmd, const char *text = nullptr, uint32 binary_length = 0);
CommandCost DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, DoCommandFlag flags, uint32 cmd, const char *text = nullptr, const CommandAuxiliaryBase *aux_data = nullptr);
inline CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = nullptr)
{
@ -40,10 +40,10 @@ inline CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag
}
inline CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
{
return DoCommandEx(container->tile, container->p1, container->p2, container->p3, flags, container->cmd & CMD_ID_MASK, container->text.c_str(), container->binary_length);
return DoCommandEx(container->tile, container->p1, container->p2, container->p3, flags, container->cmd & CMD_ID_MASK, container->text.c_str(), container->aux_data.get());
}
bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, uint32 binary_length, bool my_cmd = true);
bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, const CommandAuxiliaryBase *aux_data, bool my_cmd = true);
inline bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const char *text = nullptr, bool my_cmd = true)
{
@ -52,13 +52,13 @@ inline bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Command
inline bool DoCommandP(const CommandContainer *container, bool my_cmd = true)
{
return DoCommandPEx(container->tile, container->p1, container->p2, container->p3, container->cmd, container->callback, container->text.c_str(), container->binary_length, my_cmd);
return DoCommandPEx(container->tile, container->p1, container->p2, container->p3, container->cmd, container->callback, container->text.c_str(), container->aux_data.get(), my_cmd);
}
CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length);
CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, const CommandAuxiliaryBase *aux_data);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, const CommandAuxiliaryBase *aux_data);
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, uint32 binary_length);
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, const CommandAuxiliaryBase *aux_data);
extern Money _additional_cash_required;

@ -621,6 +621,8 @@ enum CommandPauseLevel {
CMDPL_ALL_ACTIONS, ///< All actions may be executed.
};
struct CommandAuxiliaryBase;
/**
* Defines the callback type for all command handler functions.
*
@ -640,7 +642,7 @@ enum CommandPauseLevel {
* @return The CommandCost of the command, which can be succeeded or failed.
*/
typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
typedef CommandCost CommandProcEx(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length);
typedef CommandCost CommandProcEx(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data);
/**
* Define a command with the flags which belongs to it.
@ -662,9 +664,9 @@ struct Command {
Command(CommandProcEx *procex, const char *name, CommandFlags flags, CommandType type)
: procex(procex), name(name), flags(flags | CMD_PROCEX), type(type) {}
inline CommandCost Execute(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length) const {
inline CommandCost Execute(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data) const {
if (this->flags & CMD_PROCEX) {
return this->procex(tile, flags, p1, p2, p3, text, binary_length);
return this->procex(tile, flags, p1, p2, p3, text, aux_data);
} else {
return this->proc(tile, flags, p1, p2, text);
}
@ -733,13 +735,13 @@ struct CommandContainer {
uint32 cmd; ///< command being executed.
uint64 p3; ///< parameter p3. (here for alignment)
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
uint32 binary_length; ///< in case text contains binary data, this describes its length.
std::string text; ///< possible text sent for name changes etc.
CommandAuxiliaryPtr aux_data; ///< Auxiliary command data
};
inline CommandContainer NewCommandContainerBasic(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr)
{
return { tile, p1, p2, cmd, 0, callback, 0, {} };
return { tile, p1, p2, cmd, 0, callback, {}, nullptr };
}
#endif /* COMMAND_TYPE_H */

@ -922,7 +922,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
/* In network games, we need to try setting the company manager face here to sync it to all clients.
* If a favorite company manager face is selected, choose it. Otherwise, use a random face. */
if (_company_manager_face != 0) NetworkSendCommand(0, 0, _company_manager_face, 0, CMD_SET_COMPANY_MANAGER_FACE, nullptr, nullptr, _local_company, 0);
if (_company_manager_face != 0) NetworkSendCommand(0, 0, _company_manager_face, 0, CMD_SET_COMPANY_MANAGER_FACE, nullptr, nullptr, _local_company, nullptr);
/* Now that we have a new company, broadcast our company settings to
* all clients so everything is in sync */

@ -190,7 +190,7 @@ CommandCost CmdCreateLeagueTable(TileIndex tile, DoCommandFlag flags, uint32 p1,
return res;
}
CommandCost CmdCreateLeagueTableElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdCreateLeagueTableElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
std::string text_str, score;
text = StrConsumeToSeparator(text_str, text);
@ -227,7 +227,7 @@ CommandCost CmdUpdateLeagueTableElementData(TileIndex tile, DoCommandFlag flags,
return CmdUpdateLeagueTableElementData(flags, element, company, text, link_type, link_target);
}
CommandCost CmdUpdateLeagueTableElementScore(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdUpdateLeagueTableElementScore(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
return CmdUpdateLeagueTableElementScore(flags, p1, p3, text);
}

@ -85,6 +85,13 @@ bool Packet::CanWriteToPacket(size_t bytes_to_write)
return this->Size() + bytes_to_write <= this->limit;
}
void Packet::WriteAtOffset_uint16(size_t offset, uint16 data)
{
assert(offset + 1 < this->buffer.size());
this->buffer[offset] = GB(data, 0, 8);
this->buffer[offset + 1] = GB(data, 8, 8);
}
/*

@ -72,7 +72,9 @@ public:
PacketSize &GetDeserialisationPosition() { return this->pos; }
bool CanDeserialiseBytes(size_t bytes_to_read, bool raise_error) { return this->CanReadFromPacket(bytes_to_read, raise_error); }
bool CanWriteToPacket(size_t bytes_to_write);
bool CanWriteToPacket(size_t bytes_to_write);
void WriteAtOffset_uint16(size_t offset, uint16);
/* Reading/receiving of packets */
size_t ReadRawPacketSize() const;

@ -1120,7 +1120,7 @@ void NetworkGameLoop()
while (f != nullptr && !feof(f)) {
if (_date == next_date && _date_fract == next_date_fract) {
if (cp != nullptr) {
NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->p3, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text.c_str(), cp->company, cp->binary_length);
NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->p3, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text.c_str(), cp->company, cp->aux_data);
DEBUG(net, 0, "injecting: date{%08x; %02x; %02x}; %02x; %06x; %08x; %08x; " OTTD_PRINTFHEX64PAD " %08x; \"%s\" (%x) (%s)", _date, _date_fract, _tick_skip_counter, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->p3, cp->cmd, cp->text.c_str(), cp->binary_length, GetCommandName(cp->cmd));
cp.reset();
}
@ -1167,7 +1167,7 @@ void NetworkGameLoop()
* string misses because in 99% of the time it's not used. */
assert(ret == 10 || ret == 9);
cp->company = (CompanyID)company;
cp->binary_length = 0;
cp->aux_data = nullptr;
} else if (strncmp(p, "join: ", 6) == 0) {
/* Manually insert a pause when joining; this way the client can join at the exact right time. */
int ret = sscanf(p + 6, "date{%x; %x; %x}", &next_date, &next_date_fract, &next_tick_skip_counter);
@ -1181,7 +1181,7 @@ void NetworkGameLoop()
cp->p2 = 1;
cp->p3 = 0;
cp->callback = nullptr;
cp->binary_length = 0;
cp->aux_data = nullptr;
_ddc_fastforward = false;
} else if (strncmp(p, "sync: ", 6) == 0) {
int ret = sscanf(p + 6, "date{%x; %x; %x}; %x; %x", &next_date, &next_date_fract, &next_tick_skip_counter, &sync_state[0], &sync_state[1]);

@ -1002,7 +1002,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
* the server will give us a client-id and let us in */
_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
ShowJoinStatusWindow();
NetworkSendCommand(0, CCA_NEW, 0, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company, 0);
NetworkSendCommand(0, CCA_NEW, 0, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company, nullptr);
}
} else {
/* take control over an existing company */

@ -12,6 +12,7 @@
#include "network_client.h"
#include "network_server.h"
#include "../command_func.h"
#include "../command_aux.h"
#include "../company_func.h"
#include "../settings_type.h"
@ -143,9 +144,9 @@ static CommandQueue _local_execution_queue;
* @param callback A callback function to call after the command is finished
* @param text The text to pass
* @param company The company that wants to send the command
* @param binary_length The quantity of binary data in text
* @param aux_data Auxiliary command data
*/
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, uint32 binary_length)
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, const CommandAuxiliaryBase *aux_data)
{
assert((cmd & CMD_FLAGS_MASK) == 0);
@ -157,16 +158,12 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32
c.p3 = p3;
c.cmd = cmd;
c.callback = callback;
if (aux_data != nullptr) c.aux_data.reset(aux_data->Clone());
c.binary_length = binary_length;
if (binary_length == 0) {
if (text != nullptr) {
c.text.assign(text);
} else {
c.text.clear();
}
if (text != nullptr) {
c.text.assign(text);
} else {
c.text.assign(text, binary_length);
c.text.clear();
}
if (_network_server) {
@ -328,21 +325,24 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
cp->p2 = p->Recv_uint32();
cp->p3 = p->Recv_uint64();
cp->tile = p->Recv_uint32();
cp->binary_length = p->Recv_uint32();
if (cp->binary_length == 0) {
StringValidationSettings settings = (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK;
if (GetCommandFlags(cp->cmd) & CMD_STR_SEP) settings |= SVS_ALLOW_SEPARATOR_CODE;
p->Recv_string(cp->text, settings);
} else {
if (!p->CanReadFromPacket(cp->binary_length + /* callback index */ 1)) return "invalid binary data length";
if (cp->binary_length > MAX_CMD_TEXT_LENGTH) return "over-size binary data length";
p->Recv_binary(cp->text, cp->binary_length);
}
StringValidationSettings settings = (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK;
if (GetCommandFlags(cp->cmd) & CMD_STR_SEP) settings |= SVS_ALLOW_SEPARATOR_CODE;
p->Recv_string(cp->text, settings);
byte callback = p->Recv_uint8();
if (callback >= lengthof(_callback_table)) return "invalid callback";
cp->callback = _callback_table[callback];
uint16 aux_data_size = p->Recv_uint16();
if (aux_data_size > 0 && p->CanReadFromPacket(aux_data_size, true)) {
CommandAuxiliarySerialised *aux_data = new CommandAuxiliarySerialised();
cp->aux_data.reset(aux_data);
aux_data->serialised_data.resize(aux_data_size);
p->Recv_binary((char *)(aux_data->serialised_data.data()), aux_data_size);
}
return nullptr;
}
@ -359,13 +359,7 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
p->Send_uint32(cp->p2);
p->Send_uint64(cp->p3);
p->Send_uint32(cp->tile);
p->Send_uint32(cp->binary_length);
if (cp->binary_length == 0) {
p->Send_string(cp->text.c_str());
} else {
assert(cp->text.size() >= cp->binary_length);
p->Send_binary(cp->text.c_str(), cp->binary_length);
}
p->Send_string(cp->text.c_str());
byte callback = 0;
while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {
@ -377,4 +371,12 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
callback = 0; // _callback_table[0] == nullptr
}
p->Send_uint8 (callback);
size_t aux_data_size_pos = p->Size();
p->Send_uint16(0);
if (cp->aux_data != nullptr) {
CommandSerialisationBuffer serialiser(p->GetSerialisationBuffer(), p->GetSerialisationLimit());
cp->aux_data->Serialise(serialiser);
p->WriteAtOffset_uint16(aux_data_size_pos, (uint16)(p->Size() - aux_data_size_pos - 2));
}
}

@ -1563,7 +1563,7 @@ private:
if (_network_server) {
DoCommandP(0, CCA_NEW, _network_own_client_id, CMD_COMPANY_CTRL);
} else {
NetworkSendCommand(0, CCA_NEW, 0, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company, 0);
NetworkSendCommand(0, CCA_NEW, 0, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company, nullptr);
}
}

@ -1211,7 +1211,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
_settings_client.network.sync_freq = std::min<uint16>(_settings_client.network.sync_freq, 16);
// have the server and all clients run some sanity checks
NetworkSendCommand(0, 0, 0, 0, CMD_DESYNC_CHECK, nullptr, nullptr, _local_company, 0);
NetworkSendCommand(0, 0, 0, 0, CMD_DESYNC_CHECK, nullptr, nullptr, _local_company, nullptr);
SendPacketsState send_state = this->SendPackets(true);
if (send_state != SPS_CLOSED) {
@ -2301,7 +2301,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
/* ci is nullptr when replaying, or for AIs. In neither case there is a client. */
ci->client_playas = c->index;
NetworkUpdateClientInfo(ci->client_id);
NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name.c_str(), c->index, 0);
NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name.c_str(), c->index, nullptr);
}
/* Announce new company on network. */

@ -966,7 +966,7 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p2, 0, 16);
@ -1758,7 +1758,7 @@ CommandCost CmdReverseOrderList(TileIndex tile, DoCommandFlag flags, uint32 p1,
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleOrderID sel_ord = GB(p3, 0, 16);
VehicleID veh = GB(p1, 0, 20);

@ -47,3 +47,19 @@ void PlanLine::UpdateVisualExtents()
this->viewport_extents = { (int)(min_x * TILE_SIZE * 2 * ZOOM_LVL_BASE), (int)(min_y * TILE_SIZE * ZOOM_LVL_BASE),
(int)((max_x + 1) * TILE_SIZE * 2 * ZOOM_LVL_BASE), (int)((max_y + 1) * TILE_SIZE * ZOOM_LVL_BASE) };
}
bool Plan::ValidateNewLine()
{
extern bool AddPlanLine(PlanID plan, TileVector tiles);
bool ret = false;
if (this->temp_line->tiles.size() > 1) {
this->temp_line->MarkDirty();
this->last_tile = this->temp_line->tiles.back();
this->SetVisibility(true, false);
TileVector tiles = std::move(this->temp_line->tiles);
this->temp_line->Clear();
ret = AddPlanLine(this->index, std::move(tiles));
}
return ret;
}

@ -18,7 +18,6 @@
#include "map_func.h"
#include "date_func.h"
#include "viewport_func.h"
#include "core/endian_func.hpp"
#include <string>
#include <vector>
@ -111,30 +110,6 @@ struct PlanLine {
}
}
TileIndex *Export(uint *buffer_length)
{
const uint cnt = (uint) this->tiles.size();
const uint datalen = sizeof(TileIndex) * cnt;
TileIndex *buffer = (TileIndex *) malloc(datalen);
if (buffer) {
for (uint i = 0; i < cnt; i++) {
buffer[i] = TO_LE32(this->tiles[i]);
}
if (buffer_length) *buffer_length = datalen;
}
return buffer;
}
bool Import(const TileIndex* data, const uint data_length)
{
for (uint i = data_length; i != 0; i--, data++) {
TileIndex t = FROM_LE32(*data);
if (t >= MapSize()) return false;
this->tiles.push_back(t);
}
return true;
}
void AddLineToCalculateCentreTile(uint64 &x, uint64 &y, uint32 &count) const
{
for (size_t i = 0; i < this->tiles.size(); i++) {
@ -226,24 +201,7 @@ struct Plan : PlanPool::PoolItem<&_plan_pool> {
return this->temp_line->AppendTile(tile);
}
bool ValidateNewLine()
{
bool ret = false;
if (this->temp_line->tiles.size() > 1) {
uint buffer_length = 0;
const TileIndex *buffer = this->temp_line->Export(&buffer_length);
uint tiles = (uint)this->temp_line->tiles.size();
this->temp_line->MarkDirty();
this->last_tile = this->temp_line->tiles.back();
this->temp_line->Clear();
if (buffer) {
this->SetVisibility(true, false);
ret = DoCommandPEx(0, this->index, tiles, 0, CMD_ADD_PLAN_LINE, nullptr, (const char *) buffer, buffer_length);
free(buffer);
}
}
return ret;
}
bool ValidateNewLine();
bool IsListable()
{

@ -9,6 +9,7 @@
#include "stdafx.h"
#include "command_func.h"
#include "command_aux.h"
#include "plans_base.h"
#include "plans_func.h"
#include "window_func.h"
@ -43,6 +44,36 @@ CommandCost CmdAddPlan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2
return CommandCost();
}
struct PlanLineCmdData : public CommandAuxiliarySerialisable<PlanLineCmdData> {
TileVector tiles;
virtual void Serialise(CommandSerialisationBuffer &buffer) const override
{
buffer.Send_uint32((uint32)this->tiles.size());
for (TileIndex t : this->tiles) {
buffer.Send_uint32(t);
}
}
CommandCost Deserialise(CommandDeserialisationBuffer &buffer)
{
uint32 size = buffer.Recv_uint32();
if (!buffer.CanRecvBytes(size * 4)) return CMD_ERROR;
this->tiles.resize(size);
for (uint i = 0; i < size; i++) {
this->tiles[i] = buffer.Recv_uint32();
}
return CommandCost();
}
};
bool AddPlanLine(PlanID plan, TileVector tiles)
{
PlanLineCmdData data;
data.tiles = std::move(tiles);
return DoCommandPEx(0, plan, 0, 0, CMD_ADD_PLAN_LINE, nullptr, nullptr, &data);
}
/**
* Create a new line in a plan.
* @param tile unused
@ -50,25 +81,25 @@ CommandCost CmdAddPlan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2
* @param p1 plan id
* @param p2 number of nodes
* @param text list of tile indexes that compose the line
* @param binary_length binary length of text
* @param aux_data auxiliary data
* @return the cost of this operation or an error
*/
CommandCost CmdAddPlanLine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdAddPlanLine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
Plan *p = Plan::GetIfValid(p1);
if (p == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(p->owner);
if (ret.Failed()) return ret;
if (p2 > (MAX_CMD_TEXT_LENGTH / sizeof(TileIndex))) return_cmd_error(STR_ERROR_TOO_MANY_NODES);
if (!text || binary_length != p2 * 4) return CMD_ERROR;
CommandAuxData<PlanLineCmdData> data;
ret = data.Load(aux_data);
if (ret.Failed()) return ret;
if (data->tiles.size() > (MAX_CMD_TEXT_LENGTH / sizeof(TileIndex))) return_cmd_error(STR_ERROR_TOO_MANY_NODES);
if (flags & DC_EXEC) {
PlanLine *pl = p->NewLine();
if (!pl) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_LINES);
if (!pl->Import((const TileIndex *) text, p2)) {
delete pl;
p->lines.pop_back();
return CMD_ERROR;
}
pl->tiles = std::move(data->tiles);
pl->UpdateVisualExtents();
if (p->IsListable()) {
pl->SetVisibility(p->visible);

@ -73,7 +73,7 @@ CommandCost CmdScheduledDispatch(TileIndex tile, DoCommandFlag flags, uint32 p1,
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);
uint schedule_index = GB(p1, 20, 12);
@ -185,7 +185,7 @@ CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags,
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);
uint schedule_index = GB(p1, 20, 12);
@ -330,7 +330,7 @@ CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint3
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdScheduledDispatchAddNewSchedule(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdScheduledDispatchAddNewSchedule(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);

@ -313,7 +313,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
return GetStorage()->callback_value[index];
}
/* static */ bool ScriptObject::DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint cmd, const char *text, uint32 binary_length, Script_SuspendCallbackProc *callback)
/* static */ bool ScriptObject::DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint cmd, const char *text, const CommandAuxiliaryBase *aux_data, Script_SuspendCallbackProc *callback)
{
if (!ScriptObject::CanSuspend()) {
throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
@ -325,7 +325,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
}
std::string text_validated;
if (binary_length == 0 && !StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) {
if (!StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) {
/* The string must be valid, i.e. not contain special codes. Since some
* can be made with GSText, make sure the control codes are removed. */
text_validated = text;
@ -349,7 +349,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, p3, cmd);
/* Try to perform the command. */
CommandCost res = ::DoCommandPScript(tile, p1, p2, p3, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, text, false, estimate_only, binary_length);
CommandCost res = ::DoCommandPScript(tile, p1, p2, p3, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, text, false, estimate_only, aux_data);
/* We failed; set the error and bail out */
if (res.Failed()) {

@ -18,6 +18,8 @@
#include "../script_suspend.hpp"
#include "../squirrel.hpp"
struct CommandAuxiliaryBase;
/**
* The callback function for Mode-classes.
*/
@ -69,7 +71,7 @@ protected:
/**
* Executes a raw DoCommand for the script.
*/
static bool DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint cmd, const char *text = nullptr, uint32 binary_length = 0, Script_SuspendCallbackProc *callback = nullptr);
static bool DoCommandEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint cmd, const char *text = nullptr, const CommandAuxiliaryBase *aux_data = nullptr, Script_SuspendCallbackProc *callback = nullptr);
static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text = nullptr, Script_SuspendCallbackProc *callback = nullptr)
{

@ -2647,7 +2647,7 @@ void SyncCompanySettings()
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
uint32 old_value = (uint32)sd->AsIntSetting()->Read(old_object);
uint32 new_value = (uint32)sd->AsIntSetting()->Read(new_object);
if (old_value != new_value) NetworkSendCommand(0, 0, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company, 0);
if (old_value != new_value) NetworkSendCommand(0, 0, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company, nullptr);
}
}

@ -2087,7 +2087,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
* @param text Unused.
* @return The cost of this operation or an error.
*/
CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
bool type = HasBit(p2, 0);
bool is_drive_through = HasBit(p2, 1);

@ -162,7 +162,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val,
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
VehicleID veh = GB(p1, 0, 20);

@ -199,7 +199,7 @@ extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
/* Unpack parameters */
Axis axis = Extract<Axis, 6, 1>(p1);
@ -344,7 +344,7 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint
* @param text Unused.
* @return The cost of this operation or an error.
*/
CommandCost CmdBuildRoadWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
CommandCost CmdBuildRoadWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
{
StationID station_to_join = GB(p2, 16, 16);
byte width = GB(p1, 0, 8);

Loading…
Cancel
Save