Changeset - r26125:9a63e6c142ba
[Not reviewed]
master
0 21 0
Michael Lutz - 3 years ago 2021-11-30 22:21:16
michi@icosahedron.de
Codechange: Don't use globals for return values from vehicle command procs.
21 files changed with 88 insertions and 118 deletions:
0 comments (0 inline, 0 general)
src/aircraft_cmd.cpp
Show inline comments
 
@@ -328,8 +328,6 @@ CommandCost CmdBuildAircraft(DoCommandFl
 
		v->reliability_spd_dec = e->reliability_spd_dec;
 
		v->max_age = e->GetLifeLengthInDays();
 

	
 
		_new_vehicle_id = v->index;
 

	
 
		v->pos = GetVehiclePosOnBuild(tile);
 

	
 
		v->state = HANGAR;
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -345,17 +345,18 @@ static CommandCost BuildReplacementVehic
 
	}
 

	
 
	/* Build the new vehicle */
 
	cost = Command<CMD_BUILD_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, CT_INVALID, INVALID_CLIENT_ID);
 
	VehicleID new_veh_id;
 
	std::tie(cost, new_veh_id, std::ignore, std::ignore) = Command<CMD_BUILD_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, CT_INVALID, INVALID_CLIENT_ID);
 
	if (cost.Failed()) return cost;
 

	
 
	Vehicle *new_veh = Vehicle::Get(_new_vehicle_id);
 
	Vehicle *new_veh = Vehicle::Get(new_veh_id);
 
	*new_vehicle = new_veh;
 

	
 
	/* Refit the vehicle if needed */
 
	if (refit_cargo != CT_NO_REFIT) {
 
		byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
 

	
 
		cost.AddCost(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0));
 
		cost.AddCost(std::get<0>(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()
 
	}
 

	
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -1229,11 +1229,11 @@ struct BuildVehicleWindow : Window {
 

	
 
		if (!this->listview_mode) {
 
			/* Query for cost and refitted capacity */
 
			CommandCost ret = Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID);
 
			auto [ret, veh_id, refit_capacity, refit_mail] = Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID);
 
			if (ret.Succeeded()) {
 
				this->te.cost          = ret.GetCost() - e->GetCost();
 
				this->te.capacity      = _returned_refit_capacity;
 
				this->te.mail_capacity = _returned_mail_refit_capacity;
 
				this->te.capacity      = refit_capacity;
 
				this->te.mail_capacity = refit_mail;
 
				this->te.cargo         = (cargo == CT_INVALID) ? e->GetDefaultCargoType() : cargo;
 
				return;
 
			}
 
@@ -1469,10 +1469,13 @@ struct BuildVehicleWindow : Window {
 
			case WID_BV_BUILD: {
 
				EngineID sel_eng = this->sel_engine;
 
				if (sel_eng != INVALID_ENGINE) {
 
					CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle;
 
					CargoID cargo = this->cargo_filter[this->cargo_filter_criteria];
 
					if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE;
 
					Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID);
 
					if (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) {
 
						Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), CcBuildWagon, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID);
 
					} else {
 
						Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), CcBuildPrimaryVehicle, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID);
 
					}
 
				}
 
				break;
 
			}
src/depot_cmd.h
Show inline comments
 
@@ -17,6 +17,6 @@ CommandCost CmdRenameDepot(DoCommandFlag
 

	
 
DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT)
 

	
 
CommandCallback CcCloneVehicle;
 
void CcCloneVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id);
 

	
 
#endif /* DEPOT_CMD_H */
src/depot_gui.cpp
Show inline comments
 
@@ -116,13 +116,13 @@ extern void DepotSortList(VehicleList *l
 
 * This is the Callback method after the cloning attempt of a vehicle
 
 * @param cmd unused
 
 * @param result the result of the cloning command
 
 * @param tile unused
 
 * @param veh_id cloned vehicle ID
 
 */
 
void CcCloneVehicle(Commands cmd, const CommandCost &result, TileIndex tile)
 
void CcCloneVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id)
 
{
 
	if (result.Failed()) return;
 

	
 
	const Vehicle *v = Vehicle::Get(_new_vehicle_id);
 
	const Vehicle *v = Vehicle::Get(veh_id);
 

	
 
	ShowVehicleViewWindow(v);
 
}
src/economy.cpp
Show inline comments
 
