Codechange: Un-bitstuff vehicle/engine commands.

This commit is contained in:
Michael Lutz 2021-11-05 23:55:23 +01:00
parent 2637c06f88
commit 21675ec7e2
25 changed files with 221 additions and 268 deletions

View File

@ -1275,7 +1275,7 @@ void HandleMissingAircraftOrders(Aircraft *v)
const Station *st = GetTargetAirportIfValid(v);
if (st == nullptr) {
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->tile, v->index, 0, {});
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::None, {});
cur_company.Restore();
if (ret.Failed()) CrashAirplane(v);
@ -1638,7 +1638,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass
/* Send the helicopter to a hangar if needed for replacement */
if (v->NeedsAutomaticServicing()) {
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, {});
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service | DepotCommand::LocateHangar, {});
cur_company.Restore();
}
}
@ -1689,7 +1689,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
if (v->NeedsAutomaticServicing()) {
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE, 0, {});
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service, {});
cur_company.Restore();
}
}

View File

@ -355,13 +355,13 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
if (refit_cargo != CT_NO_REFIT) {
byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
cost.AddCost(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, 0, new_veh->index, refit_cargo | (subtype << 8), {}));
cost.AddCost(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0));
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
}
/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
if (new_veh->type == VEH_TRAIN && HasBit(Train::From(old_veh)->flags, VRF_REVERSE_DIRECTION)) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, 0, new_veh->index, true, {});
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, new_veh->index, true);
}
return cost;
@ -373,9 +373,9 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
* @param evaluate_callback shall the start/stop callback be evaluated?
* @return success or error
*/
static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_callback)
static inline CommandCost DoCmdStartStopVehicle(const Vehicle *v, bool evaluate_callback)
{
return Command<CMD_START_STOP_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, 0, v->index, evaluate_callback ? 1 : 0, {});
return Command<CMD_START_STOP_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, v->index, evaluate_callback);
}
/**
@ -388,7 +388,7 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca
*/
static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain)
{
return Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags | DC_NO_CARGO_CAP_CHECK, 0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, {});
return Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags | DC_NO_CARGO_CAP_CHECK, v->index, after != nullptr ? after->index : INVALID_VEHICLE, whole_chain);
}
/**
@ -411,10 +411,10 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head,
if (cost.Succeeded()) {
/* Start the vehicle, might be denied by certain things */
assert((new_head->vehstatus & VS_STOPPED) != 0);
cost.AddCost(CmdStartStopVehicle(new_head, true));
cost.AddCost(DoCmdStartStopVehicle(new_head, true));
/* Stop the vehicle again, but do not care about evil newgrfs allowing starting but not stopping :p */
if (cost.Succeeded()) cost.AddCost(CmdStartStopVehicle(new_head, false));
if (cost.Succeeded()) cost.AddCost(DoCmdStartStopVehicle(new_head, false));
}
/* Last do those things which do never fail (resp. we do not care about), but which are not undo-able */
@ -471,11 +471,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
}
/* Sell the old vehicle */
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, 0, old_v->index, false, false, INVALID_CLIENT_ID));
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, old_v->index, false, false, INVALID_CLIENT_ID));
/* If we are not in DC_EXEC undo everything */
if ((flags & DC_EXEC) == 0) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, 0, new_v->index, false, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, new_v->index, false, false, INVALID_CLIENT_ID);
}
}
@ -602,7 +602,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
/* Sell wagon */
[[maybe_unused]] CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, 0, wagon->index, false, false, INVALID_CLIENT_ID);
[[maybe_unused]] CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, wagon->index, false, false, INVALID_CLIENT_ID);
assert(ret.Succeeded());
new_vehs[i] = nullptr;
@ -634,7 +634,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
/* Sell the vehicle.
* Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent
* it from failing due to engine limits. */
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags | DC_AUTOREPLACE, 0, w->index, false, false, INVALID_CLIENT_ID));
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags | DC_AUTOREPLACE, w->index, false, false, INVALID_CLIENT_ID));
if ((flags & DC_EXEC) != 0) {
old_vehs[i] = nullptr;
if (i == 0) old_head = nullptr;
@ -665,7 +665,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if ((flags & DC_EXEC) == 0) {
for (int i = num_units - 1; i >= 0; i--) {
if (new_vehs[i] != nullptr) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, 0, new_vehs[i]->index, false, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, new_vehs[i]->index, false, false, INVALID_CLIENT_ID);
new_vehs[i] = nullptr;
}
}
@ -696,12 +696,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
}
/* Sell the old vehicle */
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, 0, old_head->index, false, false, INVALID_CLIENT_ID));
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, old_head->index, false, false, INVALID_CLIENT_ID));
}
/* If we are not in DC_EXEC undo everything */
if ((flags & DC_EXEC) == 0) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, 0, new_head->index, false, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, new_head->index, false, false, INVALID_CLIENT_ID);
}
}
}
@ -764,7 +764,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1
bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0);
/* Stop the vehicle */
if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, true));
if (!was_stopped) cost.AddCost(DoCmdStartStopVehicle(v, true));
if (cost.Failed()) return cost;
assert(free_wagon || v->IsStoppedInDepot());
@ -792,7 +792,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1
}
/* Restart the vehicle */
if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, false));
if (!was_stopped) cost.AddCost(DoCmdStartStopVehicle(v, false));
}
if (cost.Succeeded() && nothing_to_do) cost = CommandCost(STR_ERROR_AUTOREPLACE_NOTHING_TO_DO);

View File

@ -1461,7 +1461,7 @@ struct BuildVehicleWindow : Window {
case WID_BV_SHOW_HIDE: {
const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine);
if (e != nullptr) {
Command<CMD_SET_VEHICLE_VISIBILITY>::Post(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), {});
Command<CMD_SET_VEHICLE_VISIBILITY>::Post(this->sel_engine, !e->IsHidden(_current_company));
}
break;
}
@ -1637,7 +1637,7 @@ struct BuildVehicleWindow : Window {
{
if (str == nullptr) return;
Command<CMD_RENAME_ENGINE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str);
Command<CMD_RENAME_ENGINE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, this->rename_engine, str);
}
void OnDropdownSelect(int widget, int index) override

