Changeset - r28423:a991b75e9b00
[Not reviewed]
master
0 13 0
Peter Nelson - 11 months ago 2024-01-06 15:29:48
peter1138@openttd.org
Codechange: Redefine some cargo-related values in terms of CargoID instead of CargoType.

Values used as special filter types are now defined as offsets from NUM_CARGO instead of confusingly reusing CARGO_NO_REFIT/CARGO_AUTO_REFIT types.
13 files changed with 99 insertions and 103 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -223,48 +223,48 @@ static int GetIncompatibleRefitOrderIdFo
 
/**
 
 * Function to find what type of cargo to refit to when autoreplacing
 
 * @param *v Original vehicle that is being replaced.
 
 * @param engine_type The EngineID of the vehicle that is being replaced to
 
 * @param part_of_chain The vehicle is part of a train
 
 * @return The cargo type to replace to
 
 *    CT_NO_REFIT is returned if no refit is needed
 
 *    CARGO_NO_REFIT is returned if no refit is needed
 
 *    INVALID_CARGO is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible
 
 */
 
static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool part_of_chain)
 
{
 
	CargoTypes available_cargo_types, union_mask;
 
	GetArticulatedRefitMasks(engine_type, true, &union_mask, &available_cargo_types);
 

	
 
	if (union_mask == 0) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity
 
	if (union_mask == 0) return CARGO_NO_REFIT; // Don't try to refit an engine with no cargo capacity
 

	
 
	CargoID cargo_type;
 
	CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type);
 
	if (!HasAtMostOneBit(cargo_mask)) {
 
		CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(engine_type);
 
		if ((cargo_mask & new_engine_default_cargoes) == cargo_mask) {
 
			return CT_NO_REFIT; // engine_type is already a mixed cargo type which matches the incoming vehicle by default, no refit required
 
			return CARGO_NO_REFIT; // engine_type is already a mixed cargo type which matches the incoming vehicle by default, no refit required
 
		}
 

	
 
		return INVALID_CARGO; // We cannot refit to mixed cargoes in an automated way
 
	}
 

	
 
	if (!IsValidCargoID(cargo_type)) {
 
		if (v->type != VEH_TRAIN) return CT_NO_REFIT; // If the vehicle does not carry anything at all, every replacement is fine.
 
		if (v->type != VEH_TRAIN) return CARGO_NO_REFIT; // If the vehicle does not carry anything at all, every replacement is fine.
 

	
 
		if (!part_of_chain) return CT_NO_REFIT;
 
		if (!part_of_chain) return CARGO_NO_REFIT;
 

	
 
		/* the old engine didn't have cargo capacity, but the new one does
 
		 * now we will figure out what cargo the train is carrying and refit to fit this */
 

	
 
		for (v = v->First(); v != nullptr; v = v->Next()) {
 
			if (!v->GetEngine()->CanCarryCargo()) continue;
 
			/* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */
 
			if (HasBit(available_cargo_types, v->cargo_type)) return v->cargo_type;
 
		}
 

	
 
		return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
 
		return CARGO_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
 
	} else {
 
		if (!HasBit(available_cargo_types, cargo_type)) return INVALID_CARGO; // We can't refit the vehicle to carry the cargo we want
 

	
 
		if (part_of_chain && !VerifyAutoreplaceRefitForOrders(v, engine_type)) return INVALID_CARGO; // Some refit orders lose their effect
 

	
 
		return cargo_type;
 
@@ -356,13 +356,13 @@ static CommandCost BuildReplacementVehic
 
	if (cost.Failed()) return cost;
 

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

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

	
 
		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
 
@@ -90,22 +90,18 @@ static const NWidgetPart _nested_build_v
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDE), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_NULL),
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_RENAME), SetResize(1, 0), SetFill(1, 0),
 
		NWidget(WWT_RESIZEBOX, COLOUR_GREY),
 
	EndContainer(),
 
};
 

	
 
/** Special cargo filter criteria */
 
static const CargoID CF_ANY     = CT_NO_REFIT;   ///< Show all vehicles independent of carried cargo (i.e. no filtering)
 
static const CargoID CF_NONE    = INVALID_CARGO; ///< Show only vehicles which do not carry cargo (e.g. train engines)
 
static const CargoID CF_ENGINES = CT_AUTO_REFIT; ///< Show only engines (for rail vehicles only)
 

	
 
bool _engine_sort_direction; ///< \c false = descending, \c true = ascending.
 
byte _engine_sort_last_criteria[]       = {0, 0, 0, 0};                 ///< Last set sort criteria, for each vehicle type.
 
bool _engine_sort_last_order[]          = {false, false, false, false}; ///< Last set direction of the sort order, for each vehicle type.
 
bool _engine_sort_show_hidden_engines[] = {false, false, false, false}; ///< Last set 'show hidden engines' setting for each vehicle type.
 
static CargoID _engine_sort_last_cargo_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_ANY}; ///< Last set filter criteria, for each vehicle type.
 
static CargoID _engine_sort_last_cargo_criteria[] = {CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY}; ///< Last set filter criteria, for each vehicle type.
 

	
 
/**
 
 * Determines order of engines by engineID
 
 * @param a first engine to compare
 
 * @param b second engine to compare
 
 * @return for descending order: returns true if a < b. Vice versa for ascending order
 
@@ -540,19 +536,19 @@ const StringID _engine_sort_listing[][12
 
	INVALID_STRING_ID
 
}};
 

	
 
/** Filters vehicles by cargo and engine (in case of rail vehicle). */
 