@@ -1488,14 +1488,14 @@ static void HandleStationRefit(Vehicle *
 
			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->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
 
				auto [cc, refit_capacity, mail_capacity] = 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
 
				 * are equal refit to the cargo of which most is available. This is important for
 
				 * consists of only a single vehicle as those will generally have a consist_capleft
 
				 * of 0 for all cargoes. */
 
				if (_returned_refit_capacity > 0 && (consist_capleft[cid] < consist_capleft[new_cid] ||
 
				if (refit_capacity > 0 && (consist_capleft[cid] < consist_capleft[new_cid] ||
 
						(consist_capleft[cid] == consist_capleft[new_cid] &&
 
						st->goods[cid].cargo.AvailableCount() > st->goods[new_cid].cargo.AvailableCount()))) {
 
					new_cid = cid;
 
@@ -1511,7 +1511,7 @@ static void HandleStationRefit(Vehicle *
 
		 * "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->index, new_cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
 
		CommandCost cost = std::get<0>(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;
 
	}
 

	
src/roadveh_cmd.cpp
Show inline comments
 
@@ -295,7 +295,6 @@ CommandCost CmdBuildRoadVehicle(DoComman
 
		v->reliability = e->reliability;
 
		v->reliability_spd_dec = e->reliability_spd_dec;
 
		v->max_age = e->GetLifeLengthInDays();
 
		_new_vehicle_id = v->index;
 

	
 
		v->SetServiceInterval(Company::Get(v->owner)->settings.vehicle.servint_roadveh);
 

	
src/script/api/script_object.cpp
Show inline comments
 
@@ -159,8 +159,6 @@ ScriptObject::ActiveInstance::~ActiveIns
 
/* static */ void ScriptObject::SetLastCommandRes(bool res)
 
{
 
	GetStorage()->last_command_res = res;
 
	/* Also store the results of various global variables */
 
	SetNewVehicleID(_new_vehicle_id);
 
}
 

	
 
/* static */ bool ScriptObject::GetLastCommandRes()
 
@@ -178,16 +176,6 @@ ScriptObject::ActiveInstance::~ActiveIns
 
	return GetStorage()->last_cmd_ret;
 
}
 

	
 
/* static */ void ScriptObject::SetNewVehicleID(VehicleID vehicle_id)
 
{
 
	GetStorage()->new_vehicle_id = vehicle_id;
 
}
 

	
 
/* static */ VehicleID ScriptObject::GetNewVehicleID()
 
{
 
	return GetStorage()->new_vehicle_id;
 
}
 

	
 
/* static */ void ScriptObject::SetAllowDoCommand(bool allow)
 
{
 
	GetStorage()->allow_do_command = allow;
src/script/api/script_object.hpp
Show inline comments
 
@@ -193,11 +193,6 @@ protected:
 
	static const CommandDataBuffer &GetLastCommandResData();
 

	
 
	/**
 
	 * Get the latest stored new_vehicle_id.
 
	 */
 
	static VehicleID GetNewVehicleID();
 

	
 
	/**
 
	 * Store a allow_do_command per company.
 
	 * @param allow The new allow.
 
	 */
 
@@ -274,12 +269,6 @@ protected:
 
	static char *GetString(StringID string);
 

	
 
private:
 
	/**
 
	 * Store a new_vehicle_id per company.
 
	 * @param vehicle_id The new VehicleID.
 
	 */
 
	static void SetNewVehicleID(VehicleID vehicle_id);
 

	
 
	/* Helper functions for DoCommand. */
 
	static std::tuple<bool, bool, bool> DoCommandPrep();
 
	static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only);
src/script/api/script_vehicle.cpp
Show inline comments
 
@@ -94,8 +94,8 @@
 
	if (!ScriptEngine::IsBuildable(engine_id)) return -1;
 
	if (!ScriptCargo::IsValidCargo(cargo)) return -1;
 

	
 
	CommandCost res = ::Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID);
 
	return res.Succeeded() ? _returned_refit_capacity : -1;
 
	auto [res, veh_id, refit_capacity, refit_mail] = ::Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID);
 
	return res.Succeeded() ? refit_capacity : -1;
 
}
 

	
 
/* static */ VehicleID ScriptVehicle::CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders)
 
@@ -143,8 +143,8 @@
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 
	if (!ScriptCargo::IsValidCargo(cargo)) return -1;
 

	
 
	CommandCost res = ::Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0);
 
	return res.Succeeded() ? _returned_refit_capacity : -1;
 
	auto [res, refit_capacity, refit_mail] = ::Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0);
 
	return res.Succeeded() ? refit_capacity : -1;
 
}
 

	
 