View File

@ -29,9 +29,9 @@
/** Operators to allow to work with enum as with type safe bit set in C++ */
# define DECLARE_ENUM_AS_BIT_SET(mask_t) \
inline constexpr mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 | m2);} \
inline constexpr mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 & m2);} \
inline constexpr mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 ^ m2);} \
inline constexpr mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 | (std::underlying_type<mask_t>::type)m2);} \
inline constexpr mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 & (std::underlying_type<mask_t>::type)m2);} \
inline constexpr mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 ^ (std::underlying_type<mask_t>::type)m2);} \
inline constexpr mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \
inline constexpr mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \
inline constexpr mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \

View File

@ -142,7 +142,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh
if (wagon == v) return;
Command<CMD_MOVE_RAIL_VEHICLE>::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, {});
Command<CMD_MOVE_RAIL_VEHICLE>::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index, wagon == nullptr ? INVALID_VEHICLE : wagon->index, _ctrl_pressed);
}
static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view.
@ -803,7 +803,7 @@ struct DepotWindow : Window {
case WID_D_STOP_ALL:
case WID_D_START_ALL: {
VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner);
Command<CMD_MASS_START_STOP>::Post(this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack(), {});
Command<CMD_MASS_START_STOP>::Post(this->window_number, widget == WID_D_START_ALL, false, vli);
break;
}
@ -826,7 +826,7 @@ struct DepotWindow : Window {
break;
case WID_D_AUTOREPLACE:
Command<CMD_DEPOT_MASS_AUTOREPLACE>::Post(this->window_number, this->type, 0, {});
Command<CMD_DEPOT_MASS_AUTOREPLACE>::Post(this->window_number, this->type);
break;
}
@ -905,10 +905,10 @@ struct DepotWindow : Window {
{
if (_ctrl_pressed) {
/* Share-clone, do not open new viewport, and keep tool active */
Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1, {});
Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, true);
} else {
/* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
if (Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0, {})) {
if (Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, false)) {
ResetObjectToPlace();
}
}
@ -1002,7 +1002,7 @@ struct DepotWindow : Window {
if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) {
if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, {});
Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true);
} else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) {
this->vehicle_over = INVALID_VEHICLE;
TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
@ -1090,8 +1090,8 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
if (confirmed) {
DepotWindow *w = (DepotWindow*)win;
TileIndex tile = w->window_number;
byte vehtype = w->type;
Command<CMD_DEPOT_SELL_ALL_VEHICLES>::Post(tile, vehtype, 0, {});
VehicleType vehtype = w->type;
Command<CMD_DEPOT_SELL_ALL_VEHICLES>::Post(tile, vehtype);
}
}

View File

@ -451,7 +451,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
* However, do not rely on that behaviour.
*/
int interval = CompanyServiceInterval(new_company, v->type);
Command<CMD_CHANGE_SERVICE_INT>::Do(DC_EXEC | DC_BANKRUPT, v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17), {});
Command<CMD_CHANGE_SERVICE_INT>::Do(DC_EXEC | DC_BANKRUPT, v->index, interval, false, new_company->settings.vehicle.servint_ispercent);
}
v->owner = new_owner;
@ -1488,7 +1488,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
if (st->goods[cid].cargo.HasCargoFor(next_station)) {
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
* the returned refit capacity will be greater than zero. */
Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts.
Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, v_start->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
/* Try to balance different loadable cargoes between parts of the consist, so that
* all of them can be loaded. Avoid a situation where all vehicles suddenly switch
* to the first loadable cargo for which there is only one packet. If the capacities
@ -1511,7 +1511,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
* "via any station" before reserving. We rather produce some more "any station" cargo than
* misrouting it. */
IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION));
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts.
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v_start->index, new_cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8;
}

View File

