diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index cdeaa9ea42..d8601fff7d 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -31,6 +31,7 @@ #include "core/geometry_func.hpp" #include "autoreplace_func.h" #include "train.h" +#include "error.h" #include "widgets/build_vehicle_widget.h" @@ -1676,7 +1677,7 @@ struct BuildVehicleWindow : Window { } else { VehicleID target = (*(this->virtual_train_out))->GetLastUnit()->index; - DoCommandP(0, (1 << 23) | (1 << 21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE); + DoCommandP(0, (1 << 23) | (1 << 21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcMoveNewVirtualEngine); } InvalidateWindowClassesData(WC_CREATE_TEMPLATE); InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN); @@ -1691,6 +1692,21 @@ void CcAddVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, ui if (window) { Train* train = Train::From(Vehicle::Get(_new_vehicle_id)); ((BuildVehicleWindow*) window)->AddVirtualEngine(train); + } else { + DoCommandP(0, _new_vehicle_id | (1 << 21), 0, CMD_SELL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_SELL_TRAIN)); + } +} + +void CcMoveNewVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +{ + if (result.Failed()) return; + + Window* window = FindWindowById(WC_BUILD_VIRTUAL_TRAIN, 0); + if (window) { + if (result.IsSuccessWithMessage()) { + CommandCost res = result.UnwrapSuccessWithMessage(); + ShowErrorMessage(STR_ERROR_CAN_T_MOVE_VEHICLE, res.GetErrorMessage(), WL_INFO, 0, 0, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack(), res.GetExtraErrorMessage()); + } } } diff --git a/src/command_func.h b/src/command_func.h index 62fb3a9375..20370d103d 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -135,5 +135,6 @@ CommandCallback CcDeleteVirtualTrain; /* build_vehicle_gui.cpp */ CommandCallback CcAddVirtualEngine; +CommandCallback CcMoveNewVirtualEngine; #endif /* COMMAND_FUNC_H */ diff --git a/src/command_type.h b/src/command_type.h index d2b68f9d3e..3024f6dfae 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -198,6 +198,25 @@ public: * @return the number of bytes written */ int WriteSummaryMessage(char *buf, char *last, StringID cmd_msg = 0) const; + + bool IsSuccessWithMessage() const + { + return this->Succeeded() && this->message != INVALID_STRING_ID; + } + + void MakeSuccessWithMessage() + { + assert(this->message != INVALID_STRING_ID); + this->success = true; + } + + CommandCost UnwrapSuccessWithMessage() const + { + assert(this->IsSuccessWithMessage()); + CommandCost res = *this; + res.success = false; + return res; + } }; /** diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 731ed0822d..38ca82694d 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -52,6 +52,7 @@ static CommandCallback * const _callback_table[] = { /* 0x1E */ CcVirtualTrainWagonsMoved, /* 0x1F */ CcDeleteVirtualTrain, /* 0x20 */ CcAddVirtualEngine, + /* 0x21 */ CcMoveNewVirtualEngine, }; /** diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 5e03e1e935..a89a9bb037 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1396,7 +1396,10 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u auto check_on_failure = [&](CommandCost cost) -> CommandCost { if (delete_failed_virtual && src->IsVirtual()) { - return DoCommand(src->tile, src->index | (1 << 21), 0, flags, CMD_SELL_VEHICLE); + CommandCost res = DoCommand(src->tile, src->index | (1 << 21), 0, flags, CMD_SELL_VEHICLE); + if (res.Failed() || cost.GetErrorMessage() == INVALID_STRING_ID) return res; + cost.MakeSuccessWithMessage(); + return cost; } else { return cost; }