static bool CDECL CargoAndEngineFilter(const GUIEngineListItem *item, const CargoID cid)
 
{
 
	if (cid == CF_ANY) {
 
	if (cid == CargoFilterCriteria::CF_ANY) {
 
		return true;
 
	} else if (cid == CF_ENGINES) {
 
	} else if (cid == CargoFilterCriteria::CF_ENGINES) {
 
		return Engine::Get(item->engine_id)->GetPower() != 0;
 
	} else {
 
		CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(item->engine_id, true) & _standard_cargo_mask;
 
		return (cid == CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid));
 
		return (cid == CargoFilterCriteria::CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid));
 
	}
 
}
 

	
 
static GUIEngineList::FilterFunction * const _filter_funcs[] = {
 
	&CargoAndEngineFilter,
 
};
 
@@ -1143,13 +1139,13 @@ struct BuildVehicleWindow : Window {
 
	QueryString vehicle_editbox;                ///< Filter editbox
 

	
 
	void SetBuyVehicleText()
 
	{
 
		NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_BUILD);
 

	
 
		bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter_criteria != CF_ANY && this->cargo_filter_criteria != CF_NONE;
 
		bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY && this->cargo_filter_criteria != CargoFilterCriteria::CF_NONE;
 
		if (refit) refit = Engine::Get(this->sel_engine)->GetDefaultCargoType() != this->cargo_filter_criteria;
 

	
 
		if (refit) {
 
			widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON + this->vehicle_type;
 
			widget->tool_tip    = STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP + this->vehicle_type;
 
		} else {
 
@@ -1269,34 +1265,34 @@ struct BuildVehicleWindow : Window {
 
		}
 
	}
 

	
 
	StringID GetCargoFilterLabel(CargoID cid) const
 
	{
 
		switch (cid) {
 
			case CF_ANY: return STR_PURCHASE_INFO_ALL_TYPES;
 
			case CF_ENGINES: return STR_PURCHASE_INFO_ENGINES_ONLY;
 
			case CF_NONE: return STR_PURCHASE_INFO_NONE;
 
			case CargoFilterCriteria::CF_ANY: return STR_PURCHASE_INFO_ALL_TYPES;
 
			case CargoFilterCriteria::CF_ENGINES: return STR_PURCHASE_INFO_ENGINES_ONLY;
 
			case CargoFilterCriteria::CF_NONE: return STR_PURCHASE_INFO_NONE;
 
			default: return CargoSpec::Get(cid)->name;
 
		}
 
	}
 

	
 
	/** Populate the filter list and set the cargo filter criteria. */
 
	void SetCargoFilterArray()
 
	{
 
		/* Set the last cargo filter criteria. */
 
		this->cargo_filter_criteria = _engine_sort_last_cargo_criteria[this->vehicle_type];
 
		if (this->cargo_filter_criteria < NUM_CARGO && !HasBit(_standard_cargo_mask, this->cargo_filter_criteria)) this->cargo_filter_criteria = CF_ANY;
 
		if (this->cargo_filter_criteria < NUM_CARGO && !HasBit(_standard_cargo_mask, this->cargo_filter_criteria)) this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
 

	
 
		this->eng_list.SetFilterFuncs(_filter_funcs);
 
		this->eng_list.SetFilterState(this->cargo_filter_criteria != CF_ANY);
 
		this->eng_list.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
 
	}
 

	
 
	void SelectEngine(EngineID engine)
 
	{
 
		CargoID cargo = this->cargo_filter_criteria;
 
		if (cargo == CF_ANY || cargo == CF_ENGINES || cargo == CF_NONE) cargo = INVALID_CARGO;
 
		if (cargo == CargoFilterCriteria::CF_ANY || cargo == CargoFilterCriteria::CF_ENGINES || cargo == CargoFilterCriteria::CF_NONE) cargo = INVALID_CARGO;
 

	
 
		this->sel_engine = engine;
 
		this->SetBuyVehicleText();
 

	
 
		if (this->sel_engine == INVALID_ENGINE) return;
 

	
 
@@ -1564,20 +1560,20 @@ struct BuildVehicleWindow : Window {
 

	
 
	DropDownList BuildCargoDropDownList() const
 
	{
 
		DropDownList list;
 

	
 
		/* Add item for disabling filtering. */
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), CF_ANY, false));
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
 
		/* Specific filters for trains. */
 
		if (this->vehicle_type == VEH_TRAIN) {
 
			/* Add item for locomotives only in case of trains. */
 
			list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ENGINES), CF_ENGINES, false));
 
			list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false));
 
			/* Add item for vehicles not carrying anything, e.g. train engines.
 
			 * This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */
 
			list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));
 
			list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
 
		}
 

	
 
		/* Add cargos */
 
		Dimension d = GetLargestCargoIconSize();
 
		for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
 
			list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
 
@@ -1649,13 +1645,13 @@ struct BuildVehicleWindow : Window {
 
			}
 

	
 
			case WID_BV_BUILD: {
 
				EngineID sel_eng = this->sel_engine;
 
				if (sel_eng != INVALID_ENGINE) {
 
					CargoID cargo = this->cargo_filter_criteria;
 
					if (cargo == CF_ANY || cargo == CF_ENGINES || cargo == CF_NONE) cargo = INVALID_CARGO;
 
					if (cargo == CargoFilterCriteria::CF_ANY || cargo == CargoFilterCriteria::CF_ENGINES || cargo == CargoFilterCriteria::CF_NONE) cargo = INVALID_CARGO;
 
					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);
 
					}
 

	
 