@ -876,20 +876,18 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid)
/**
* Set the visibility of an engine.
* @param flags Operation to perform.
* @param tile Unused.
* @param p1 Unused.
* @param p2 Bit 31: 0=visible, 1=hidden, other bits for the #EngineID.
* @param text Unused.
* @param engine_id Engine id..
* @param hide Set for hidden, unset for visible.
* @return The cost of this operation or an error.
*/
CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, bool hide)
{
Engine *e = Engine::GetIfValid(GB(p2, 0, 31));
Engine *e = Engine::GetIfValid(engine_id);
if (e == nullptr || _current_company >= MAX_COMPANIES) return CMD_ERROR;
if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR;
if ((flags & DC_EXEC) != 0) {
SB(e->company_hidden, _current_company, 1, GB(p2, 31, 1));
SB(e->company_hidden, _current_company, 1, hide ? 1 : 0);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}
@ -900,18 +898,15 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, TileIndex tile, uint32
* Accept an engine prototype. XXX - it is possible that the top-company
* changes while you are waiting to accept the offer? Then it becomes invalid
* @param flags operation to perform
* @param tile unused
* @param p1 engine-prototype offered
* @param p2 unused
* @param text unused
* @param engine_id engine-prototype offered
* @return the cost of this operation or an error
*/
CommandCost CmdWantEnginePreview(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdWantEnginePreview(DoCommandFlag flags, EngineID engine_id)
{
Engine *e = Engine::GetIfValid(p1);
Engine *e = Engine::GetIfValid(engine_id);
if (e == nullptr || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR;
if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_company);
if (flags & DC_EXEC) AcceptEnginePreview(engine_id, _current_company);
return CommandCost();
}
@ -919,20 +914,14 @@ CommandCost CmdWantEnginePreview(DoCommandFlag flags, TileIndex tile, uint32 p1,
/**
* Allow or forbid a specific company to use an engine
* @param flags operation to perform
* @param tile unused
* @param p1 engine id
* @param p2 various bitstuffed elements
* - p2 = (bit 0 - 7) - Company to allow/forbid the use of an engine.
* - p2 = (bit 31) - 0 to forbid, 1 to allow.
* @param text unused
* @param engine_id engine id
* @param company_id Company to allow/forbid the use of an engine.
* @param allow false to forbid, true to allow.
* @return the cost of this operation or an error
*/
CommandCost CmdEngineCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdEngineCtrl(DoCommandFlag flags, EngineID engine_id, CompanyID company_id, bool allow)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
EngineID engine_id = (EngineID)p1;
CompanyID company_id = (CompanyID)GB(p2, 0, 8);
bool allow = HasBit(p2, 31);
if (!Engine::IsValidID(engine_id) || !Company::IsValidID(company_id)) return CMD_ERROR;
@ -1073,15 +1062,13 @@ static bool IsUniqueEngineName(const std::string &name)
/**
* Rename an engine.
* @param flags operation to perform
* @param tile unused
* @param p1 engine ID to rename
* @param p2 unused
* @param engine_id engine ID to rename
* @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error
*/
CommandCost CmdRenameEngine(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdRenameEngine(DoCommandFlag flags, EngineID engine_id, const std::string &text)
{
Engine *e = Engine::GetIfValid(p1);
Engine *e = Engine::GetIfValid(engine_id);
if (e == nullptr) return CMD_ERROR;
bool reset = text.empty();

View File

@ -12,10 +12,10 @@
#include "command_type.h"
CommandProc CmdWantEnginePreview;
CommandProc CmdEngineCtrl;
CommandProc CmdRenameEngine;
CommandProc CmdSetVehicleVisibility;
CommandCost CmdWantEnginePreview(DoCommandFlag flags, EngineID engine_id);
CommandCost CmdEngineCtrl(DoCommandFlag flags, EngineID engine_id, CompanyID company_id, bool allow);
CommandCost CmdRenameEngine(DoCommandFlag flags, EngineID engine_id, const std::string &text);
CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, bool hide);
DEF_CMD_TRAIT(CMD_WANT_ENGINE_PREVIEW, CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT)
DEF_CMD_TRAIT(CMD_ENGINE_CTRL, CmdEngineCtrl, CMD_DEITY, CMDT_VEHICLE_MANAGEMENT)

View File

@ -126,7 +126,7 @@ struct EnginePreviewWindow : Window {
{
switch (widget) {
case WID_EP_YES:
Command<CMD_WANT_ENGINE_PREVIEW>::Post(0, this->window_number, 0, {});
Command<CMD_WANT_ENGINE_PREVIEW>::Post(this->window_number);
FALLTHROUGH;
case WID_EP_NO:
if (!_shift_pressed) this->Close();

View File

@ -802,7 +802,7 @@ public:
case WID_GL_START_ALL:
case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list
Command<CMD_MASS_START_STOP>::Post(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), {});
Command<CMD_MASS_START_STOP>::Post(0, widget == WID_GL_START_ALL, true, this->vli);
break;
}
@ -954,7 +954,7 @@ public:
break;
case ADI_SERVICE: // Send for servicing
case ADI_DEPOT: { // Send to Depots
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), {});
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DepotCommand::MassSend | (index == ADI_SERVICE ? DepotCommand::Service : DepotCommand::None), this->vli);
break;
}

View File

@ -1996,7 +1996,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo());
/* If there is no depot in front, reverse automatically (trains only) */
if (v->type == VEH_TRAIN && reverse) Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, v->tile, v->index, 0, {});
if (v->type == VEH_TRAIN && reverse) Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, v->index, false);
if (v->type == VEH_AIRCRAFT) {
Aircraft *a = Aircraft::From(v);

View File

@ -361,15 +361,12 @@ bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destinati
/**
* Turn a roadvehicle around.
* @param flags operation to perform
* @param tile unused
* @param p1 vehicle ID to turn
* @param p2 unused
* @param text unused
* @param veh_id vehicle ID to turn
* @return the cost of this operation or an error
*/
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id)
{
RoadVehicle *v = RoadVehicle::GetIfValid(p1);
RoadVehicle *v = RoadVehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
if (!v->IsPrimaryVehicle()) return CMD_ERROR;

View File

@ -16,7 +16,7 @@
CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v);
CommandProc CmdTurnRoadVeh;
CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id);
DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT)

View File

@ -286,7 +286,7 @@
EnforcePrecondition(false, IsValidEngine(engine_id));
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(0, engine_id, (uint32)company | (1 << 31), {});
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, (::CompanyID)company, true);
}
/* static */ bool ScriptEngine::DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company)
@ -297,5 +297,5 @@
EnforcePrecondition(false, IsValidEngine(engine_id));
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(0, engine_id, company, {});
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, (::CompanyID)company, false);
}

View File

@ -112,7 +112,7 @@ int32 ScriptEventEnginePreview::GetVehicleType()
bool ScriptEventEnginePreview::AcceptPreview()
{
if (!this->IsEngineValid()) return false;
return ScriptObject::Command<CMD_WANT_ENGINE_PREVIEW>::Do(0, this->engine, 0, {});
return ScriptObject::Command<CMD_WANT_ENGINE_PREVIEW>::Do(this->engine);
}
bool ScriptEventCompanyAskMerger::AcceptMerger()

View File