/* static */ bool ScriptVehicle::RefitVehicle(VehicleID vehicle_id, CargoID cargo)
src/script/script_instance.cpp
Show inline comments
 
@@ -270,7 +270,7 @@ void ScriptInstance::CollectGarbage()
 

	
 
/* static */ void ScriptInstance::DoCommandReturnVehicleID(ScriptInstance *instance)
 
{
 
	instance->engine->InsertResult(ScriptObject::GetNewVehicleID());
 
	instance->engine->InsertResult(EndianBufferReader::ToValue<VehicleID>(ScriptObject::GetLastCommandResData()));
 
}
 

	
 
/* static */ void ScriptInstance::DoCommandReturnSignID(ScriptInstance *instance)
src/script/script_storage.hpp
Show inline comments
 
@@ -49,8 +49,6 @@ private:
 
	Commands last_cmd;               ///< The last cmd passed to a command.
 
	CommandDataBuffer last_cmd_ret;  ///< The extra data returned by the last command.
 

	
 
	VehicleID new_vehicle_id;        ///< The ID of the new Vehicle.
 

	
 
	std::vector<int> callback_value; ///< The values which need to survive a callback.
 

	
 
	RoadType road_type;              ///< The current roadtype we build.
 
@@ -73,7 +71,6 @@ public:
 
		last_command_res  (true),
 
		last_tile         (INVALID_TILE),
 
		last_cmd          (CMD_END),
 
		new_vehicle_id    (0),
 
		/* calback_value (can't be set) */
 
		road_type         (INVALID_ROADTYPE),
 
		rail_type         (INVALID_RAILTYPE),
src/ship_cmd.cpp
Show inline comments
 
@@ -879,7 +879,6 @@ CommandCost CmdBuildShip(DoCommandFlag f
 
		v->reliability = e->reliability;
 
		v->reliability_spd_dec = e->reliability_spd_dec;
 
		v->max_age = e->GetLifeLengthInDays();
 
		_new_vehicle_id = v->index;
 

	
 
		v->state = TRACK_BIT_DEPOT;
 

	
src/train_cmd.cpp
Show inline comments
 
@@ -641,8 +641,6 @@ static CommandCost CmdBuildRailWagon(DoC
 

	
 
		AddArticulatedParts(v);
 

	
 
		_new_vehicle_id = v->index;
 

	
 
		v->UpdatePosition();
 
		v->First()->ConsistChanged(CCF_ARRANGE);
 
		UpdateTrainGroupID(v->First());
 
@@ -762,7 +760,6 @@ CommandCost CmdBuildRailVehicle(DoComman
 
		v->max_age = e->GetLifeLengthInDays();
 

	
 
		v->railtype = rvi->railtype;
 
		_new_vehicle_id = v->index;
 

	
 
		v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
 
		v->date_of_last_service = _date;
src/train_cmd.h
Show inline comments
 
@@ -25,6 +25,6 @@ DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE,    
 
DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED,     CmdForceTrainProceed,     0, CMDT_VEHICLE_MANAGEMENT)
 
DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT)
 

	
 
CommandCallback CcBuildWagon;
 
void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, TileIndex tile, EngineID, bool, CargoID, ClientID);
 

	
 
#endif /* TRAIN_CMD_H */
src/train_gui.cpp
Show inline comments
 
@@ -24,9 +24,10 @@
 
 * Callback for building wagons.
 
 * @param cmd Unused.
 
 * @param result The result of the command.
 
 * @param new_veh_id ID of the ne vehicle.
 
 * @param tile   The tile the command was executed on.
 
 */
 
void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile)
 
void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, TileIndex tile, EngineID, bool, CargoID, ClientID)
 