@@ -1854,13 +1850,13 @@ struct BuildVehicleWindow : Window {
 

	
 
			case WID_BV_CARGO_FILTER_DROPDOWN: // Select a cargo filter criteria
 
				if (this->cargo_filter_criteria != index) {
 
					this->cargo_filter_criteria = index;
 
					_engine_sort_last_cargo_criteria[this->vehicle_type] = this->cargo_filter_criteria;
 
					/* deactivate filter if criteria is 'Show All', activate it otherwise */
 
					this->eng_list.SetFilterState(this->cargo_filter_criteria != CF_ANY);
 
					this->eng_list.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
 
					this->eng_list.ForceRebuild();
 
					this->SelectEngine(this->sel_engine);
 
				}
 
				break;
 
		}
 
		this->SetDirty();
src/cargo_type.h
Show inline comments
 
@@ -58,22 +58,35 @@ enum CargoType {
 
	CT_COLA         =  7,
 
	CT_COTTON_CANDY =  8,
 
	CT_BUBBLES      =  9,
 
	CT_PLASTIC      = 10,
 
	CT_FIZZY_DRINKS = 11,
 

	
 
	NUM_ORIGINAL_CARGO = 12,
 
	NUM_CARGO       = 64,   ///< Maximal number of cargo types in a game.
 

	
 
	CT_AUTO_REFIT   = 0xFD, ///< Automatically choose cargo type when doing auto refitting.
 
	CT_NO_REFIT     = 0xFE, ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-new).
 
	CT_INVALID      = 0xFF, ///< Invalid cargo type.
 
};
 

	
 
static const CargoID NUM_ORIGINAL_CARGO = 12; ///< Original number of cargo types.
 
static const CargoID NUM_CARGO = 64; ///< Maximum number of cargo types in a game.
 

	
 
/* CARGO_AUTO_REFIT and CARGO_NO_REFIT are stored in save-games for refit-orders, so should not be changed. */
 
static const CargoID CARGO_AUTO_REFIT = 0xFD; ///< Automatically choose cargo type when doing auto refitting.
 
static const CargoID CARGO_NO_REFIT = 0xFE; ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-renew).
 

	
 
static const CargoID INVALID_CARGO = UINT8_MAX;
 

	
 
/**
 
 * Special cargo filter criteria.
 
 * These are used by user interface code only and must not be assigned to any entity. Not all values are valid for every UI filter.
 
 */
 
namespace CargoFilterCriteria {
 
	static constexpr CargoID CF_ANY     = NUM_CARGO;     ///< Show all items independent of carried cargo (i.e. no filtering)
 
	static constexpr CargoID CF_NONE    = NUM_CARGO + 1; ///< Show only items which do not carry cargo (e.g. train engines)
 
	static constexpr CargoID CF_ENGINES = NUM_CARGO + 2; ///< Show only engines (for rail vehicles only)
 
	static constexpr CargoID CF_FREIGHT = NUM_CARGO + 3; ///< Show only vehicles which carry any freight (non-passenger) cargo
 
};
 

	
 
/** Test whether cargo type is not CT_INVALID */
 
inline bool IsValidCargoType(CargoType t) { return t != CT_INVALID; }
 
/** Test whether cargo type is not INVALID_CARGO */
 
inline bool IsValidCargoID(CargoID t) { return t != INVALID_CARGO; }
 

	
 
typedef uint64_t CargoTypes;
src/economy.cpp
Show inline comments
 