@ -103,7 +103,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, IsValidVehicle(vehicle_id));
if (!ScriptObject::Command<CMD_CLONE_VEHICLE>::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders, {})) return VEHICLE_INVALID;
if (!ScriptObject::Command<CMD_CLONE_VEHICLE>::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders)) return VEHICLE_INVALID;
/* In case of test-mode, we return VehicleID 0 */
return 0;
@ -125,7 +125,7 @@
while (dest_wagon-- > 0) w = w->GetNextUnit();
}
return ScriptObject::Command<CMD_MOVE_RAIL_VEHICLE>::Do(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == nullptr ? ::INVALID_VEHICLE : w->index, {});
return ScriptObject::Command<CMD_MOVE_RAIL_VEHICLE>::Do(v->index, w == nullptr ? ::INVALID_VEHICLE : w->index, move_attached_wagons);
}
/* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon)
@ -143,7 +143,7 @@
if (!IsValidVehicle(vehicle_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
CommandCost res = ::Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, 0, vehicle_id, cargo, {});
CommandCost res = ::Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0);
return res.Succeeded() ? _returned_refit_capacity : -1;
}
@ -152,7 +152,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo));
return ScriptObject::Command<CMD_REFIT_VEHICLE>::Do(0, vehicle_id, cargo, {});
return ScriptObject::Command<CMD_REFIT_VEHICLE>::Do(vehicle_id, cargo, 0, false, false, 0);
}
@ -162,7 +162,7 @@
EnforcePrecondition(false, IsValidVehicle(vehicle_id));
const Vehicle *v = ::Vehicle::Get(vehicle_id);
return ScriptObject::Command<CMD_SELL_VEHICLE>::Do(0, vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID);
return ScriptObject::Command<CMD_SELL_VEHICLE>::Do(vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID);
}
/* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons)
@ -174,7 +174,7 @@
const Train *v = ::Train::Get(vehicle_id);
while (wagon-- > 0) v = v->GetNextUnit();
return ScriptObject::Command<CMD_SELL_VEHICLE>::Do(0, v->index, sell_attached_wagons, false, INVALID_CLIENT_ID);
return ScriptObject::Command<CMD_SELL_VEHICLE>::Do(v->index, sell_attached_wagons, false, INVALID_CLIENT_ID);
}
/* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, int wagon)
@ -192,7 +192,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, IsValidVehicle(vehicle_id));
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(0, vehicle_id, 0, {});
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommand::None, {});
}
/* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id)
@ -200,7 +200,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, IsValidVehicle(vehicle_id));
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(0, vehicle_id | DEPOT_SERVICE, 0, {});
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommand::Service, {});
}
/* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id)
@ -220,7 +220,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, IsValidVehicle(vehicle_id));
return ScriptObject::Command<CMD_START_STOP_VEHICLE>::Do(0, vehicle_id, 0, {});
return ScriptObject::Command<CMD_START_STOP_VEHICLE>::Do(vehicle_id, false);
}
/* static */ bool ScriptVehicle::ReverseVehicle(VehicleID vehicle_id)
@ -230,8 +230,8 @@
EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_ROAD || ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN);
switch (::Vehicle::Get(vehicle_id)->type) {
case VEH_ROAD: return ScriptObject::Command<CMD_TURN_ROADVEH>::Do(0, vehicle_id, 0, {});
case VEH_TRAIN: return ScriptObject::Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(0, vehicle_id, 0, {});
case VEH_ROAD: return ScriptObject::Command<CMD_TURN_ROADVEH>::Do(vehicle_id);
case VEH_TRAIN: return ScriptObject::Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(vehicle_id, false);
default: NOT_REACHED();
}
}
@ -247,7 +247,7 @@
EnforcePreconditionEncodedText(false, text);
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_VEHICLE_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
return ScriptObject::Command<CMD_RENAME_VEHICLE>::Do(0, vehicle_id, 0, text);
return ScriptObject::Command<CMD_RENAME_VEHICLE>::Do(vehicle_id, text);
}
/* static */ TileIndex ScriptVehicle::GetLocation(VehicleID vehicle_id)

View File