{
 
	if (result.Failed()) return;
 

	
 
@@ -43,7 +44,7 @@ void CcBuildWagon(Commands cmd, const Co
 
	if (found != nullptr) {
 
		found = found->Last();
 
		/* put the new wagon at the end of the loco. */
 
		Command<CMD_MOVE_RAIL_VEHICLE>::Post( _new_vehicle_id, found->index, false);
 
		Command<CMD_MOVE_RAIL_VEHICLE>::Post(new_veh_id, found->index, false);
 
		InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
	}
 
}
src/vehicle.cpp
Show inline comments
 
@@ -85,10 +85,6 @@ static const int GEN_HASHY_INC = 1 << GE
 
static const uint GEN_HASHX_MASK =  (1 << GEN_HASHX_BITS) - 1;
 
static const uint GEN_HASHY_MASK = ((1 << GEN_HASHY_BITS) - 1) << GEN_HASHX_BITS;
 

	
 
VehicleID _new_vehicle_id;
 
uint _returned_refit_capacity;        ///< Stores the capacity after a refit operation.
 
uint16 _returned_mail_refit_capacity; ///< Stores the mail capacity after a refit operation (Aircraft only).
 

	
 

	
 
/** The pool with all our precious vehicles. */
 
VehiclePool _vehicle_pool("Vehicle");
 
@@ -1565,7 +1561,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->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0);
 
			CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0));
 
			cur_company.Restore();
 

	
 
			if (cost.Failed()) {
src/vehicle_cmd.cpp
Show inline comments
 
@@ -83,27 +83,27 @@ const StringID _send_to_depot_msg_table[
 
 * @param use_free_vehicles use free vehicles when building the vehicle.
 
 * @param cargo refit cargo type.
 
 * @param client_id User
 
 * @return the cost of this operation or an error
 
 * @return the cost of this operation + the new vehicle ID + the refitted capacity + the refitted mail capacity (aircraft) or an error
 
 */
 
CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id)
 
std::tuple<CommandCost, VehicleID, uint, uint16> CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id)
 
{
 
	/* Elementary check for valid location. */
 
	if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR;
 
	if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 };
 

	
 
	VehicleType type = GetDepotVehicleType(tile);
 

	
 
	/* Validate the engine type. */
 
	if (!IsEngineBuildable(eid, type, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type);
 
	if (!IsEngineBuildable(eid, type, _current_company)) return { CommandCost(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type), INVALID_VEHICLE, 0, 0 };
 

	
 
	/* Validate the cargo type. */
 
	if (cargo >= NUM_CARGO && cargo != CT_INVALID) return CMD_ERROR;
 
	if (cargo >= NUM_CARGO && cargo != CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 };
 

	
 
	const Engine *e = Engine::Get(eid);
 
	CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
 

	
 
	/* Engines without valid cargo should not be available */
 
	CargoID default_cargo = e->GetDefaultCargoType();
 
	if (default_cargo == CT_INVALID) return CMD_ERROR;
 
	if (default_cargo == CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 };
 

	
 
	bool refitting = cargo != CT_INVALID && cargo != default_cargo;
 

	
 
@@ -116,13 +116,13 @@ CommandCost CmdBuildVehicle(DoCommandFla
 
		case VEH_AIRCRAFT: num_vehicles = e->u.air.subtype & AIR_CTOL ? 2 : 3; break;
 
		default: NOT_REACHED(); // Safe due to IsDepotTile()
 
	}
 
	if (!Vehicle::CanAllocateItem(num_vehicles)) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 
	if (!Vehicle::CanAllocateItem(num_vehicles)) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0 };
 

	
 
	/* Check whether we can allocate a unit number. Autoreplace does not allocate
 
	 * an unit number as it will (always) reuse the one of the replaced vehicle
 
	 * and (train) wagons don't have an unit number in any scenario. */
 
	UnitID unit_num = (flags & DC_QUERY_COST || flags & DC_AUTOREPLACE || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type);
 
	if (unit_num == UINT16_MAX) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 
	if (unit_num == UINT16_MAX) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0 };
 

	
 
	/* If we are refitting we need to temporarily purchase the vehicle to be able to
 
	 * test it. */
 