@@ -1497,13 +1497,13 @@ static void HandleStationRefit(Vehicle *
 

	
 
	CargoTypes refit_mask = v->GetEngine()->info.refit_mask;
 

	
 
	/* Remove old capacity from consist capacity and collect refit mask. */
 
	IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask));
 

	
 
	bool is_auto_refit = new_cid == CT_AUTO_REFIT;
 
	bool is_auto_refit = new_cid == CARGO_AUTO_REFIT;
 
	if (is_auto_refit) {
 
		/* Get a refittable cargo type with waiting cargo for next_station or INVALID_STATION. */
 
		new_cid = v_start->cargo_type;
 
		for (CargoID cid : SetCargoBitIterator(refit_mask)) {
 
			if (st->goods[cid].cargo.HasCargoFor(next_station)) {
 
				/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
 
@@ -1633,13 +1633,13 @@ static void LoadUnloadVehicle(Vehicle *f
 
	assert(front->current_order.IsType(OT_LOADING));
 

	
 
	StationID last_visited = front->last_station_visited;
 
	Station *st = Station::Get(last_visited);
 

	
 
	StationIDStack next_station = front->GetNextStoppingStation();
 
	bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
 
	bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT;
 
	CargoArray consist_capleft{};
 
	if (_settings_game.order.improved_load && use_autorefit ?
 
			front->cargo_payment == nullptr : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) {
 
		ReserveConsist(st, front,
 
				(use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr,
 
				&next_station);
src/industry_gui.cpp
Show inline comments
 
@@ -1242,18 +1242,12 @@ static const NWidgetPart _nested_industr
 
		NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
 
	EndContainer(),
 
};
 

	
 
typedef GUIList<const Industry *, const CargoID &, const std::pair<CargoID, CargoID> &> GUIIndustryList;
 

	
 
/** Special cargo filter criteria */
 
enum CargoFilterSpecialType {
 
	CF_ANY  = CT_NO_REFIT, ///< Show all industries (i.e. no filtering)
 
	CF_NONE = INVALID_CARGO, ///< Show only industries which do not produce/accept cargo
 
};
 

	
 
/** Cargo filter functions */
 
/**
 
 * Check whether an industry accepts and produces a certain cargo pair.
 
 * @param industry The industry whose cargoes will being checked.
 
 * @param cargoes The accepted and produced cargo pair to look for.
 
 * @return bool Whether the given cargoes accepted and produced by the industry.
 
@@ -1263,33 +1257,33 @@ static bool CDECL CargoFilter(const Indu
 
	auto accepted_cargo = cargoes.first;
 
	auto produced_cargo = cargoes.second;
 

	
 
	bool accepted_cargo_matches;
 

	
 
	switch (accepted_cargo) {
 
		case CF_ANY:
 
		case CargoFilterCriteria::CF_ANY:
 
			accepted_cargo_matches = true;
 
			break;
 

	
 
		case CF_NONE:
 
		case CargoFilterCriteria::CF_NONE:
 
			accepted_cargo_matches = !(*industry)->IsCargoAccepted();
 
			break;
 

	
 
		default:
 
			accepted_cargo_matches = (*industry)->IsCargoAccepted(accepted_cargo);
 
			break;
 
	}
 

	
 
	bool produced_cargo_matches;
 

	
 
	switch (produced_cargo) {
 
		case CF_ANY:
 
		case CargoFilterCriteria::CF_ANY:
 
			produced_cargo_matches = true;
 
			break;
 

	
 
		case CF_NONE:
 
		case CargoFilterCriteria::CF_NONE:
 
			produced_cargo_matches = !(*industry)->IsCargoProduced();
 
			break;
 

	
 
		default:
 
			produced_cargo_matches = (*industry)->IsCargoProduced(produced_cargo);
 
			break;
 
@@ -1341,13 +1335,13 @@ protected:
 
	 */
 
	void SetProducedCargoFilter(CargoID cid)
 
	{
 
		if (this->produced_cargo_filter_criteria != cid) {
 
			this->produced_cargo_filter_criteria = cid;
 
			/* deactivate filter if criteria is 'Show All', activate it otherwise */
 
			bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
 
			bool is_filtering_necessary = this->produced_cargo_filter_criteria != CargoFilterCriteria::CF_ANY || this->accepted_cargo_filter_criteria != CargoFilterCriteria::CF_ANY;
 

	
 
			this->industries.SetFilterState(is_filtering_necessary);
 
			this->industries.SetFilterType(0);
 
			this->industries.ForceRebuild();
 
		}
 
	}
 
@@ -1358,40 +1352,40 @@ protected:
 
	 */
 
	void SetAcceptedCargoFilter(CargoID cid)
 
	{
 
		if (this->accepted_cargo_filter_criteria != cid) {
 
			this->accepted_cargo_filter_criteria = cid;
 
			/* deactivate filter if criteria is 'Show All', activate it otherwise */
 
			bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
 
			bool is_filtering_necessary = this->produced_cargo_filter_criteria != CargoFilterCriteria::CF_ANY || this->accepted_cargo_filter_criteria != CargoFilterCriteria::CF_ANY;
 

	
 
			this->industries.SetFilterState(is_filtering_necessary);
 
			this->industries.SetFilterType(0);
 
			this->industries.ForceRebuild();
 
		}
 
	}
 

	
 
	StringID GetCargoFilterLabel(CargoID cid) const
 
	{
 
		switch (cid) {
 
			case CF_ANY: return STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
 
			case CF_NONE: return STR_INDUSTRY_DIRECTORY_FILTER_NONE;
 
			case CargoFilterCriteria::CF_ANY: return STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
 
			case CargoFilterCriteria::CF_NONE: return STR_INDUSTRY_DIRECTORY_FILTER_NONE;
 
			default: return CargoSpec::Get(cid)->name;
 
		}
 
	}
 

	
 
	/**
 
	 * Populate the filter list and set the cargo filter criteria.
 
	 */
 
	void SetCargoFilterArray()
 
	{
 
		this->produced_cargo_filter_criteria = CF_ANY;
 
		this->accepted_cargo_filter_criteria = CF_ANY;
 
		this->produced_cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
 
		this->accepted_cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
 

	
 
		this->industries.SetFilterFuncs(_filter_funcs);
 

	
 
		bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
 
		bool is_filtering_necessary = this->produced_cargo_filter_criteria != CargoFilterCriteria::CF_ANY || this->accepted_cargo_filter_criteria != CargoFilterCriteria::CF_ANY;
 

	
 
		this->industries.SetFilterState(is_filtering_necessary);
 
	}
 

	
 
	/**
 
	 * Get the width needed to draw the longest industry line.
 
@@ -1459,17 +1453,17 @@ protected:
 
	 * @param i industry to check
 
	 * @return value used for sorting
 
	 */
 
	static int GetCargoTransportedSortValue(const Industry *i)
 
	{
 
		CargoID filter = IndustryDirectoryWindow::produced_cargo_filter;
 
		if (filter == CF_NONE) return 0;
 
		if (filter == CargoFilterCriteria::CF_NONE) return 0;
 

	
 
		int percentage = 0, produced_cargo_count = 0;
 
		for (const auto &p : i->produced) {
 
			if (filter == CF_ANY) {
 
			if (filter == CargoFilterCriteria::CF_ANY) {
 
				int transported = GetCargoTransportedPercentsIfValid(p);
 
				if (transported != -1) {
 
					produced_cargo_count++;
 
					percentage += transported;
 
				}
 
				if (produced_cargo_count == 0 && &p == &i->produced.back() && percentage == 0) {
 
@@ -1503,16 +1497,16 @@ protected:
 
		return (r == 0) ? IndustryNameSorter(a, b, filter) : r < 0;
 
	}
 

	
 
	/** Sort industries by production and name */
 
	static bool IndustryProductionSorter(const Industry * const &a, const Industry * const &b, const CargoID &filter)
 
	{
 
		if (filter == CF_NONE) return IndustryTypeSorter(a, b, filter);
 
		if (filter == CargoFilterCriteria::CF_NONE) return IndustryTypeSorter(a, b, filter);
 

	
 
		uint prod_a = 0, prod_b = 0;
 
		if (filter == CF_ANY) {
 
		if (filter == CargoFilterCriteria::CF_ANY) {
 
			for (const auto &pa : a->produced) {
 
				if (IsValidCargoID(pa.cargo)) prod_a += pa.history[LAST_MONTH].production;
 
			}
 
			for (const auto &pb : b->produced) {
 
				if (IsValidCargoID(pb.cargo)) prod_b += pb.history[LAST_MONTH].production;
 
			}
 
@@ -1582,13 +1576,13 @@ protected:
 
				break;
 
		}
 

	
 
		/* If the produced cargo filter is active then move the filtered cargo to the beginning of the list,
 
		 * because this is the one the player interested in, and that way it is not hidden in the 'n' more cargos */
 
		const CargoID cid = this->produced_cargo_filter_criteria;
 
		if (cid != CF_ANY && cid != CF_NONE) {
 
		if (cid != CargoFilterCriteria::CF_ANY && cid != CargoFilterCriteria::CF_NONE) {
 
			auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](const CargoInfo &ci) -> bool {
 
				return ci.cargo_id == cid;
 
			});
 
			if (filtered_ci != cargos.end()) {
 
				std::rotate(cargos.begin(), filtered_ci, filtered_ci + 1);
 
			}
 
@@ -1690,13 +1684,13 @@ public:
 
					break;
 
				}
 
				int n = 0;
 
				const CargoID acf_cid = this->accepted_cargo_filter_criteria;
 
				for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) {
 
					TextColour tc = TC_FROMSTRING;
 
					if (acf_cid != CF_ANY && acf_cid != CF_NONE) {
 
					if (acf_cid != CargoFilterCriteria::CF_ANY && acf_cid != CargoFilterCriteria::CF_NONE) {
 
						Industry *ind = const_cast<Industry *>(this->industries[i]);
 
						if (IndustryTemporarilyRefusesCargo(ind, acf_cid)) {
 
							tc = TC_GREY | TC_FORCED;
 
						}
 
					}
 
					DrawString(ir, this->GetIndustryString(this->industries[i]), tc);
 
@@ -1745,15 +1739,15 @@ public:
 

	
 
	DropDownList BuildCargoDropDownList() const
 
	{
 
		DropDownList list;
 

	
 
		/* Add item for disabling filtering. */
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), CF_ANY, false));
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
 
		/* Add item for industries not producing anything, e.g. power plants */
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));
 
		list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
 

	
 
		/* Add cargos */
 
		Dimension d = GetLargestCargoIconSize();
 
		for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
 
			list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
 
		}
 
@@ -1903,13 +1897,13 @@ const StringID IndustryDirectoryWindow::
 
	STR_SORT_BY_TYPE,
 
	STR_SORT_BY_PRODUCTION,
 
	STR_SORT_BY_TRANSPORTED,
 
	INVALID_STRING_ID
 
};
 

	
 
CargoID IndustryDirectoryWindow::produced_cargo_filter = CF_ANY;
 
CargoID IndustryDirectoryWindow::produced_cargo_filter = CargoFilterCriteria::CF_ANY;
 

	
 

	
 
/** Window definition of the industry directory gui */
 
static WindowDesc _industry_directory_desc(__FILE__, __LINE__,
 
	WDP_AUTO, "list_industries", 428, 190,
 
	WC_INDUSTRY_DIRECTORY, WC_NONE,
src/order_base.h
Show inline comments
 
@@ -55,13 +55,13 @@ private:
 
	uint16_t travel_time;  ///< How long in ticks the journey to this destination should take.
 
	uint16_t max_speed;    ///< How fast the vehicle may go on the way to the destination.
 

	
 
public:
 
	Order *next;          ///< Pointer to next order. If nullptr, end of list
 

	
 
	Order() : flags(0), refit_cargo(CT_NO_REFIT), wait_time(0), travel_time(0), max_speed(UINT16_MAX) {}
 
	Order() : flags(0), refit_cargo(CARGO_NO_REFIT), wait_time(0), travel_time(0), max_speed(UINT16_MAX) {}
 
	~Order();
 

	
 
	Order(uint32_t packed);
 

	
 
	/**
 
	 * Check whether this order is of the given type.
 
@@ -76,13 +76,13 @@ public:
 
	 */
 
	inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); }
 

	
 
	void Free();
 

	
 
	void MakeGoToStation(StationID destination);
 
	void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CT_NO_REFIT);
 
	void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CARGO_NO_REFIT);
 
	void MakeGoToWaypoint(StationID destination);
 
	void MakeLoading(bool ordered);
 
	void MakeLeaveStation();
 
	void MakeDummy();
 
	void MakeConditional(VehicleOrderID order);
 
	void MakeImplicit(StationID destination);
 
@@ -112,20 +112,20 @@ public:
 

	
 
	/**
 
	 * Is this order a refit order.
 
	 * @pre IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION)
 
	 * @return true if a refit should happen.
 
	 */
 
	inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO || this->refit_cargo == CT_AUTO_REFIT; }
 
	inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO || this->refit_cargo == CARGO_AUTO_REFIT; }
 

	
 
	/**
 
	 * Is this order a auto-refit order.
 
	 * @pre IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION)
 
	 * @return true if a auto-refit should happen.
 
	 */
 
	inline bool IsAutoRefit() const { return this->refit_cargo == CT_AUTO_REFIT; }
 
	inline bool IsAutoRefit() const { return this->refit_cargo == CARGO_AUTO_REFIT; }
 

	
 
	/**
 
	 * Get the cargo to to refit to.
 
	 * @pre IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION)
 
	 * @return the cargo type.
 
	 */