@ -656,7 +656,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const
w->engine_type == e->index && ///< Same type
w->First() != v && ///< Don't connect to ourself
!(w->vehstatus & VS_CRASHED)) { ///< Not crashed/flooded
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DC_EXEC, 0, v->index | 1 << 20, w->Last()->index, {}).Succeeded()) {
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DC_EXEC, v->index, w->Last()->index, true).Succeeded()) {
break;
}
}
@ -672,7 +672,7 @@ static void NormalizeTrainVehInDepot(const Train *u)
for (const Train *v : Train::Iterate()) {
if (v->IsFreeWagon() && v->tile == u->tile &&
v->track == TRACK_BIT_DEPOT) {
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DC_EXEC, 0, v->index | 1 << 20, u->index, {}).Failed()) {
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DC_EXEC, v->index, u->index, true).Failed()) {
break;
}
}
@ -1162,21 +1162,14 @@ static void NormaliseTrainHead(Train *head)
* Move a rail vehicle around inside the depot.
* @param flags type of operation
* Note: DC_AUTOREPLACE is set when autoreplace tries to undo its modifications or moves vehicles to temporary locations inside the depot.
* @param tile unused
* @param p1 various bitstuffed elements
* - p1 (bit 0 - 19) source vehicle index
* - p1 (bit 20) move all vehicles following the source vehicle
* @param p2 what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
* @param text unused
* @param src_veh source vehicle index
* @param dest_veh what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
* @param move_chain move all vehicles following the source vehicle
* @return the cost of this operation or an error
*/
CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dest_veh, bool move_chain)
{
VehicleID s = GB(p1, 0, 20);
VehicleID d = GB(p2, 0, 20);
bool move_chain = HasBit(p1, 20);
Train *src = Train::GetIfValid(s);
Train *src = Train::GetIfValid(src_veh);
if (src == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(src->owner);
@ -1187,10 +1180,10 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, u
/* if nothing is selected as destination, try and find a matching vehicle to drag to. */
Train *dst;
if (d == INVALID_VEHICLE) {
if (dest_veh == INVALID_VEHICLE) {
dst = (src->IsEngine() || (flags & DC_AUTOREPLACE)) ? nullptr : FindGoodVehiclePos(src);
} else {
dst = Train::GetIfValid(d);
dst = Train::GetIfValid(dest_veh);
if (dst == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(dst->owner);
@ -1908,22 +1901,20 @@ void ReverseTrainDirection(Train *v)
/**
* Reverse train.
* @param tile unused
* @param flags type of operation
* @param p1 train to reverse
* @param p2 if true, reverse a unit in a train (needs to be in a depot)
* @param text unused
* @param veh_id train to reverse
* @param reverse_single_veh if true, reverse a unit in a train (needs to be in a depot)
* @return the cost of this operation or an error
*/
CommandCost CmdReverseTrainDirection(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh)
{
Train *v = Train::GetIfValid(p1);
Train *v = Train::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret;
if (p2 != 0) {
if (reverse_single_veh) {
/* turn a single unit around */
if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) {
@ -1982,15 +1973,12 @@ CommandCost CmdReverseTrainDirection(DoCommandFlag flags, TileIndex tile, uint32
/**
* Force a train through a red signal
* @param flags type of operation
* @param tile unused
* @param p1 train to ignore the red signal
* @param p2 unused
* @param text unused
* @param veh_id train to ignore the red signal
* @return the cost of this operation or an error
*/
CommandCost CmdForceTrainProceed(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id)
{
Train *t = Train::GetIfValid(p1);
Train *t = Train::GetIfValid(veh_id);
if (t == nullptr) return CMD_ERROR;
if (!t->IsPrimaryVehicle()) return CMD_ERROR;

View File

@ -17,9 +17,9 @@
CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, bool free_cars, Vehicle **ret);
CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, bool backup_order, ClientID user);
CommandProc CmdMoveRailVehicle;
CommandProc CmdForceTrainProceed;
CommandProc CmdReverseTrainDirection;
CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dest_veh, bool move_chain);
CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id);
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_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT)

View File

@ -43,7 +43,7 @@ void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile, const
if (found != nullptr) {
found = found->Last();
/* put the new wagon at the end of the loco. */
Command<CMD_MOVE_RAIL_VEHICLE>::Post(0, _new_vehicle_id, found->index, {});
Command<CMD_MOVE_RAIL_VEHICLE>::Post( _new_vehicle_id, found->index, false);
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
}
}

View File

@ -1565,7 +1565,7 @@ void VehicleEnterDepot(Vehicle *v)
if (v->current_order.IsRefit()) {
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, {});
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0);
cur_company.Restore();
if (cost.Failed()) {
@ -2397,7 +2397,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
if (this->current_order.IsType(OT_GOTO_DEPOT)) {
bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
if (!!(command & DEPOT_SERVICE) == halt_in_depot) {
if (((command & DepotCommand::Service) != DepotCommand::None) == halt_in_depot) {
/* We called with a different DEPOT_SERVICE setting.
* Now we change the setting to apply the new one and let the vehicle head for the same depot.
* Note: the if is (true for requesting service == true for ordered to stop in depot) */
@ -2409,7 +2409,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
return CommandCost();
}
if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancellation of depot orders
if ((command & DepotCommand::DontCancel) != DepotCommand::None) return CMD_ERROR; // Requested no cancellation of depot orders
if (flags & DC_EXEC) {
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
@ -2442,12 +2442,12 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
this->SetDestTile(location);
this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
/* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->tile, this->index, 0, {});
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->index, false);
}
if (this->type == VEH_AIRCRAFT) {

View File

@ -151,7 +151,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b
if (refitting) {
/* Refit only one vehicle. If we purchased an engine, it may have gained free wagons. */
value.AddCost(CmdRefitVehicle(flags, tile, v->index, cargo | (1 << 16), {}));
value.AddCost(CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1));
} else {
/* Fill in non-refitted capacities */
_returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity);
@ -179,7 +179,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b
/* If we are not in DC_EXEC undo everything */
if (flags != subflags) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, 0, v->index, false, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, v->index, false, false, INVALID_CLIENT_ID);
}
}
@ -191,7 +191,6 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b
/**
* Sell a vehicle.
* @param tile unused.
* @param flags for command.
* @aram v_id vehicle ID being sold.
* @param sell_chain sell the vehicle and all vehicles following it in the chain.
@ -200,7 +199,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b
* @param text unused.
* @return the cost of this operation or an error.
*/
CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id)
CommandCost CmdSellVehicle(DoCommandFlag flags, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id)
{
Vehicle *v = Vehicle::GetIfValid(v_id);
if (v == nullptr) return CMD_ERROR;
@ -450,21 +449,18 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
/**
* Refits a vehicle to the specified cargo type.
* @param flags type of operation
* @param tile unused
* @param p1 vehicle ID to refit
* @param p2 various bitstuffed elements
* - p2 = (bit 0-7) - New cargo type to refit to.
* - p2 = (bit 8-15) - New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
* - p2 = (bit 16-23) - Number of vehicles to refit (not counting articulated parts). Zero means all vehicles.
* Only used if "refit only this vehicle" is false.
* - p2 = (bit 24) - Automatic refitting.
* - p2 = (bit 25) - Refit only this vehicle. Used only for cloning vehicles.
* @param text unused
* @param veh_id vehicle ID to refit
* @param new_cid New cargo type to refit to.
* @param new_subtype New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
* @param auto_refit Automatic refitting.
* @param only_this Refit only this vehicle. Used only for cloning vehicles.
* @param num_vehicles Number of vehicles to refit (not counting articulated parts). Zero means all vehicles.
* Only used if "refit only this vehicle" is false.
* @return the cost of this operation or an error
*/
CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles)
{
Vehicle *v = Vehicle::GetIfValid(p1);
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
/* Don't allow disasters and sparks and such to be refitted.
@ -476,7 +472,6 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
CommandCost ret = CheckOwnership(front->owner);
if (ret.Failed()) return ret;
bool auto_refit = HasBit(p2, 24);
bool free_wagon = v->type == VEH_TRAIN && Train::From(front)->IsFreeWagon(); // used by autoreplace/renew
/* Don't allow shadows and such to be refitted. */
@ -493,13 +488,10 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);
/* Check cargo */
CargoID new_cid = GB(p2, 0, 8);
byte new_subtype = GB(p2, 8, 8);
if (new_cid >= NUM_CARGO) return CMD_ERROR;
/* For ships and aircraft there is always only one. */
bool only_this = HasBit(p2, 25) || front->type == VEH_SHIP || front->type == VEH_AIRCRAFT;
uint8 num_vehicles = GB(p2, 16, 8);
only_this |= front->type == VEH_SHIP || front->type == VEH_AIRCRAFT;
CommandCost cost = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit);
@ -544,18 +536,16 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
/**
* Start/Stop a vehicle
* @param flags type of operation
* @param tile unused
* @param p1 vehicle to start/stop, don't forget to change CcStartStopVehicle if you modify this!
* @param p2 bit 0: Shall the start/stop newgrf callback be evaluated (only valid with DC_AUTOREPLACE for network safety)
* @param text unused
* @param veh_id vehicle to start/stop, don't forget to change CcStartStopVehicle if you modify this!
* @param evaluate_startstop_cb Shall the start/stop newgrf callback be evaluated (only valid with DC_AUTOREPLACE for network safety)
* @return the cost of this operation or an error
*/
CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool evaluate_startstop_cb)
{
/* Disable the effect of p2 bit 0, when DC_AUTOREPLACE is not set */
if ((flags & DC_AUTOREPLACE) == 0) SetBit(p2, 0);
if ((flags & DC_AUTOREPLACE) == 0) evaluate_startstop_cb = true;
Vehicle *v = Vehicle::GetIfValid(p1);
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
@ -583,7 +573,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1,
default: return CMD_ERROR;
}
if (HasBit(p2, 0)) {
if (evaluate_startstop_cb) {
/* Check if this vehicle can be started/stopped. Failure means 'allow'. */
uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
StringID error = STR_NULL;
@ -610,7 +600,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1,
}
if (flags & DC_EXEC) {
if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(p1, STR_NEWS_TRAIN_IS_WAITING + v->type);
if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(veh_id, STR_NEWS_TRAIN_IS_WAITING + v->type);
v->vehstatus ^= VS_STOPPED;
if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly'
@ -627,21 +617,16 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1,
* Starts or stops a lot of vehicles
* @param flags type of operation
* @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
* @param p1 bitmask
* - bit 0 set = start vehicles, unset = stop vehicles
* - bit 1 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
* @param p2 packed VehicleListIdentifier
* @param text unused
* @param do_start set = start vehicles, unset = stop vehicles
* @param vehicle_list_window if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
* @param vli VehicleListIdentifier
* @return the cost of this operation or an error
*/
CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do_start, bool vehicle_list_window, const VehicleListIdentifier &vli)
{
VehicleList list;
bool do_start = HasBit(p1, 0);
bool vehicle_list_window = HasBit(p1, 1);
VehicleListIdentifier vli;
if (!vli.UnpackIfValid(p2)) return CMD_ERROR;
if (!vli.Valid()) return CMD_ERROR;
if (!IsCompanyBuildableVehicleType(vli.vtype)) return CMD_ERROR;
if (vehicle_list_window) {
@ -659,7 +644,7 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32
if (!vehicle_list_window && !v->IsChainInDepot()) continue;
/* Just try and don't care if some vehicle's can't be stopped. */
Command<CMD_START_STOP_VEHICLE>::Do(flags, tile, v->index, 0, {});
Command<CMD_START_STOP_VEHICLE>::Do(flags, v->index, false);
}
return CommandCost();
@ -669,17 +654,14 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32
* Sells all vehicles in a depot
* @param flags type of operation
* @param tile Tile of the depot where the depot is
* @param p1 Vehicle type
* @param p2 unused
* @param text unused
* @param vehicle_type Vehicle type
* @return the cost of this operation or an error
*/
CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type)
{
VehicleList list;
CommandCost cost(EXPENSES_NEW_VEHICLES);
VehicleType vehicle_type = Extract<VehicleType, 0, 3>(p1);
if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR;
@ -689,7 +671,7 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32
CommandCost last_error = CMD_ERROR;
bool had_success = false;
for (uint i = 0; i < list.size(); i++) {
CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(flags, tile, list[i]->index, true, false, INVALID_CLIENT_ID);
CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(flags, list[i]->index, true, false, INVALID_CLIENT_ID);
if (ret.Succeeded()) {
cost.AddCost(ret);
had_success = true;
@ -705,16 +687,13 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32
* Autoreplace all vehicles in the depot
* @param flags type of operation
* @param tile Tile of the depot where the vehicles are
* @param p1 Type of vehicle
* @param p2 unused
* @param text unused
* @param vehicle_type Type of vehicle
* @return the cost of this operation or an error
*/
CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type)
{
VehicleList list;
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES);
VehicleType vehicle_type = Extract<VehicleType, 0, 3>(p1);
if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR;
if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR;
@ -809,16 +788,15 @@ static void CloneVehicleName(const Vehicle *src, Vehicle *dst)
* Clone a vehicle. If it is a train, it will clone all the cars too
* @param flags type of operation
* @param tile tile of the depot where the cloned vehicle is build
* @param p1 the original vehicle's index
* @param p2 1 = shared orders, else copied orders
* @param text unused
* @param veh_id the original vehicle's index
* @param share_orders shared orders, else copied orders
* @return the cost of this operation or an error
*/
CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders)
{
CommandCost total_cost(EXPENSES_NEW_VEHICLES);
Vehicle *v = Vehicle::GetIfValid(p1);
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
Vehicle *v_front = v;
Vehicle *w = nullptr;
@ -871,7 +849,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
if (cost.Failed()) {
/* Can't build a part, then sell the stuff we already made; clear up the mess */
if (w_front != nullptr) Command<CMD_SELL_VEHICLE>::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID);
if (w_front != nullptr) Command<CMD_SELL_VEHICLE>::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID);
return cost;
}
@ -887,12 +865,12 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
if (v->type == VEH_TRAIN && !v->IsFrontEngine()) {
/* this s a train car
* add this unit to the end of the train */
CommandCost result = Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags, 0, w->index | 1 << 20, w_rear->index, {});
CommandCost result = Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags, w->index, w_rear->index, true);
if (result.Failed()) {
/* The train can't be joined to make the same consist as the original.
* Sell what we already made (clean up) and return an error. */
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->tile, w->index, true, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(flags, w->index, true, false, INVALID_CLIENT_ID);
return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE
}
} else {
@ -935,7 +913,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
/* Find out what's the best sub type */
byte subtype = GetBestFittingSubType(v, w, v->cargo_type);
if (w->cargo_type != v->cargo_type || w->cargo_subtype != subtype) {
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(flags, 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8), {});
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(flags, w->index, v->cargo_type, subtype, false, true, 0);
if (cost.Succeeded()) total_cost.AddCost(cost);
}
@ -970,10 +948,10 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
* the vehicle refitted before doing this, otherwise the moved
* cargo types might not match (passenger vs non-passenger)
*/
CommandCost result = Command<CMD_CLONE_ORDER>::Do(flags, (p2 & 1 ? CO_SHARE : CO_COPY), w_front->index, v_front->index);
CommandCost result = Command<CMD_CLONE_ORDER>::Do(flags, (share_orders ? CO_SHARE : CO_COPY), w_front->index, v_front->index);
if (result.Failed()) {
/* The vehicle has already been bought, so now it must be sold again. */
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID);
return result;
}
@ -984,7 +962,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint
* check whether the company has enough money manually. */
if (!CheckCompanyHasMoney(total_cost)) {
/* The vehicle has already been bought, so now it must be sold again. */
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID);
return total_cost;
}
}
@ -1009,7 +987,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con
bool had_success = false;
for (uint i = 0; i < list.size(); i++) {
const Vehicle *v = list[i];
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(flags, v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0, {});
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(flags, v->index, (service ? DepotCommand::Service : DepotCommand::None) | DepotCommand::DontCancel, {});
if (ret.Succeeded()) {
had_success = true;
@ -1028,42 +1006,36 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con
/**
* Send a vehicle to the depot.
* @param flags for command type
* @param tile unused
* @param p1 bitmask
* - p1 0-20: bitvehicle ID to send to the depot
* - p1 bits 25-8 - DEPOT_ flags (see vehicle_type.h)
* @param p2 packed VehicleListIdentifier.
* @param text unused
* @param veh_id vehicle ID to send to the depot
* @param depot_cmd DEPOT_ flags (see vehicle_type.h)
* @param vli VehicleListIdentifier.
* @return the cost of this operation or an error
*/
CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli)
{
if (p1 & DEPOT_MASS_SEND) {
if ((depot_cmd & DepotCommand::MassSend) != DepotCommand::None) {
/* Mass goto depot requested */
VehicleListIdentifier vli;
if (!vli.UnpackIfValid(p2)) return CMD_ERROR;
return SendAllVehiclesToDepot(flags, (p1 & DEPOT_SERVICE) != 0, vli);
if (!vli.Valid()) return CMD_ERROR;
return SendAllVehiclesToDepot(flags, (depot_cmd & DepotCommand::Service) != DepotCommand::None, vli);
}
Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20));
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
if (!v->IsPrimaryVehicle()) return CMD_ERROR;
return v->SendToDepot(flags, (DepotCommand)(p1 & DEPOT_COMMAND_MASK));
return v->SendToDepot(flags, depot_cmd);
}
/**
* Give a custom name to your vehicle
* @param flags type of operation
* @param tile unused
* @param p1 vehicle ID to name
* @param p2 unused
* @param veh_id vehicle ID to name
* @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error
*/
CommandCost CmdRenameVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdRenameVehicle(DoCommandFlag flags, VehicleID veh_id, const std::string &text)
{
Vehicle *v = Vehicle::GetIfValid(p1);
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
@ -1093,39 +1065,33 @@ CommandCost CmdRenameVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uin
/**
* Change the service interval of a vehicle
* @param flags type of operation
* @param tile unused
* @param p1 vehicle ID that is being service-interval-changed
* @param p2 bitmask
* - p2 = (bit 0-15) - new service interval
* - p2 = (bit 16) - service interval is custom flag
* - p2 = (bit 17) - service interval is percentage flag
* @param text unused
* @param veh_id vehicle ID that is being service-interval-changed
* @param serv_int new service interval
* @param is_custom service interval is custom flag
* @param is_percent service interval is percentage flag
* @return the cost of this operation or an error
*/
CommandCost CmdChangeServiceInt(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
CommandCost CmdChangeServiceInt(DoCommandFlag flags, VehicleID veh_id, uint16 serv_int, bool is_custom, bool is_percent)
{
Vehicle *v = Vehicle::GetIfValid(p1);
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret;
const Company *company = Company::Get(v->owner);
bool iscustom = HasBit(p2, 16);
bool ispercent = iscustom ? HasBit(p2, 17) : company->settings.vehicle.servint_ispercent;
is_percent = is_custom ? is_percent : company->settings.vehicle.servint_ispercent;
uint16 serv_int;
if (iscustom) {
serv_int = GB(p2, 0, 16);
if (serv_int != GetServiceIntervalClamped(serv_int, ispercent)) return CMD_ERROR;
if (is_custom) {
if (serv_int != GetServiceIntervalClamped(serv_int, is_percent)) return CMD_ERROR;
} else {
serv_int = CompanyServiceInterval(company, v->type);
}
if (flags & DC_EXEC) {
v->SetServiceInterval(serv_int);
v->SetServiceIntervalIsCustom(iscustom);
v->SetServiceIntervalIsPercent(ispercent);
v->SetServiceIntervalIsCustom(is_custom);
v->SetServiceIntervalIsPercent(is_percent);
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
}

View File

@ -11,18 +11,21 @@
#define VEHICLE_CMD_H
#include "command_type.h"
#include "engine_type.h"
#include "vehicle_type.h"
#include "vehiclelist.h"
CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id);
CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id);
CommandProc CmdRefitVehicle;
CommandProc CmdSendVehicleToDepot;
CommandProc CmdChangeServiceInt;
CommandProc CmdRenameVehicle;
CommandProc CmdCloneVehicle;
CommandProc CmdStartStopVehicle;
CommandProc CmdMassStartStopVehicle;
CommandProc CmdDepotSellAllVehicles;
CommandProc CmdDepotMassAutoReplace;
CommandCost CmdSellVehicle(DoCommandFlag flags, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id);
CommandCost CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles);
CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli);
CommandCost CmdChangeServiceInt(DoCommandFlag flags, VehicleID veh_id, uint16 serv_int, bool is_custom, bool is_percent);
CommandCost CmdRenameVehicle(DoCommandFlag flags, VehicleID veh_id, const std::string &text);
CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders);
CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool evaluate_startstop_cb);
CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do_start, bool vehicle_list_window, const VehicleListIdentifier &vli);
CommandCost CmdDepotSellAllVehicles(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_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION)
@ -39,4 +42,15 @@ DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0,
CommandCallback CcBuildPrimaryVehicle;
CommandCallback CcStartStopVehicle;
template <typename Tcont, typename Titer>
inline EndianBufferWriter<Tcont, Titer> &operator <<(EndianBufferWriter<Tcont, Titer> &buffer, const VehicleListIdentifier &vli)
{
return buffer << vli.type << vli.vtype << vli.company << vli.index;
}
inline EndianBufferReader &operator >>(EndianBufferReader &buffer, VehicleListIdentifier &vli)
{
return buffer >> vli.type >> vli.vtype >> vli.company >> vli.index;
}
#endif /* VEHICLE_CMD_H */