@@ -143,18 +143,24 @@ CommandCost CmdBuildVehicle(DoCommandFla
 
		default: NOT_REACHED(); // Safe due to IsDepotTile()
 
	}
 

	
 
	VehicleID veh_id = INVALID_VEHICLE;
 
	uint refitted_capacity = 0;
 
	uint16 refitted_mail_capacity = 0;
 
	if (value.Succeeded()) {
 
		if (subflags & DC_EXEC) {
 
			v->unitnumber = unit_num;
 
			v->value      = value.GetCost();
 
			veh_id        = v->index;
 
		}
 

	
 
		if (refitting) {
 
			/* Refit only one vehicle. If we purchased an engine, it may have gained free wagons. */
 
			value.AddCost(CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1));
 
			CommandCost cc;
 
			std::tie(cc, refitted_capacity, refitted_mail_capacity) = CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1);
 
			value.AddCost(cc);
 
		} else {
 
			/* Fill in non-refitted capacities */
 
			_returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity);
 
			refitted_capacity = e->GetDisplayDefaultCapacity(&refitted_mail_capacity);
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
@@ -186,7 +192,7 @@ CommandCost CmdBuildVehicle(DoCommandFla
 
	/* Only restore if we actually did some refitting */
 
	if (flags != subflags) RestoreRandomSeeds(saved_seeds);
 

	
 
	return value;
 
	return { value, veh_id, refitted_capacity, refitted_mail_capacity };
 
}
 

	
 
/**
 
@@ -333,9 +339,9 @@ struct RefitResult {
 
 * @param new_subtype  Cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
 
 * @param flags        Command flags
 
 * @param auto_refit   Refitting is done as automatic refitting outside a depot.
 
 * @return Refit cost.
 
 * @return Refit cost + refittet capacity + mail capacity (aircraft).
 
 */
 
static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit)
 
static std::tuple<CommandCost, uint, uint16> RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit)
 
{
 
	CommandCost cost(v->GetExpenseType(false));
 
	uint total_capacity = 0;
 
@@ -441,9 +447,7 @@ static CommandCost RefitVehicle(Vehicle 
 
	}
 

	
 
	refit_result.clear();
 
	_returned_refit_capacity = total_capacity;
 
	_returned_mail_refit_capacity = total_mail_capacity;
 
	return cost;
 
	return { cost, total_capacity, total_mail_capacity };
 
}
 

	
 
/**
 
@@ -458,42 +462,42 @@ static CommandCost RefitVehicle(Vehicle 
 
 *                     Only used if "refit only this vehicle" is false.
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles)
 
std::tuple<CommandCost, uint, uint16> 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(veh_id);
 
	if (v == nullptr) return CMD_ERROR;
 
	if (v == nullptr) return { CMD_ERROR, 0, 0 };
 

	
 
	/* Don't allow disasters and sparks and such to be refitted.
 
	 * We cannot check for IsPrimaryVehicle as autoreplace also refits in free wagon chains. */
 
	if (!IsCompanyBuildableVehicleType(v->type)) return CMD_ERROR;
 
	if (!IsCompanyBuildableVehicleType(v->type)) return { CMD_ERROR, 0, 0 };
 

	
 
	Vehicle *front = v->First();
 

	
 
	CommandCost ret = CheckOwnership(front->owner);
 
	if (ret.Failed()) return ret;
 
	if (ret.Failed()) return { ret, 0, 0 };
 

	
 
	bool free_wagon = v->type == VEH_TRAIN && Train::From(front)->IsFreeWagon(); // used by autoreplace/renew
 

	
 
	/* Don't allow shadows and such to be refitted. */
 
	if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
 
	if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return { CMD_ERROR, 0, 0 };
 

	
 
	/* Allow auto-refitting only during loading and normal refitting only in a depot. */
 
	if ((flags & DC_QUERY_COST) == 0 && // used by the refit GUI, including the order refit GUI.
 
			!free_wagon && // used by autoreplace/renew
 
			(!auto_refit || !front->current_order.IsType(OT_LOADING)) && // refit inside stations
 
			!front->IsStoppedInDepot()) { // refit inside depots
 
		return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
 
		return { CommandCost(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type), 0, 0};
 
	}
 

	
 
	if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);
 
	if (front->vehstatus & VS_CRASHED) return { CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED), 0, 0};
 

	
 
	/* Check cargo */
 
	if (new_cid >= NUM_CARGO) return CMD_ERROR;
 
	if (new_cid >= NUM_CARGO) return { CMD_ERROR, 0, 0 };
 

	
 
	/* For ships and aircraft there is always only one. */
 
	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);
 
	auto [cost, refit_capacity, mail_capacity] = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit);
 

	
 
	if (flags & DC_EXEC) {
 
		/* Update the cached variables */
 
@@ -530,7 +534,7 @@ CommandCost CmdRefitVehicle(DoCommandFla
 
		v->InvalidateNewGRFCacheOfChain();
 
	}
 

	
 
	return cost;
 
	return { cost, refit_capacity, mail_capacity };
 
}
 

	
 