src/order_cmd.cpp
Show inline comments
 
@@ -234,13 +234,13 @@ uint16_t Order::MapOldOrder() const
 
Order::Order(uint32_t packed)
 
{
 
	this->type    = (OrderType)GB(packed,  0,  8);
 
	this->flags   = GB(packed,  8,  8);
 
	this->dest    = GB(packed, 16, 16);
 
	this->next    = nullptr;
 
	this->refit_cargo   = CT_NO_REFIT;
 
	this->refit_cargo   = CARGO_NO_REFIT;
 
	this->wait_time     = 0;
 
	this->travel_time   = 0;
 
	this->max_speed     = UINT16_MAX;
 
}
 

	
 
/**
 
@@ -716,13 +716,13 @@ CommandCost CmdInsertOrder(DoCommandFlag
 
	if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
 

	
 
	CommandCost ret = CheckOwnership(v->owner);
 
	if (ret.Failed()) return ret;
 

	
 
	/* Validate properties we don't want to have different from default as they are set by other commands. */
 
	if (new_order.GetRefitCargo() != CT_NO_REFIT || new_order.GetWaitTime() != 0 || new_order.GetTravelTime() != 0 || new_order.GetMaxSpeed() != UINT16_MAX) return CMD_ERROR;
 
	if (new_order.GetRefitCargo() != CARGO_NO_REFIT || new_order.GetWaitTime() != 0 || new_order.GetTravelTime() != 0 || new_order.GetMaxSpeed() != UINT16_MAX) return CMD_ERROR;
 

	
 
	/* Check if the inserted order is to the correct destination (owner, type),
 
	 * and has the correct flags if any */
 
	switch (new_order.GetType()) {
 
		case OT_GOTO_STATION: {
 
			const Station *st = Station::GetIfValid(new_order.GetDestination());
 
@@ -1323,13 +1323,13 @@ CommandCost CmdModifyOrder(DoCommandFlag
 

	
 
	if (flags & DC_EXEC) {
 
		switch (mof) {
 
			case MOF_NON_STOP:
 
				order->SetNonStopType((OrderNonStopFlags)data);
 
				if (data & ONSF_NO_STOP_AT_DESTINATION_STATION) {
 
					order->SetRefit(CT_NO_REFIT);
 
					order->SetRefit(CARGO_NO_REFIT);
 
					order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
 
					order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
 
				}
 
				break;
 

	
 
			case MOF_STOP_LOCATION:
 
@@ -1339,32 +1339,32 @@ CommandCost CmdModifyOrder(DoCommandFlag
 
			case MOF_UNLOAD:
 
				order->SetUnloadType((OrderUnloadFlags)data);
 
				break;
 

	
 
			case MOF_LOAD:
 
				order->SetLoadType((OrderLoadFlags)data);
 
				if (data & OLFB_NO_LOAD) order->SetRefit(CT_NO_REFIT);
 
				if (data & OLFB_NO_LOAD) order->SetRefit(CARGO_NO_REFIT);
 
				break;
 

	
 
			case MOF_DEPOT_ACTION: {
 
				switch (data) {
 
					case DA_ALWAYS_GO:
 
						order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
 
						order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
 
						break;
 

	
 
					case DA_SERVICE:
 
						order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() | ODTFB_SERVICE));
 
						order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
 
						order->SetRefit(CT_NO_REFIT);
 
						order->SetRefit(CARGO_NO_REFIT);
 
						break;
 

	
 
					case DA_STOP:
 
						order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
 
						order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() | ODATFB_HALT));
 
						order->SetRefit(CT_NO_REFIT);
 
						order->SetRefit(CARGO_NO_REFIT);
 
						break;
 

	
 
					default:
 
						NOT_REACHED();
 
				}
 
				break;
 
@@ -1615,33 +1615,33 @@ CommandCost CmdCloneOrder(DoCommandFlag 
 
 * @param order_number number of order to modify
 
 * @param cargo CargoID
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdOrderRefit(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, CargoID cargo)
 
{
 
	if (cargo >= NUM_CARGO && cargo != CT_NO_REFIT && cargo != CT_AUTO_REFIT) return CMD_ERROR;
 
	if (cargo >= NUM_CARGO && cargo != CARGO_NO_REFIT && cargo != CARGO_AUTO_REFIT) return CMD_ERROR;
 

	
 
	const Vehicle *v = Vehicle::GetIfValid(veh);
 
	if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
 

	
 
	CommandCost ret = CheckOwnership(v->owner);
 
	if (ret.Failed()) return ret;
 

	
 
	Order *order = v->GetOrder(order_number);
 
	if (order == nullptr) return CMD_ERROR;
 

	
 
	/* Automatic refit cargo is only supported for goto station orders. */
 
	if (cargo == CT_AUTO_REFIT && !order->IsType(OT_GOTO_STATION)) return CMD_ERROR;
 
	if (cargo == CARGO_AUTO_REFIT && !order->IsType(OT_GOTO_STATION)) return CMD_ERROR;
 

	
 
	if (order->GetLoadType() & OLFB_NO_LOAD) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		order->SetRefit(cargo);
 

	
 
		/* Make the depot order an 'always go' order. */
 
		if (cargo != CT_NO_REFIT && order->IsType(OT_GOTO_DEPOT)) {
 
		if (cargo != CARGO_NO_REFIT && order->IsType(OT_GOTO_DEPOT)) {
 
			order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
 
			order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
 
		}
 

	
 
		for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
 
			/* Update any possible open window of the vehicle */
src/order_gui.cpp
Show inline comments
 
@@ -746,16 +746,16 @@ private:
 
	 * @param auto_refit Select refit for auto-refitting.
 
	 */
 
	void OrderClick_Refit(int i, bool auto_refit)
 
	{
 
		if (_ctrl_pressed) {
 
			/* Cancel refitting */
 
			Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CT_NO_REFIT);
 
			Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_NO_REFIT);
 
		} else {
 
			if (i == 1) { // Auto-refit to available cargo type.
 
				Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CT_AUTO_REFIT);
 
				Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CARGO_AUTO_REFIT);
 
			} else {
 
				ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit);
 
			}
 
		}
 
	}
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -1459,17 +1459,17 @@ bool AfterLoadGame()
 
		}
 
	}
 

	
 
	/* Setting no refit flags to all orders in savegames from before refit in orders were added */
 
	if (IsSavegameVersionBefore(SLV_36)) {
 
		for (Order *order : Order::Iterate()) {
 
			order->SetRefit(CT_NO_REFIT);
 
			order->SetRefit(CARGO_NO_REFIT);
 
		}
 

	
 
		for (Vehicle *v : Vehicle::Iterate()) {
 
			v->current_order.SetRefit(CT_NO_REFIT);
 
			v->current_order.SetRefit(CARGO_NO_REFIT);
 
		}
 
	}
 

	
 
	/* from version 38 we have optional elrails, since we cannot know the
 
	 * preference of a user, let elrails enabled; it can be disabled manually */
 
	if (IsSavegameVersionBefore(SLV_38)) _settings_game.vehicle.disable_elrails = false;