View File

@ -776,9 +776,7 @@ struct RefitWindow : public Window {
StringID GetCapacityString(RefitOption *option) const
{
assert(_current_company == _local_company);
Vehicle *v = Vehicle::Get(this->window_number);
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, v->tile, this->selected_vehicle, option->cargo |
option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24, {});
CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles);
if (cost.Failed()) return INVALID_STRING_ID;
@ -1038,7 +1036,7 @@ struct RefitWindow : public Window {
if (this->order == INVALID_VEH_ORDER_ID) {
bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX;
if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, {}) && delete_window) this->Close();
if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo, this->cargo->subtype, false, false, this->num_vehicles) && delete_window) this->Close();
} else {
if (Command<CMD_ORDER_REFIT>::Post(v->tile, v->index, this->order, this->cargo->cargo)) this->Close();
}
@ -1899,7 +1897,7 @@ public:
case WID_VL_STOP_ALL:
case WID_VL_START_ALL:
Command<CMD_MASS_START_STOP>::Post(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, {});
Command<CMD_MASS_START_STOP>::Post(0, widget == WID_VL_START_ALL, true, this->vli);
break;
}
}
@ -1924,7 +1922,7 @@ public:
break;
case ADI_SERVICE: // Send for servicing
case ADI_DEPOT: // Send to Depots
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, {});
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DepotCommand::MassSend | (index == ADI_SERVICE ? DepotCommand::Service : DepotCommand::None), this->vli);
break;
default: NOT_REACHED();
@ -2427,7 +2425,7 @@ struct VehicleDetailsWindow : Window {
mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent());
if (mod == v->GetServiceInterval()) return;
Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), {});
Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, mod, true, v->ServiceIntervalIsPercent());
break;
}
@ -2463,7 +2461,7 @@ struct VehicleDetailsWindow : Window {
bool iscustom = index != 0;
bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent;
uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent);
Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), {});
Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, interval, iscustom, ispercent);
break;
}
}
@ -2628,8 +2626,8 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile,
{
if (result.Failed()) return;
auto [tile_, p1, p2, text] = EndianBufferReader::ToValue<CommandTraits<CMD_START_STOP_VEHICLE>::Args>(data);
const Vehicle *v = Vehicle::GetIfValid(p1);
VehicleID veh_id = std::get<0>(EndianBufferReader::ToValue<CommandTraits<CMD_START_STOP_VEHICLE>::Args>(data));
const Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return;
StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED;
@ -2645,7 +2643,7 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile,
void StartStopVehicle(const Vehicle *v, bool texteffect)
{
assert(v->IsPrimaryVehicle());
Command<CMD_START_STOP_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0, {});
Command<CMD_START_STOP_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, false);
}
/** Checks whether the vehicle may be refitted at the moment.*/
@ -2969,7 +2967,7 @@ public:
break;
case WID_VV_GOTO_DEPOT: // goto hangar
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, {});
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(v), v->index, _ctrl_pressed ? DepotCommand::Service : DepotCommand::None, {});
break;
case WID_VV_REFIT: // refit
ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this);
@ -2995,19 +2993,19 @@ public:
* most likely already open, but is also visible in the vehicle viewport. */
Command<CMD_CLONE_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type],
_ctrl_pressed ? nullptr : CcCloneVehicle,
v->tile, v->index, _ctrl_pressed ? 1 : 0, {});
v->tile, v->index, _ctrl_pressed);
break;
case WID_VV_TURN_AROUND: // turn around
assert(v->IsGroundVehicle());
if (v->type == VEH_ROAD) {
Command<CMD_TURN_ROADVEH>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {});
Command<CMD_TURN_ROADVEH>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index);
} else {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {});
Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, false);
}
break;
case WID_VV_FORCE_PROCEED: // force proceed
assert(v->type == VEH_TRAIN);
Command<CMD_FORCE_TRAIN_PROCEED>::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0, {});
Command<CMD_FORCE_TRAIN_PROCEED>::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index);
break;
}
}
@ -3016,7 +3014,7 @@ public:
{
if (str == nullptr) return;
Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str);
Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, this->window_number, str);
}
void OnMouseOver(Point pt, int widget) override