/**
 
@@ -790,14 +794,14 @@ static void CloneVehicleName(const Vehic
 
 * @param tile tile of the depot where the cloned vehicle is build
 
 * @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
 
 * @return the cost of this operation + the new vehicle ID or an error
 
 */
 
CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders)
 
std::tuple<CommandCost, VehicleID> CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders)
 
{
 
	CommandCost total_cost(EXPENSES_NEW_VEHICLES);
 

	
 
	Vehicle *v = Vehicle::GetIfValid(veh_id);
 
	if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
 
	if (v == nullptr || !v->IsPrimaryVehicle()) return { CMD_ERROR, INVALID_VEHICLE };
 
	Vehicle *v_front = v;
 
	Vehicle *w = nullptr;
 
	Vehicle *w_front = nullptr;
 
@@ -812,9 +816,9 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
	 */
 

	
 
	CommandCost ret = CheckOwnership(v->owner);
 
	if (ret.Failed()) return ret;
 
	if (ret.Failed()) return { ret, INVALID_VEHICLE };
 

	
 
	if (v->type == VEH_TRAIN && (!v->IsFrontEngine() || Train::From(v)->crash_anim_pos >= 4400)) return CMD_ERROR;
 
	if (v->type == VEH_TRAIN && (!v->IsFrontEngine() || Train::From(v)->crash_anim_pos >= 4400)) return { CMD_ERROR, INVALID_VEHICLE };
 

	
 
	/* check that we can allocate enough vehicles */
 
	if (!(flags & DC_EXEC)) {
 
@@ -824,12 +828,13 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
		} while ((v = v->Next()) != nullptr);
 

	
 
		if (!Vehicle::CanAllocateItem(veh_counter)) {
 
			return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 
			return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE };
 
		}
 
	}
 

	
 
	v = v_front;
 

	
 
	VehicleID new_veh_id = INVALID_VEHICLE;
 
	do {
 
		if (v->type == VEH_TRAIN && Train::From(v)->IsRearDualheaded()) {
 
			/* we build the rear ends of multiheaded trains with the front ones */
 
@@ -845,18 +850,19 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
		DoCommandFlag build_flags = flags;
 
		if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE;
 

	
 
		CommandCost cost = Command<CMD_BUILD_VEHICLE>::Do(build_flags, tile, v->engine_type, false, CT_INVALID, INVALID_CLIENT_ID);
 
		CommandCost cost;
 
		std::tie(cost, new_veh_id, std::ignore, std::ignore) = Command<CMD_BUILD_VEHICLE>::Do(build_flags, tile, v->engine_type, false, CT_INVALID, INVALID_CLIENT_ID);
 

	
 
		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->index, true, false, INVALID_CLIENT_ID);
 
			return cost;
 
			return { cost, INVALID_VEHICLE };
 
		}
 

	
 
		total_cost.AddCost(cost);
 

	
 
		if (flags & DC_EXEC) {
 
			w = Vehicle::Get(_new_vehicle_id);
 
			w = Vehicle::Get(new_veh_id);
 

	
 
			if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
 
				SetBit(Train::From(w)->flags, VRF_REVERSE_DIRECTION);
 
@@ -871,7 +877,7 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
					 * Sell what we already made (clean up) and return an error.           */
 
					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
 
					return { result, INVALID_VEHICLE }; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE
 
				}
 
			} else {
 
				/* this is a front engine or not a train. */
 
@@ -886,7 +892,7 @@ CommandCost CmdCloneVehicle(DoCommandFla
 

	
 
	if ((flags & DC_EXEC) && v_front->type == VEH_TRAIN) {
 
		/* for trains this needs to be the front engine due to the callback function */
 
		_new_vehicle_id = w_front->index;
 
		new_veh_id = w_front->index;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
@@ -913,7 +919,7 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
				/* 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, w->index, v->cargo_type, subtype, false, true, 0);
 
					CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(flags, w->index, v->cargo_type, subtype, false, true, 0));
 
					if (cost.Succeeded()) total_cost.AddCost(cost);
 
				}
 

	
 
@@ -952,7 +958,7 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
		if (result.Failed()) {
 
			/* The vehicle has already been bought, so now it must be sold again. */
 
			Command<CMD_SELL_VEHICLE>::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID);
 
			return result;
 
			return { total_cost, INVALID_VEHICLE };
 
		}
 

	
 
		/* Now clone the vehicle's name, if it has one. */
 
@@ -963,11 +969,11 @@ CommandCost CmdCloneVehicle(DoCommandFla
 
		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->index, true, false, INVALID_CLIENT_ID);
 
			return total_cost;
 
			return { total_cost, INVALID_VEHICLE };
 
		}
 
	}
 

	
 
	return total_cost;
 
	return { total_cost, new_veh_id };
 
}
 

	
 