src/script/api/script_cargo.hpp
Show inline comments
 
@@ -52,14 +52,14 @@ public:
 

	
 
	/**
 
	 * Special cargo types.
 
	 */
 
	enum SpecialCargoID {
 
		/* Note: these values represent part of the in-game CargoTypes enum */
 
		CT_AUTO_REFIT = ::CT_AUTO_REFIT, ///< Automatically choose cargo type when doing auto-refitting.
 
		CT_NO_REFIT   = ::CT_NO_REFIT,   ///< Do not refit cargo of a vehicle.
 
		CT_AUTO_REFIT = ::CARGO_AUTO_REFIT, ///< Automatically choose cargo type when doing auto-refitting.
 
		CT_NO_REFIT   = ::CARGO_NO_REFIT, ///< Do not refit cargo of a vehicle.
 
		CT_INVALID    = ::INVALID_CARGO, ///< An invalid cargo type.
 
	};
 

	
 
	/**
 
	 * Type of cargo distribution.
 
	 */
src/script/api/script_order.cpp
Show inline comments
 
@@ -369,17 +369,17 @@ static int ScriptOrderPositionToRealOrde
 
	const Order *order = ::ResolveOrder(vehicle_id, order_position);
 
	return (ScriptOrder::StopLocation)order->GetStopLocation();
 
}
 

	
 