View File

@ -61,14 +61,15 @@ enum VehiclePathFinders {
VPF_YAPF = 2, ///< Yet Another PathFinder
};
/** Flags to add to p1 for goto depot commands. */
enum DepotCommand {
DEPOT_SERVICE = (1U << 28), ///< The vehicle will leave the depot right after arrival (service only)
DEPOT_MASS_SEND = (1U << 29), ///< Tells that it's a mass send to depot command (type in VLW flag)
DEPOT_DONT_CANCEL = (1U << 30), ///< Don't cancel current goto depot command if any
DEPOT_LOCATE_HANGAR = (1U << 31), ///< Find another airport if the target one lacks a hangar
DEPOT_COMMAND_MASK = 0xFU << 28,
/** Flags for goto depot commands. */
enum class DepotCommand : byte {
None = 0, ///< No special flags.
Service = (1U << 0), ///< The vehicle will leave the depot right after arrival (service only)
MassSend = (1U << 1), ///< Tells that it's a mass send to depot command (type in VLW flag)
DontCancel = (1U << 2), ///< Don't cancel current goto depot command if any
LocateHangar = (1U << 3), ///< Find another airport if the target one lacks a hangar
};
DECLARE_ENUM_AS_BIT_SET(DepotCommand)
static const uint MAX_LENGTH_VEHICLE_NAME_CHARS = 32; ///< The maximum length of a vehicle name in characters including '\0'

View File

@ -16,7 +16,7 @@
#include "tile_type.h"
/** Vehicle List type flags */
enum VehicleListType {
enum VehicleListType : byte {
VL_STANDARD,
VL_SHARED_ORDERS,
VL_STATION_LIST,
@ -36,6 +36,8 @@ struct VehicleListIdentifier {
bool UnpackIfValid(uint32 data);
static VehicleListIdentifier UnPack(uint32 data);
bool Valid() const { return this->type < VLT_END; }
/**
* Create a simple vehicle list.
* @param type List type.