/**
src/vehicle_cmd.h
Show inline comments
 
@@ -15,13 +15,13 @@
 
#include "vehicle_type.h"
 
#include "vehiclelist.h"
 

	
 
CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id);
 
std::tuple<CommandCost, VehicleID, uint, uint16> CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id);
 
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);
 
std::tuple<CommandCost, uint, uint16> 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);
 
std::tuple<CommandCost, VehicleID> 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);
 
@@ -39,7 +39,7 @@ DEF_CMD_TRAIT(CMD_MASS_START_STOP,      
 
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)
 

	
 
CommandCallback CcBuildPrimaryVehicle;
 
void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16);
 
void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool);
 

	
 
template <typename Tcont, typename Titer>
src/vehicle_func.h
Show inline comments
 
@@ -164,10 +164,6 @@ static inline StringID GetCmdSendToDepot
 
CommandCost EnsureNoVehicleOnGround(TileIndex tile);
 
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);
 

	
 
extern VehicleID _new_vehicle_id;
 
extern uint _returned_refit_capacity;
 
extern uint16 _returned_mail_refit_capacity;
 

	
 
bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
 
bool CanVehicleUseStation(const Vehicle *v, const struct Station *st);
 

	
src/vehicle_gui.cpp
Show inline comments
 
@@ -776,17 +776,17 @@ struct RefitWindow : public Window {
 
	StringID GetCapacityString(RefitOption *option) const
 
	{
 
		assert(_current_company == _local_company);
 
		CommandCost cost = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles);
 
		auto [cost, refit_capacity, mail_capacity] = 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;
 

	
 
		SetDParam(0, option->cargo);
 
		SetDParam(1, _returned_refit_capacity);
 
		SetDParam(1, refit_capacity);
 

	
 
		Money money = cost.GetCost();
 
		if (_returned_mail_refit_capacity > 0) {
 
		if (mail_capacity > 0) {
 
			SetDParam(2, CT_MAIL);
 
			SetDParam(3, _returned_mail_refit_capacity);
 
			SetDParam(3, mail_capacity);
 
			if (this->order != INVALID_VEH_ORDER_ID) {
 
				/* No predictable cost */
 
				return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY;
 
@@ -3119,15 +3119,15 @@ void StopGlobalFollowVehicle(const Vehic
 

	
 
/**
 
 * This is the Callback method after the construction attempt of a primary vehicle
 
 * @param cmd unused
 
 * @param result indicates completion (or not) of the operation
 
 * @param cmd unused
 
 * @param tile unused
 
 * @param new_veh_id ID of the new vehicle.
 
 */
 
void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, TileIndex tile)
 
void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16)
 
{
 
	if (result.Failed()) return;
 

	
 
	const Vehicle *v = Vehicle::Get(_new_vehicle_id);
 
	const Vehicle *v = Vehicle::Get(new_veh_id);
 
	ShowVehicleViewWindow(v);
 
}
 

	
0 comments (0 inline, 0 general)