/* static */ CargoID ScriptOrder::GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return CT_NO_REFIT;
 
	if (order_position != ORDER_CURRENT && !IsGotoStationOrder(vehicle_id, order_position) && !IsGotoDepotOrder(vehicle_id, order_position)) return CT_NO_REFIT;
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return CARGO_NO_REFIT;
 
	if (order_position != ORDER_CURRENT && !IsGotoStationOrder(vehicle_id, order_position) && !IsGotoDepotOrder(vehicle_id, order_position)) return CARGO_NO_REFIT;
 

	
 
	const Order *order = ::ResolveOrder(vehicle_id, order_position);
 
	return order->IsRefit() ? order->GetRefitCargo() : (CargoID)CT_NO_REFIT;
 
	return order->IsRefit() ? order->GetRefitCargo() : CARGO_NO_REFIT;
 
}
 

	
 
/* static */ bool ScriptOrder::SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to)
 
{
 
	EnforceCompanyModeValid(false);
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
 
@@ -438,14 +438,14 @@ static int ScriptOrderPositionToRealOrde
 
}
 

	
 
/* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo)
 
{
 
	EnforceCompanyModeValid(false);
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
 
	EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT));
 
	EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT);
 
	EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CARGO_AUTO_REFIT));
 
	EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CARGO_AUTO_REFIT || refit_cargo == CARGO_NO_REFIT);
 

	
 
	return ScriptObject::Command<CMD_ORDER_REFIT>::Do(0, vehicle_id, ScriptOrderPositionToRealOrderPosition(vehicle_id, ScriptOrder::ResolveOrderPosition(vehicle_id, order_position)), refit_cargo);
 
}
 

	
 
/* static */ bool ScriptOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags)
 
