mirror of https://github.com/OpenTTD/OpenTTD.git
Fix: Don't send unused tile field over the network (#10507)
This commit is contained in:
parent
9b3326e3fd
commit
c73b88ddca
|
@ -97,11 +97,10 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version)
|
||||||
* DoCommand callback function for all commands executed by AIs.
|
* DoCommand callback function for all commands executed by AIs.
|
||||||
* @param cmd cmd as given to DoCommandPInternal.
|
* @param cmd cmd as given to DoCommandPInternal.
|
||||||
* @param result The result of the command.
|
* @param result The result of the command.
|
||||||
* @param tile The tile on which the command was executed.
|
|
||||||
* @param data Command data as given to Command<>::Post.
|
* @param data Command data as given to Command<>::Post.
|
||||||
* @param result_data Additional returned data from the command.
|
* @param result_data Additional returned data from the command.
|
||||||
*/
|
*/
|
||||||
void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data)
|
void CcAI(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The company might not exist anymore. Check for this.
|
* The company might not exist anymore. Check for this.
|
||||||
|
@ -112,7 +111,7 @@ void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const Command
|
||||||
const Company *c = Company::GetIfValid(_current_company);
|
const Company *c = Company::GetIfValid(_current_company);
|
||||||
if (c == nullptr || c->ai_instance == nullptr) return;
|
if (c == nullptr || c->ai_instance == nullptr) return;
|
||||||
|
|
||||||
if (c->ai_instance->DoCommandCallback(result, tile, data, std::move(result_data), cmd)) {
|
if (c->ai_instance->DoCommandCallback(result, data, std::move(result_data), cmd)) {
|
||||||
c->ai_instance->Continue();
|
c->ai_instance->Continue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
|
||||||
*/
|
*/
|
||||||
#define return_cmd_error(errcode) return CommandCost(errcode);
|
#define return_cmd_error(errcode) return CommandCost(errcode);
|
||||||
|
|
||||||
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data);
|
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data);
|
||||||
|
|
||||||
bool IsValidCommand(Commands cmd);
|
bool IsValidCommand(Commands cmd);
|
||||||
CommandFlags GetCommandFlags(Commands cmd);
|
CommandFlags GetCommandFlags(Commands cmd);
|
||||||
|
@ -215,20 +215,13 @@ public:
|
||||||
* @param err_message Message prefix to show on error
|
* @param err_message Message prefix to show on error
|
||||||
* @param callback A callback function to call after the command is finished
|
* @param callback A callback function to call after the command is finished
|
||||||
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
|
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
|
||||||
* @param location Tile location for user feedback.
|
|
||||||
* @param args Parameters for the command
|
* @param args Parameters for the command
|
||||||
* @return \c true if the command succeeded, else \c false.
|
* @return \c true if the command succeeded, else \c false.
|
||||||
*/
|
*/
|
||||||
template <typename Tcallback>
|
template <typename Tcallback>
|
||||||
static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, TileIndex location, std::tuple<Targs...> args)
|
static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, std::tuple<Targs...> args)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args)>>) {
|
return InternalPost(err_message, callback, my_cmd, true, std::move(args));
|
||||||
/* Do not even think about executing out-of-bounds tile-commands. */
|
|
||||||
TileIndex tile = std::get<0>(args);
|
|
||||||
if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (GetCommandFlags<Tcmd>() & CMD_ALL_TILES) == 0))) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return InternalPost(err_message, callback, my_cmd, true, location, std::move(args));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,12 +235,7 @@ public:
|
||||||
{
|
{
|
||||||
auto args_tuple = std::forward_as_tuple(args...);
|
auto args_tuple = std::forward_as_tuple(args...);
|
||||||
|
|
||||||
TileIndex tile{};
|
::NetworkSendCommand(Tcmd, err_message, nullptr, _current_company, EndianBufferWriter<CommandDataBuffer>::FromValue(args_tuple));
|
||||||
if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args_tuple)>>) {
|
|
||||||
tile = std::get<0>(args_tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
::NetworkSendCommand(Tcmd, err_message, nullptr, _current_company, tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args_tuple));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -324,9 +312,9 @@ protected:
|
||||||
} else if constexpr (std::is_same_v<Tcallback, CommandCallbackData>) {
|
} else if constexpr (std::is_same_v<Tcallback, CommandCallbackData>) {
|
||||||
/* Generic callback that takes packed arguments as a buffer. */
|
/* Generic callback that takes packed arguments as a buffer. */
|
||||||
if constexpr (std::is_same_v<Tret, CommandCost>) {
|
if constexpr (std::is_same_v<Tret, CommandCost>) {
|
||||||
callback(Tcmd, ExtractCommandCost(res), tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args), {});
|
callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), {});
|
||||||
} else {
|
} else {
|
||||||
callback(Tcmd, ExtractCommandCost(res), tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args), EndianBufferWriter<CommandDataBuffer>::FromValue(RemoveFirstTupleElement(res)));
|
callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter<CommandDataBuffer>::FromValue(args), EndianBufferWriter<CommandDataBuffer>::FromValue(RemoveFirstTupleElement(res)));
|
||||||
}
|
}
|
||||||
} else if constexpr (!std::is_same_v<Tret, CommandCost> && std::is_same_v<Tcallback *, typename CommandTraits<Tcmd>::RetCallbackProc>) {
|
} else if constexpr (!std::is_same_v<Tret, CommandCost> && std::is_same_v<Tcallback *, typename CommandTraits<Tcmd>::RetCallbackProc>) {
|
||||||
std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res));
|
std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res));
|
||||||
|
@ -405,7 +393,7 @@ protected:
|
||||||
/* If we are in network, and the command is not from the network
|
/* If we are in network, and the command is not from the network
|
||||||
* send it to the command-queue and abort execution. */
|
* send it to the command-queue and abort execution. */
|
||||||
if (send_net) {
|
if (send_net) {
|
||||||
::NetworkSendCommand(Tcmd, err_message, callback, _current_company, tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args));
|
::NetworkSendCommand(Tcmd, err_message, callback, _current_company, EndianBufferWriter<CommandDataBuffer>::FromValue(args));
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
|
|
||||||
/* Don't return anything special here; no error, no costs.
|
/* Don't return anything special here; no error, no costs.
|
||||||
|
@ -446,8 +434,13 @@ protected:
|
||||||
template <Commands Tcmd, typename Tret, typename... Targs>
|
template <Commands Tcmd, typename Tret, typename... Targs>
|
||||||
struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), false> : CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true>
|
struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), false> : CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true>
|
||||||
{
|
{
|
||||||
/* Import Post overloads from our base class. */
|
/* Do not allow Post without explicit location. */
|
||||||
using CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), true>::Post;
|
static inline bool Post(StringID err_message, Targs... args) = delete;
|
||||||
|
template <typename Tcallback>
|
||||||
|
static inline bool Post(Tcallback *callback, Targs... args) = delete;
|
||||||
|
static inline bool Post(Targs... args) = delete;
|
||||||
|
template <typename Tcallback>
|
||||||
|
static bool Post(StringID err_message, Tcallback *callback, Targs... args) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for Post when not using a callback.
|
* Shortcut for Post when not using a callback.
|
||||||
|
@ -476,7 +469,6 @@ struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), false> : CommandHel
|
||||||
* commands that don't take a TileIndex by themselves.
|
* commands that don't take a TileIndex by themselves.
|
||||||
* @param err_message Message prefix to show on error
|
* @param err_message Message prefix to show on error
|
||||||
* @param callback A callback function to call after the command is finished
|
* @param callback A callback function to call after the command is finished
|
||||||
* @param location Tile location for user feedback.
|
|
||||||
* @param args Parameters for the command
|
* @param args Parameters for the command
|
||||||
* @return \c true if the command succeeded, else \c false.
|
* @return \c true if the command succeeded, else \c false.
|
||||||
*/
|
*/
|
||||||
|
@ -492,6 +484,6 @@ struct CommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...), false> : CommandHel
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <Commands Tcmd>
|
template <Commands Tcmd>
|
||||||
using Command = CommandHelper<Tcmd, typename CommandTraits<Tcmd>::ProcType, std::is_same_v<TileIndex, std::tuple_element_t<0, typename CommandTraits<Tcmd>::Args>>>;
|
using Command = CommandHelper<Tcmd, typename CommandTraits<Tcmd>::ProcType, (GetCommandFlags<Tcmd>() & CMD_LOCATION) == 0>;
|
||||||
|
|
||||||
#endif /* COMMAND_FUNC_H */
|
#endif /* COMMAND_FUNC_H */
|
||||||
|
|
|
@ -388,6 +388,7 @@ enum CommandFlags {
|
||||||
CMD_DEITY = 0x100, ///< the command may be executed by COMPANY_DEITY
|
CMD_DEITY = 0x100, ///< the command may be executed by COMPANY_DEITY
|
||||||
CMD_STR_CTRL = 0x200, ///< the command's string may contain control strings
|
CMD_STR_CTRL = 0x200, ///< the command's string may contain control strings
|
||||||
CMD_NO_EST = 0x400, ///< the command is never estimated.
|
CMD_NO_EST = 0x400, ///< the command is never estimated.
|
||||||
|
CMD_LOCATION = 0x800, ///< the command has implicit location argument.
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(CommandFlags)
|
DECLARE_ENUM_AS_BIT_SET(CommandFlags)
|
||||||
|
|
||||||
|
@ -479,6 +480,6 @@ typedef void CommandCallback(Commands cmd, const CommandCost &result, TileIndex
|
||||||
* @param result_data Additional returned data from the command
|
* @param result_data Additional returned data from the command
|
||||||
* @see CommandProc
|
* @see CommandProc
|
||||||
*/
|
*/
|
||||||
typedef void CommandCallbackData(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data);
|
typedef void CommandCallbackData(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data);
|
||||||
|
|
||||||
#endif /* COMMAND_TYPE_H */
|
#endif /* COMMAND_TYPE_H */
|
||||||
|
|
|
@ -84,13 +84,12 @@ void GameInstance::Died()
|
||||||
* DoCommand callback function for all commands executed by Game Scripts.
|
* DoCommand callback function for all commands executed by Game Scripts.
|
||||||
* @param cmd cmd as given to DoCommandPInternal.
|
* @param cmd cmd as given to DoCommandPInternal.
|
||||||
* @param result The result of the command.
|
* @param result The result of the command.
|
||||||
* @param tile The tile on which the command was executed.
|
|
||||||
* @param data Command data as given to Command<>::Post.
|
* @param data Command data as given to Command<>::Post.
|
||||||
* @param result_data Additional returned data from the command.
|
* @param result_data Additional returned data from the command.
|
||||||
*/
|
*/
|
||||||
void CcGame(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data)
|
void CcGame(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data)
|
||||||
{
|
{
|
||||||
if (Game::GetGameInstance()->DoCommandCallback(result, tile, data, std::move(result_data), cmd)) {
|
if (Game::GetGameInstance()->DoCommandCallback(result, data, std::move(result_data), cmd)) {
|
||||||
Game::GetGameInstance()->Continue();
|
Game::GetGameInstance()->Continue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -881,7 +881,7 @@ public:
|
||||||
uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP);
|
uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP);
|
||||||
GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index;
|
GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index;
|
||||||
|
|
||||||
Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS);
|
Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -261,17 +261,15 @@ static size_t FindCallbackIndex(CommandCallback *callback)
|
||||||
* @param err_message Message prefix to show on error
|
* @param err_message Message prefix to show on error
|
||||||
* @param callback A callback function to call after the command is finished
|
* @param callback A callback function to call after the command is finished
|
||||||
* @param company The company that wants to send the command
|
* @param company The company that wants to send the command
|
||||||
* @param location Location of the command (e.g. for error message position)
|
|
||||||
* @param cmd_data The command proc arguments.
|
* @param cmd_data The command proc arguments.
|
||||||
*/
|
*/
|
||||||
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data)
|
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data)
|
||||||
{
|
{
|
||||||
CommandPacket c;
|
CommandPacket c;
|
||||||
c.company = company;
|
c.company = company;
|
||||||
c.cmd = cmd;
|
c.cmd = cmd;
|
||||||
c.err_msg = err_message;
|
c.err_msg = err_message;
|
||||||
c.callback = callback;
|
c.callback = callback;
|
||||||
c.tile = location;
|
|
||||||
c.data = cmd_data;
|
c.data = cmd_data;
|
||||||
|
|
||||||
if (_network_server) {
|
if (_network_server) {
|
||||||
|
@ -429,7 +427,6 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
|
||||||
if (!IsValidCommand(cp->cmd)) return "invalid command";
|
if (!IsValidCommand(cp->cmd)) return "invalid command";
|
||||||
if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command";
|
if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command";
|
||||||
cp->err_msg = p->Recv_uint16();
|
cp->err_msg = p->Recv_uint16();
|
||||||
cp->tile = p->Recv_uint32();
|
|
||||||
cp->data = _cmd_dispatch[cp->cmd].Sanitize(p->Recv_buffer());
|
cp->data = _cmd_dispatch[cp->cmd].Sanitize(p->Recv_buffer());
|
||||||
|
|
||||||
byte callback = p->Recv_uint8();
|
byte callback = p->Recv_uint8();
|
||||||
|
@ -449,7 +446,6 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
|
||||||
p->Send_uint8(cp->company);
|
p->Send_uint8(cp->company);
|
||||||
p->Send_uint16(cp->cmd);
|
p->Send_uint16(cp->cmd);
|
||||||
p->Send_uint16(cp->err_msg);
|
p->Send_uint16(cp->err_msg);
|
||||||
p->Send_uint32(cp->tile);
|
|
||||||
p->Send_buffer(cp->data);
|
p->Send_buffer(cp->data);
|
||||||
|
|
||||||
size_t callback = FindCallbackIndex(cp->callback);
|
size_t callback = FindCallbackIndex(cp->callback);
|
||||||
|
@ -540,5 +536,5 @@ template <Commands Tcmd, size_t Tcb>
|
||||||
void UnpackNetworkCommand(const CommandPacket* cp)
|
void UnpackNetworkCommand(const CommandPacket* cp)
|
||||||
{
|
{
|
||||||
auto args = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(cp->data);
|
auto args = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(cp->data);
|
||||||
Command<Tcmd>::PostFromNet(cp->err_msg, std::get<Tcb>(_callback_tuple), cp->my_cmd, cp->tile, args);
|
Command<Tcmd>::PostFromNet(cp->err_msg, std::get<Tcb>(_callback_tuple), cp->my_cmd, args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ void UpdateNetworkGameWindow();
|
||||||
*/
|
*/
|
||||||
struct CommandPacket {
|
struct CommandPacket {
|
||||||
/** Make sure the pointer is nullptr. */
|
/** Make sure the pointer is nullptr. */
|
||||||
CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false), tile(0) {}
|
CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false) {}
|
||||||
CommandPacket *next; ///< the next command packet (if in queue)
|
CommandPacket *next; ///< the next command packet (if in queue)
|
||||||
CompanyID company; ///< company that is executing the command
|
CompanyID company; ///< company that is executing the command
|
||||||
uint32 frame; ///< the frame in which this packet is executed
|
uint32 frame; ///< the frame in which this packet is executed
|
||||||
|
@ -117,7 +117,6 @@ struct CommandPacket {
|
||||||
Commands cmd; ///< command being executed.
|
Commands cmd; ///< command being executed.
|
||||||
StringID err_msg; ///< string ID of error message to use.
|
StringID err_msg; ///< string ID of error message to use.
|
||||||
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
|
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
|
||||||
TileIndex tile; ///< location of the command (for e.g. error message or effect display).
|
|
||||||
CommandDataBuffer data; ///< command parameters.
|
CommandDataBuffer data; ///< command parameters.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,13 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve
|
||||||
CommandCost CmdMoveOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order);
|
CommandCost CmdMoveOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order);
|
||||||
CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id);
|
CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id);
|
||||||
|
|
||||||
DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING)
|
DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING)
|
||||||
|
|
||||||
template <typename Tcont, typename Titer>
|
template <typename Tcont, typename Titer>
|
||||||
|
|
|
@ -22,6 +22,6 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin
|
||||||
|
|
||||||
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id);
|
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id);
|
||||||
|
|
||||||
DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT)
|
||||||
|
|
||||||
#endif /* ROADVEH_CMD_H */
|
#endif /* ROADVEH_CMD_H */
|
||||||
|
|
|
@ -82,20 +82,18 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||||
return GetStorage()->mode_instance;
|
return GetStorage()->mode_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd)
|
/* static */ void ScriptObject::SetLastCommand(const CommandDataBuffer &data, Commands cmd)
|
||||||
{
|
{
|
||||||
ScriptStorage *s = GetStorage();
|
ScriptStorage *s = GetStorage();
|
||||||
Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data));
|
Debug(script, 6, "SetLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data));
|
||||||
s->last_tile = tile;
|
|
||||||
s->last_data = data;
|
s->last_data = data;
|
||||||
s->last_cmd = cmd;
|
s->last_cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd)
|
/* static */ bool ScriptObject::CheckLastCommand(const CommandDataBuffer &data, Commands cmd)
|
||||||
{
|
{
|
||||||
ScriptStorage *s = GetStorage();
|
ScriptStorage *s = GetStorage();
|
||||||
Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data));
|
Debug(script, 6, "CheckLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data));
|
||||||
if (s->last_tile != tile) return false;
|
|
||||||
if (s->last_cmd != cmd) return false;
|
if (s->last_cmd != cmd) return false;
|
||||||
if (s->last_data != data) return false;
|
if (s->last_data != data) return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -118,12 +118,12 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Store the latest command executed by the script.
|
* Store the latest command executed by the script.
|
||||||
*/
|
*/
|
||||||
static void SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd);
|
static void SetLastCommand(const CommandDataBuffer &data, Commands cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if it's the latest command executed by the script.
|
* Check if it's the latest command executed by the script.
|
||||||
*/
|
*/
|
||||||
static bool CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd);
|
static bool CheckLastCommand(const CommandDataBuffer &data, Commands cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the DoCommand costs counter to a value.
|
* Sets the DoCommand costs counter to a value.
|
||||||
|
@ -354,7 +354,7 @@ bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>
|
||||||
if constexpr ((::GetCommandFlags<Tcmd>() & CMD_CLIENT_ID) != 0) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for<Targs...>{});
|
if constexpr ((::GetCommandFlags<Tcmd>() & CMD_CLIENT_ID) != 0) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for<Targs...>{});
|
||||||
|
|
||||||
/* Store the command for command callback validation. */
|
/* Store the command for command callback validation. */
|
||||||
if (!estimate_only && networking) ScriptObject::SetLastCommand(tile, EndianBufferWriter<CommandDataBuffer>::FromValue(args), Tcmd);
|
if (!estimate_only && networking) ScriptObject::SetLastCommand(EndianBufferWriter<CommandDataBuffer>::FromValue(args), Tcmd);
|
||||||
|
|
||||||
/* Try to perform the command. */
|
/* Try to perform the command. */
|
||||||
Tret res = ::Command<Tcmd>::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args);
|
Tret res = ::Command<Tcmd>::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args);
|
||||||
|
|
|
@ -744,11 +744,11 @@ SQInteger ScriptInstance::GetOpsTillSuspend()
|
||||||
return this->engine->GetOpsTillSuspend();
|
return this->engine->GetOpsTillSuspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd)
|
bool ScriptInstance::DoCommandCallback(const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd)
|
||||||
{
|
{
|
||||||
ScriptObject::ActiveInstance active(this);
|
ScriptObject::ActiveInstance active(this);
|
||||||
|
|
||||||
if (!ScriptObject::CheckLastCommand(tile, data, cmd)) {
|
if (!ScriptObject::CheckLastCommand(data, cmd)) {
|
||||||
Debug(script, 1, "DoCommandCallback terminating a script, last command does not match expected command");
|
Debug(script, 1, "DoCommandCallback terminating a script, last command does not match expected command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +763,7 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile
|
||||||
ScriptObject::SetLastCost(result.GetCost());
|
ScriptObject::SetLastCost(result.GetCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptObject::SetLastCommand(INVALID_TILE, {}, CMD_END);
|
ScriptObject::SetLastCommand({}, CMD_END);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,7 @@ public:
|
||||||
* @param cmd cmd as given to DoCommandPInternal.
|
* @param cmd cmd as given to DoCommandPInternal.
|
||||||
* @return true if we handled result.
|
* @return true if we handled result.
|
||||||
*/
|
*/
|
||||||
bool DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd);
|
bool DoCommandCallback(const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an event for this script.
|
* Insert an event for this script.
|
||||||
|
|
|
@ -44,7 +44,6 @@ private:
|
||||||
uint last_error; ///< The last error of the command.
|
uint last_error; ///< The last error of the command.
|
||||||
bool last_command_res; ///< The last result of the command.
|
bool last_command_res; ///< The last result of the command.
|
||||||
|
|
||||||
TileIndex last_tile; ///< The last tile passed to a command.
|
|
||||||
CommandDataBuffer last_data; ///< The last data passed to a command.
|
CommandDataBuffer last_data; ///< The last data passed to a command.
|
||||||
Commands last_cmd; ///< The last cmd passed to a command.
|
Commands last_cmd; ///< The last cmd passed to a command.
|
||||||
CommandDataBuffer last_cmd_ret; ///< The extra data returned by the last command.
|
CommandDataBuffer last_cmd_ret; ///< The extra data returned by the last command.
|
||||||
|
@ -69,7 +68,6 @@ public:
|
||||||
last_cost (0),
|
last_cost (0),
|
||||||
last_error (STR_NULL),
|
last_error (STR_NULL),
|
||||||
last_command_res (true),
|
last_command_res (true),
|
||||||
last_tile (INVALID_TILE),
|
|
||||||
last_cmd (CMD_END),
|
last_cmd (CMD_END),
|
||||||
/* calback_value (can't be set) */
|
/* calback_value (can't be set) */
|
||||||
road_type (INVALID_ROADTYPE),
|
road_type (INVALID_ROADTYPE),
|
||||||
|
|
|
@ -28,7 +28,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id);
|
||||||
|
|
||||||
DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run
|
DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run
|
||||||
DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, CMD_LOCATION, CMDT_LANDSCAPE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
||||||
|
|
|
@ -21,9 +21,9 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID
|
||||||
CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id);
|
CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id);
|
||||||
CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh);
|
CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh);
|
||||||
|
|
||||||
DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT)
|
||||||
|
|
||||||
void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray, TileIndex tile, EngineID, bool, CargoID, ClientID);
|
void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray, TileIndex tile, EngineID, bool, CargoID, ClientID);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id,
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
found = found->Last();
|
found = found->Last();
|
||||||
/* put the new wagon at the end of the loco. */
|
/* put the new wagon at the end of the loco. */
|
||||||
Command<CMD_MOVE_RAIL_VEHICLE>::Post(new_veh_id, found->index, false);
|
Command<CMD_MOVE_RAIL_VEHICLE>::Post(found->tile, new_veh_id, found->index, false);
|
||||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,17 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do
|
||||||
CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type);
|
CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type);
|
||||||
CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type);
|
CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type);
|
||||||
|
|
||||||
DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID | CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, 0, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost
|
DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost
|
||||||
DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT)
|
DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT)
|
||||||
DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION)
|
DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION)
|
||||||
|
|
||||||
void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray);
|
void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray);
|
||||||
void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool);
|
void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool);
|
||||||
|
|
Loading…
Reference in New Issue