{
src/vehicle_gui.cpp
Show inline comments
 
@@ -242,22 +242,22 @@ void BaseVehicleListWindow::BuildVehicle
 
 * @param v The vehicle to check.
 
 * @param cid The cargo to filter for.
 
 * @return true iff the vehicle carries the cargo.
 
 */
 
static bool CargoFilterSingle(const Vehicle *v, const CargoID cid)
 
{
 
	if (cid == BaseVehicleListWindow::CF_ANY) {
 
	if (cid == CargoFilterCriteria::CF_ANY) {
 
		return true;
 
	} else if (cid == BaseVehicleListWindow::CF_NONE) {
 
	} else if (cid == CargoFilterCriteria::CF_NONE) {
 
		for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
 
			if (w->cargo_cap > 0) {
 
				return false;
 
			}
 
		}
 
		return true;
 
	} else if (cid == BaseVehicleListWindow::CF_FREIGHT) {
 
	} else if (cid == CargoFilterCriteria::CF_FREIGHT) {
 
		bool have_capacity = false;
 
		for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
 
			if (w->cargo_cap > 0) {
 
				if (IsCargoInClass(w->cargo_type, CC_PASSENGERS)) {
 
					return false;
 
				} else {
 
@@ -305,26 +305,26 @@ static GUIVehicleGroupList::FilterFuncti
 
 */
 
void BaseVehicleListWindow::SetCargoFilter(CargoID cid)
 
{
 
	if (this->cargo_filter_criteria != cid) {
 
		this->cargo_filter_criteria = cid;
 
		/* Deactivate filter if criteria is 'Show All', activate it otherwise. */
 
		this->vehgroups.SetFilterState(this->cargo_filter_criteria != CF_ANY);
 
		this->vehgroups.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
 
		this->vehgroups.SetFilterType(0);
 
		this->vehgroups.ForceRebuild();
 
	}
 
}
 

	
 
/**
 
 *Populate the filter list and set the cargo filter criteria.
 
 */
 
void BaseVehicleListWindow::SetCargoFilterArray()
 
{
 
	this->cargo_filter_criteria = CF_ANY;
 
	this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
 
	this->vehgroups.SetFilterFuncs(_filter_funcs);
 
	this->vehgroups.SetFilterState(this->cargo_filter_criteria != CF_ANY);
 
	this->vehgroups.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
 
}
 

	
 
/**
 
 *Filter the engine list against the currently selected cargo filter.
 
 */
 
void BaseVehicleListWindow::FilterVehicleList()
 
@@ -369,15 +369,15 @@ void BaseVehicleListWindow::OnInit()
 
	this->SetCargoFilterArray();
 
}
 

	
 
StringID BaseVehicleListWindow::GetCargoFilterLabel(CargoID cid) const
 
{
 
	switch (cid) {
 
		case CF_ANY: return STR_CARGO_TYPE_FILTER_ALL;
 
		case CF_FREIGHT: return STR_CARGO_TYPE_FILTER_FREIGHT;
 
		case CF_NONE: return STR_CARGO_TYPE_FILTER_NONE;
 
		case CargoFilterCriteria::CF_ANY: return STR_CARGO_TYPE_FILTER_ALL;
 
		case CargoFilterCriteria::CF_FREIGHT: return STR_CARGO_TYPE_FILTER_FREIGHT;
 
		case CargoFilterCriteria::CF_NONE: return STR_CARGO_TYPE_FILTER_NONE;
 
		default: return CargoSpec::Get(cid)->name;
 
	}
 
}
 

	
 
/**
 
 * Build drop down list for cargo filter selection.
 
@@ -386,17 +386,17 @@ StringID BaseVehicleListWindow::GetCargo
 
 */
 
DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const
 
{
 
	DropDownList list;
 

	
 
	/* Add item for disabling filtering. */
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), CF_ANY, false));
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
 
	/* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_FREIGHT), CF_FREIGHT, false));
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT, false));
 
	/* Add item for vehicles not carrying anything, e.g. train engines. */
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));
 
	list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
 

	
 
	/* Add cargos */
 
	Dimension d = GetLargestCargoIconSize();
 
	for (const CargoSpec *cs : _sorted_cargo_specs) {
 
		if (!full && !HasBit(this->used_cargoes, cs->Index())) continue;
 
		list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index())));
src/vehicle_gui_base.h
Show inline comments
 
@@ -70,19 +70,12 @@ struct BaseVehicleListWindow : public Wi
 
		GB_NONE,
 
		GB_SHARED_ORDERS,
 

	
 
		GB_END,
 
	};
 

	
 
	/** Special cargo filter criteria */
 
	enum CargoFilterSpecialType {
 
		CF_NONE = INVALID_CARGO,    ///< Show only vehicles which do not carry cargo (e.g. train engines)
 
		CF_ANY = CT_NO_REFIT,       ///< Show all vehicles independent of carried cargo (i.e. no filtering)
 
		CF_FREIGHT = CT_AUTO_REFIT, ///< Show only vehicles which carry any freight (non-passenger) cargo
 
	};
 

	
 
	GroupBy grouping;                           ///< How we want to group the list.
 
	VehicleList vehicles;                       ///< List of vehicles.  This is the buffer for `vehgroups` to point into; if this is structurally modified, `vehgroups` must be rebuilt.
 
	GUIVehicleGroupList vehgroups;              ///< List of (groups of) vehicles.  This stores iterators of `vehicles`, and should be rebuilt if `vehicles` is structurally changed.
 
	Listing *sorting;                           ///< Pointer to the vehicle type related sorting.
 
	byte unitnumber_digits;                     ///< The number of digits of the highest unit number.
 
	Scrollbar *vscroll;
0 comments (0 inline, 0 general)