mirror of https://github.com/OpenTTD/OpenTTD
Merge b9eac1ee78
into 9bcf1cf29b
commit
71eca36493
|
@ -117,12 +117,12 @@ static inline std::pair<CargoType, uint16_t> GetVehicleDefaultCapacity(EngineID
|
|||
static inline CargoTypes GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type)
|
||||
{
|
||||
const Engine *e = Engine::Get(engine);
|
||||
if (!e->CanCarryCargo()) return 0;
|
||||
if (!e->CanCarryCargo()) return {};
|
||||
|
||||
CargoTypes cargoes = e->info.refit_mask;
|
||||
|
||||
if (include_initial_cargo_type) {
|
||||
SetBit(cargoes, e->GetDefaultCargoType());
|
||||
cargoes.Set(e->GetDefaultCargoType());
|
||||
}
|
||||
|
||||
return cargoes;
|
||||
|
@ -165,11 +165,11 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine)
|
|||
*/
|
||||
CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine)
|
||||
{
|
||||
CargoTypes cargoes = 0;
|
||||
CargoTypes cargoes{};
|
||||
const Engine *e = Engine::Get(engine);
|
||||
|
||||
if (auto [cargo, cap] = GetVehicleDefaultCapacity(engine); IsValidCargoType(cargo) && cap > 0) {
|
||||
SetBit(cargoes, cargo);
|
||||
cargoes.Set(cargo);
|
||||
}
|
||||
|
||||
if (!e->IsGroundVehicle()) return cargoes;
|
||||
|
@ -181,7 +181,7 @@ CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine)
|
|||
if (artic_engine == EngineID::Invalid()) break;
|
||||
|
||||
if (auto [cargo, cap] = GetVehicleDefaultCapacity(artic_engine); IsValidCargoType(cargo) && cap > 0) {
|
||||
SetBit(cargoes, cargo);
|
||||
cargoes.Set(cargo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type,
|
|||
const Engine *e = Engine::Get(engine);
|
||||
CargoTypes veh_cargoes = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type);
|
||||
*union_mask = veh_cargoes;
|
||||
*intersection_mask = (veh_cargoes != 0) ? veh_cargoes : ALL_CARGOTYPES;
|
||||
*intersection_mask = veh_cargoes.Any() ? veh_cargoes : ALL_CARGOTYPES;
|
||||
|
||||
if (!e->IsGroundVehicle()) return;
|
||||
if (!e->info.callback_mask.Test(VehicleCallbackMask::ArticEngine)) return;
|
||||
|
@ -234,8 +234,8 @@ void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type,
|
|||
if (artic_engine == EngineID::Invalid()) break;
|
||||
|
||||
veh_cargoes = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type);
|
||||
*union_mask |= veh_cargoes;
|
||||
if (veh_cargoes != 0) *intersection_mask &= veh_cargoes;
|
||||
union_mask->Set(veh_cargoes);
|
||||
if (veh_cargoes.Any()) *intersection_mask = *intersection_mask & veh_cargoes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,12 +261,12 @@ CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial
|
|||
*/
|
||||
CargoTypes GetCargoTypesOfArticulatedVehicle(const Vehicle *v, CargoType *cargo_type)
|
||||
{
|
||||
CargoTypes cargoes = 0;
|
||||
CargoTypes cargoes{};
|
||||
CargoType first_cargo = INVALID_CARGO;
|
||||
|
||||
do {
|
||||
if (IsValidCargoType(v->cargo_type) && v->GetEngine()->CanCarryCargo()) {
|
||||
SetBit(cargoes, v->cargo_type);
|
||||
cargoes.Set(v->cargo_type);
|
||||
if (!IsValidCargoType(first_cargo)) first_cargo = v->cargo_type;
|
||||
if (first_cargo != v->cargo_type) {
|
||||
if (cargo_type != nullptr) {
|
||||
|
@ -299,24 +299,24 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
|
|||
GetArticulatedRefitMasks(v->engine_type, true, &purchase_refit_union, &purchase_refit_intersection);
|
||||
CargoArray purchase_default_capacity = GetCapacityOfArticulatedParts(v->engine_type);
|
||||
|
||||
CargoTypes real_refit_union = 0;
|
||||
CargoTypes real_refit_union{};
|
||||
CargoTypes real_refit_intersection = ALL_CARGOTYPES;
|
||||
CargoTypes real_default_cargoes = 0;
|
||||
CargoTypes real_default_cargoes{};
|
||||
|
||||
do {
|
||||
CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true);
|
||||
real_refit_union |= refit_mask;
|
||||
if (refit_mask != 0) real_refit_intersection &= refit_mask;
|
||||
real_refit_union.Set(refit_mask);
|
||||
if (refit_mask.Any()) real_refit_intersection = real_refit_intersection & refit_mask;
|
||||
|
||||
assert(v->cargo_type < NUM_CARGO);
|
||||
if (v->cargo_cap > 0) SetBit(real_default_cargoes, v->cargo_type);
|
||||
if (v->cargo_cap > 0) real_default_cargoes.Set(v->cargo_type);
|
||||
|
||||
v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr;
|
||||
} while (v != nullptr);
|
||||
|
||||
/* Check whether the vehicle carries more cargoes than expected */
|
||||
bool carries_more = false;
|
||||
for (CargoType cargo_type : SetCargoBitIterator(real_default_cargoes)) {
|
||||
for (CargoType cargo_type : real_default_cargoes) {
|
||||
if (purchase_default_capacity[cargo_type] == 0) {
|
||||
carries_more = true;
|
||||
break;
|
||||
|
|
|
@ -47,7 +47,7 @@ static bool EnginesHaveCargoInCommon(EngineID engine_a, EngineID engine_b)
|
|||
{
|
||||
CargoTypes available_cargoes_a = GetUnionOfArticulatedRefitMasks(engine_a, true);
|
||||
CargoTypes available_cargoes_b = GetUnionOfArticulatedRefitMasks(engine_b, true);
|
||||
return (available_cargoes_a == 0 || available_cargoes_b == 0 || (available_cargoes_a & available_cargoes_b) != 0);
|
||||
return available_cargoes_a.None() || available_cargoes_b.None() || available_cargoes_a.Any(available_cargoes_b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,8 +189,8 @@ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_ty
|
|||
if (!o.IsRefit() || o.IsAutoRefit()) continue;
|
||||
CargoType cargo_type = o.GetRefitCargo();
|
||||
|
||||
if (!HasBit(union_refit_mask_a, cargo_type)) continue;
|
||||
if (!HasBit(union_refit_mask_b, cargo_type)) return false;
|
||||
if (!union_refit_mask_a.Test(cargo_type)) continue;
|
||||
if (!union_refit_mask_b.Test(cargo_type)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -213,7 +213,7 @@ static int GetIncompatibleRefitOrderIdForAutoreplace(const Vehicle *v, EngineID
|
|||
for (VehicleOrderID i = 0; i < orders->GetNumOrders(); i++) {
|
||||
const Order *o = orders->GetOrderAt(i);
|
||||
if (!o->IsRefit()) continue;
|
||||
if (!HasBit(union_refit_mask, o->GetRefitCargo())) return i;
|
||||
if (!union_refit_mask.Test(o->GetRefitCargo())) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -233,11 +233,11 @@ static CargoType GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, boo
|
|||
CargoTypes available_cargo_types, union_mask;
|
||||
GetArticulatedRefitMasks(engine_type, true, &union_mask, &available_cargo_types);
|
||||
|
||||
if (union_mask == 0) return CARGO_NO_REFIT; // Don't try to refit an engine with no cargo capacity
|
||||
if (union_mask.None()) return CARGO_NO_REFIT; // Don't try to refit an engine with no cargo capacity
|
||||
|
||||
CargoType cargo_type;
|
||||
CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type);
|
||||
if (!HasAtMostOneBit(cargo_mask)) {
|
||||
if (!HasAtMostOneBit(cargo_mask.base())) {
|
||||
CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(engine_type);
|
||||
if ((cargo_mask & new_engine_default_cargoes) == cargo_mask) {
|
||||
return CARGO_NO_REFIT; // engine_type is already a mixed cargo type which matches the incoming vehicle by default, no refit required
|
||||
|
@ -257,12 +257,12 @@ static CargoType GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, boo
|
|||
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;
|
||||
if (available_cargo_types.Test(v->cargo_type)) return v->cargo_type;
|
||||
}
|
||||
|
||||
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 (!available_cargo_types.Test(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
|
||||
|
||||
|
|
|
@ -546,7 +546,7 @@ static bool CargoAndEngineFilter(const GUIEngineListItem *item, const CargoType
|
|||
return Engine::Get(item->engine_id)->GetPower() != 0;
|
||||
} else {
|
||||
CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(item->engine_id, true) & _standard_cargo_mask;
|
||||
return (cargo_type == CargoFilterCriteria::CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cargo_type));
|
||||
return (cargo_type == CargoFilterCriteria::CF_NONE ? refit_mask.None() : refit_mask.Test(cargo_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ static GUIEngineList::FilterFunction * const _engine_filter_funcs[] = {
|
|||
static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype)
|
||||
{
|
||||
uint weight = 0;
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
if (cap[cargo] != 0) {
|
||||
if (vtype == VEH_TRAIN) {
|
||||
weight += CargoSpec::Get(cargo)->WeightOfNUnitsInTrain(cap[cargo]);
|
||||
|
@ -1261,10 +1261,10 @@ struct BuildVehicleWindow : Window {
|
|||
|
||||
StringID GetCargoFilterLabel(CargoType cargo_type) const
|
||||
{
|
||||
switch (cargo_type) {
|
||||
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;
|
||||
switch (cargo_type.base()) {
|
||||
case CargoFilterCriteria::CF_ANY.base(): return STR_PURCHASE_INFO_ALL_TYPES;
|
||||
case CargoFilterCriteria::CF_ENGINES.base(): return STR_PURCHASE_INFO_ENGINES_ONLY;
|
||||
case CargoFilterCriteria::CF_NONE.base(): return STR_PURCHASE_INFO_NONE;
|
||||
default: return CargoSpec::Get(cargo_type)->name;
|
||||
}
|
||||
}
|
||||
|
@ -1274,7 +1274,7 @@ struct BuildVehicleWindow : Window {
|
|||
{
|
||||
/* 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 = CargoFilterCriteria::CF_ANY;
|
||||
if (this->cargo_filter_criteria < NUM_CARGO && !_standard_cargo_mask.Test(this->cargo_filter_criteria)) this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
|
||||
|
||||
this->eng_list.SetFilterFuncs(_engine_filter_funcs);
|
||||
this->eng_list.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
|
||||
|
@ -1570,20 +1570,20 @@ struct BuildVehicleWindow : Window {
|
|||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY.base()));
|
||||
/* Specific filters for trains. */
|
||||
if (this->vehicle_type == VEH_TRAIN) {
|
||||
/* Add item for locomotives only in case of trains. */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES.base()));
|
||||
/* 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(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE.base()));
|
||||
}
|
||||
|
||||
/* Add cargos */
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index().base()));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -1675,7 +1675,7 @@ struct BuildVehicleWindow : Window {
|
|||
break;
|
||||
|
||||
case WID_BV_CARGO_FILTER_DROPDOWN: // Select cargo filtering criteria dropdown menu
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->cargo_filter_criteria, widget);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->cargo_filter_criteria.base(), widget);
|
||||
break;
|
||||
|
||||
case WID_BV_CONFIGURE_BADGES:
|
||||
|
@ -1884,7 +1884,7 @@ 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;
|
||||
this->cargo_filter_criteria = static_cast<CargoType>(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 != CargoFilterCriteria::CF_ANY);
|
||||
|
|
|
@ -12,15 +12,19 @@
|
|||
|
||||
#include "core/enum_type.hpp"
|
||||
#include "core/strong_typedef_type.hpp"
|
||||
#include "core/strong_bitset_type.hpp"
|
||||
#include "core/convertible_through_base.hpp"
|
||||
|
||||
/** Globally unique label of a cargo type. */
|
||||
using CargoLabel = StrongType::Typedef<uint32_t, struct CargoLabelTag, StrongType::Compare>;
|
||||
|
||||
static constexpr uint NUM_ORIGINAL_CARGO = 12; ///< Original number of cargo types.
|
||||
static constexpr uint NUM_CARGO = 64; ///< Maximum number of cargo types in a game.
|
||||
|
||||
/**
|
||||
* Cargo slots to indicate a cargo type within a game.
|
||||
*/
|
||||
using CargoType = uint8_t;
|
||||
using CargoType = StrongType::Typedef<uint8_t, struct CargoTypeTag, StrongType::Compare, StrongType::Integer>;
|
||||
|
||||
/**
|
||||
* Available types of cargo
|
||||
|
@ -71,14 +75,11 @@ static constexpr CargoLabel CT_NONE = CT_PASSENGERS;
|
|||
|
||||
static constexpr CargoLabel CT_INVALID{UINT32_MAX}; ///< Invalid cargo type.
|
||||
|
||||
static const CargoType NUM_ORIGINAL_CARGO = 12; ///< Original number of cargo types.
|
||||
static const CargoType 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 CargoType CARGO_AUTO_REFIT = 0xFD; ///< Automatically choose cargo type when doing auto refitting.
|
||||
static const CargoType CARGO_NO_REFIT = 0xFE; ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-renew).
|
||||
static constexpr CargoType CARGO_AUTO_REFIT{0xFD}; ///< Automatically choose cargo type when doing auto refitting.
|
||||
static constexpr CargoType CARGO_NO_REFIT{0xFE}; ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-renew).
|
||||
|
||||
static const CargoType INVALID_CARGO = UINT8_MAX;
|
||||
static constexpr CargoType INVALID_CARGO{UINT8_MAX};
|
||||
|
||||
/** Mixed cargo types for definitions with cargo that can vary depending on climate. */
|
||||
enum MixedCargoType : uint8_t {
|
||||
|
@ -92,25 +93,25 @@ enum MixedCargoType : uint8_t {
|
|||
* 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 CargoType CF_ANY = NUM_CARGO; ///< Show all items independent of carried cargo (i.e. no filtering)
|
||||
static constexpr CargoType CF_NONE = NUM_CARGO + 1; ///< Show only items which do not carry cargo (e.g. train engines)
|
||||
static constexpr CargoType CF_ENGINES = NUM_CARGO + 2; ///< Show only engines (for rail vehicles only)
|
||||
static constexpr CargoType CF_FREIGHT = NUM_CARGO + 3; ///< Show only vehicles which carry any freight (non-passenger) cargo
|
||||
static constexpr CargoType CF_ANY{NUM_CARGO}; ///< Show all items independent of carried cargo (i.e. no filtering)
|
||||
static constexpr CargoType CF_NONE{NUM_CARGO + 1}; ///< Show only items which do not carry cargo (e.g. train engines)
|
||||
static constexpr CargoType CF_ENGINES{NUM_CARGO + 2}; ///< Show only engines (for rail vehicles only)
|
||||
static constexpr CargoType CF_FREIGHT{NUM_CARGO + 3}; ///< Show only vehicles which carry any freight (non-passenger) cargo
|
||||
|
||||
static constexpr CargoType CF_NO_RATING = NUM_CARGO + 4; ///< Show items with no rating (station list)
|
||||
static constexpr CargoType CF_SELECT_ALL = NUM_CARGO + 5; ///< Select all items (station list)
|
||||
static constexpr CargoType CF_EXPAND_LIST = NUM_CARGO + 6; ///< Expand list to show all items (station list)
|
||||
static constexpr CargoType CF_NO_RATING{NUM_CARGO + 4}; ///< Show items with no rating (station list)
|
||||
static constexpr CargoType CF_SELECT_ALL{NUM_CARGO + 5}; ///< Select all items (station list)
|
||||
static constexpr CargoType CF_EXPAND_LIST{NUM_CARGO + 6}; ///< Expand list to show all items (station list)
|
||||
};
|
||||
|
||||
/** Test whether cargo type is not INVALID_CARGO */
|
||||
inline bool IsValidCargoType(CargoType cargo) { return cargo != INVALID_CARGO; }
|
||||
|
||||
typedef uint64_t CargoTypes;
|
||||
using CargoTypes = StrongBitSet<CargoType, uint64_t>;
|
||||
|
||||
static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT64_MAX;
|
||||
static constexpr CargoTypes ALL_CARGOTYPES{UINT64_MAX};
|
||||
|
||||
/** Class for storing amounts of cargo */
|
||||
struct CargoArray : std::array<uint, NUM_CARGO> {
|
||||
struct CargoArray : TypedIndexContainer<std::array<uint, NUM_CARGO>, CargoType> {
|
||||
/**
|
||||
* Get the sum of all cargo amounts.
|
||||
* @return The sum.
|
||||
|
|
|
@ -63,7 +63,7 @@ inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, CargoType ct
|
|||
uint32_t ret = 0;
|
||||
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, ind.base());
|
||||
SetBit(ret, CCB_IS_INDUSTRY_BIT);
|
||||
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
|
||||
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype.base());
|
||||
SB(ret, CCB_COMPANY_START, CCB_COMPANY_LENGTH, company.base());
|
||||
return ret;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ inline CargoMonitorID EncodeCargoTownMonitor(CompanyID company, CargoType ctype,
|
|||
|
||||
uint32_t ret = 0;
|
||||
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, town.base());
|
||||
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
|
||||
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype.base());
|
||||
SB(ret, CCB_COMPANY_START, CCB_COMPANY_LENGTH, company.base());
|
||||
return ret;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ inline CompanyID DecodeMonitorCompany(CargoMonitorID num)
|
|||
*/
|
||||
inline CargoType DecodeMonitorCargoType(CargoMonitorID num)
|
||||
{
|
||||
return GB(num, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH);
|
||||
return static_cast<CargoType>(GB(num, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "safeguards.h"
|
||||
|
||||
CargoSpec CargoSpec::array[NUM_CARGO];
|
||||
TypedIndexContainer<std::array<CargoSpec, NUM_CARGO>, CargoType> CargoSpec::array{};
|
||||
std::array<std::vector<const CargoSpec *>, NUM_TPE> CargoSpec::town_production_cargoes{};
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ void SetupCargoForClimate(LandscapeType l)
|
|||
{
|
||||
assert(to_underlying(l) < std::size(_default_climate_cargo));
|
||||
|
||||
_cargo_mask = 0;
|
||||
_cargo_mask.Reset();
|
||||
_default_cargo_labels.clear();
|
||||
_climate_dependent_cargo_labels.fill(CT_INVALID);
|
||||
_climate_independent_cargo_labels.fill(CT_INVALID);
|
||||
|
@ -92,9 +92,9 @@ void SetupCargoForClimate(LandscapeType l)
|
|||
*insert = std::visit(visitor{}, cl);
|
||||
|
||||
if (insert->IsValid()) {
|
||||
SetBit(_cargo_mask, insert->Index());
|
||||
_cargo_mask.Set(insert->Index());
|
||||
_default_cargo_labels.push_back(insert->label);
|
||||
_climate_dependent_cargo_labels[insert->Index()] = insert->label;
|
||||
_climate_dependent_cargo_labels[insert->Index().base()] = insert->label;
|
||||
_climate_independent_cargo_labels[insert->bitnum] = insert->label;
|
||||
}
|
||||
++insert;
|
||||
|
@ -186,7 +186,7 @@ SpriteID CargoSpec::GetCargoIcon() const
|
|||
return sprite;
|
||||
}
|
||||
|
||||
std::array<uint8_t, NUM_CARGO> _sorted_cargo_types; ///< Sort order of cargoes by cargo type.
|
||||
TypedIndexContainer<std::array<uint8_t, NUM_CARGO>, CargoType> _sorted_cargo_types; ///< Sort order of cargoes by cargo type.
|
||||
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
||||
std::span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
|
||||
|
||||
|
@ -238,14 +238,14 @@ void InitializeSortedCargoSpecs()
|
|||
}
|
||||
|
||||
/* Count the number of standard cargos and fill the mask. */
|
||||
_standard_cargo_mask = 0;
|
||||
_standard_cargo_mask.Reset();
|
||||
uint8_t nb_standard_cargo = 0;
|
||||
for (const auto &cargo : _sorted_cargo_specs) {
|
||||
assert(cargo->town_production_effect != INVALID_TPE);
|
||||
CargoSpec::town_production_cargoes[cargo->town_production_effect].push_back(cargo);
|
||||
if (cargo->classes.Test(CargoClass::Special)) break;
|
||||
nb_standard_cargo++;
|
||||
SetBit(_standard_cargo_mask, cargo->Index());
|
||||
_standard_cargo_mask.Set(cargo->Index());
|
||||
}
|
||||
|
||||
/* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */
|
||||
|
|
|
@ -107,7 +107,7 @@ struct CargoSpec {
|
|||
*/
|
||||
inline CargoType Index() const
|
||||
{
|
||||
return this - CargoSpec::array;
|
||||
return static_cast<CargoType>(this - CargoSpec::array.data());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ struct CargoSpec {
|
|||
*/
|
||||
static inline size_t GetArraySize()
|
||||
{
|
||||
return lengthof(CargoSpec::array);
|
||||
return std::size(CargoSpec::array);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,9 +134,9 @@ struct CargoSpec {
|
|||
* @param index ID of cargo
|
||||
* @pre index is a valid cargo type
|
||||
*/
|
||||
static inline CargoSpec *Get(size_t index)
|
||||
static inline CargoSpec *Get(CargoType index)
|
||||
{
|
||||
assert(index < lengthof(CargoSpec::array));
|
||||
assert(index.base() < std::size(CargoSpec::array));
|
||||
return &CargoSpec::array[index];
|
||||
}
|
||||
|
||||
|
@ -165,12 +165,12 @@ struct CargoSpec {
|
|||
};
|
||||
|
||||
bool operator==(const Iterator &other) const { return this->index == other.index; }
|
||||
CargoSpec * operator*() const { return CargoSpec::Get(this->index); }
|
||||
CargoSpec * operator*() const { return CargoSpec::Get(CargoType{static_cast<CargoType::BaseType>(this->index)}); }
|
||||
Iterator & operator++() { this->index++; this->ValidateIndex(); return *this; }
|
||||
|
||||
private:
|
||||
size_t index;
|
||||
void ValidateIndex() { while (this->index < CargoSpec::GetArraySize() && !(CargoSpec::Get(this->index)->IsValid())) this->index++; }
|
||||
void ValidateIndex() { while (this->index < CargoSpec::GetArraySize() && !(**this)->IsValid()) this->index++; }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -195,7 +195,7 @@ struct CargoSpec {
|
|||
static std::array<std::vector<const CargoSpec *>, NUM_TPE> town_production_cargoes;
|
||||
|
||||
private:
|
||||
static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs
|
||||
static TypedIndexContainer<std::array<CargoSpec, NUM_CARGO>, CargoType> array; ///< Array holding all CargoSpecs
|
||||
static inline std::map<CargoLabel, CargoType> label_map{}; ///< Translation map from CargoLabel to Cargo type.
|
||||
|
||||
friend void SetupCargoForClimate(LandscapeType l);
|
||||
|
@ -223,7 +223,7 @@ inline CargoType GetCargoTypeByLabel(CargoLabel label)
|
|||
Dimension GetLargestCargoIconSize();
|
||||
|
||||
void InitializeSortedCargoSpecs();
|
||||
extern std::array<uint8_t, NUM_CARGO> _sorted_cargo_types;
|
||||
extern TypedIndexContainer<std::array<uint8_t, NUM_CARGO>, CargoType> _sorted_cargo_types;
|
||||
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
|
||||
extern std::span<const CargoSpec *> _sorted_standard_cargo_specs;
|
||||
|
||||
|
@ -238,8 +238,6 @@ inline bool IsCargoInClass(CargoType cargo, CargoClasses cc)
|
|||
return CargoSpec::Get(cargo)->classes.Any(cc);
|
||||
}
|
||||
|
||||
using SetCargoBitIterator = SetBitIterator<CargoType, CargoTypes>;
|
||||
|
||||
/** Comparator to sort CargoType by according to desired order. */
|
||||
struct CargoTypeComparator {
|
||||
bool operator() (const CargoType &lhs, const CargoType &rhs) const { return _sorted_cargo_types[lhs] < _sorted_cargo_types[rhs]; }
|
||||
|
|
|
@ -29,6 +29,7 @@ add_files(
|
|||
string_consumer.hpp
|
||||
string_inplace.cpp
|
||||
string_inplace.hpp
|
||||
strong_bitset_type.hpp
|
||||
strong_typedef_type.hpp
|
||||
utf8.cpp
|
||||
utf8.hpp
|
||||
|
|
|
@ -108,6 +108,16 @@ public:
|
|||
return static_cast<Timpl&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip all bits.
|
||||
* @returns The bit set
|
||||
*/
|
||||
inline constexpr Timpl &Flip()
|
||||
{
|
||||
this->data ^= Tmask;
|
||||
return static_cast<Timpl&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip the value-th bit.
|
||||
* @param value Bit to flip.
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file strong_bitset_type.hpp Type helper for making a BitSet out of a Strong Typedef. */
|
||||
|
||||
#ifndef STRONG_BITSET_TYPE_HPP
|
||||
#define STRONG_BITSET_TYPE_HPP
|
||||
|
||||
#include "base_bitset_type.hpp"
|
||||
|
||||
/**
|
||||
* Strong bit set.
|
||||
* @tparam Tvalue_type Type of values to wrap.
|
||||
* @tparam Tstorage Storage type required to hold values.
|
||||
*/
|
||||
template <typename Tvalue_type, typename Tstorage, Tstorage Tmask = std::numeric_limits<Tstorage>::max()>
|
||||
class StrongBitSet : public BaseBitSet<StrongBitSet<Tvalue_type, Tstorage, Tmask>, Tvalue_type, Tstorage> {
|
||||
public:
|
||||
constexpr StrongBitSet() : BaseClass() {}
|
||||
constexpr StrongBitSet(Tvalue_type value) : BaseClass() { this->Set(value); }
|
||||
explicit constexpr StrongBitSet(Tstorage data) : BaseClass(data) {}
|
||||
|
||||
constexpr StrongBitSet(std::initializer_list<const Tvalue_type> values) : BaseClass()
|
||||
{
|
||||
for (const Tvalue_type &value : values) {
|
||||
this->Set(value);
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr size_t DecayValueType(Tvalue_type value) { return value.base(); }
|
||||
|
||||
constexpr auto operator <=>(const StrongBitSet &) const noexcept = default;
|
||||
|
||||
private:
|
||||
using BaseClass = BaseBitSet<StrongBitSet<Tvalue_type, Tstorage, Tmask>, Tvalue_type, Tstorage, Tmask>;
|
||||
};
|
||||
|
||||
#endif /* STRONG_BITSET_TYPE_HPP */
|
|
@ -1103,7 +1103,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest,
|
|||
uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.ToIndustryID() : IndustryID::Invalid(), company->index);
|
||||
|
||||
/* If this cargo type is always accepted, accept all */
|
||||
uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind;
|
||||
uint accepted_total = st->always_accepted.Test(cargo_type) ? num_pieces : accepted_ind;
|
||||
|
||||
/* Update station statistics */
|
||||
if (accepted_total > 0) {
|
||||
|
@ -1400,7 +1400,7 @@ struct PrepareRefitAction
|
|||
bool operator()(const Vehicle *v)
|
||||
{
|
||||
this->consist_capleft[v->cargo_type] -= v->cargo_cap - v->cargo.ReservedCount();
|
||||
this->refit_mask |= EngInfo(v->engine_type)->refit_mask;
|
||||
this->refit_mask.Set(EngInfo(v->engine_type)->refit_mask);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1493,7 +1493,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
|||
if (is_auto_refit) {
|
||||
/* Get a refittable cargo type with waiting cargo for next_station or StationID::Invalid(). */
|
||||
new_cargo_type = v_start->cargo_type;
|
||||
for (CargoType cargo_type : SetCargoBitIterator(refit_mask)) {
|
||||
for (CargoType cargo_type : refit_mask) {
|
||||
if (st->goods[cargo_type].HasData() && st->goods[cargo_type].GetData().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. */
|
||||
|
@ -1652,10 +1652,10 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
bool completely_emptied = true;
|
||||
bool anything_unloaded = false;
|
||||
bool anything_loaded = false;
|
||||
CargoTypes full_load_amount = 0;
|
||||
CargoTypes cargo_not_full = 0;
|
||||
CargoTypes cargo_full = 0;
|
||||
CargoTypes reservation_left = 0;
|
||||
CargoTypes full_load_amount{};
|
||||
CargoTypes cargo_not_full{};
|
||||
CargoTypes cargo_full{};
|
||||
CargoTypes reservation_left{};
|
||||
|
||||
front->cur_speed = 0;
|
||||
|
||||
|
@ -1786,14 +1786,14 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||
/* Remember if there are reservations left so that we don't stop
|
||||
* loading before they're loaded. */
|
||||
SetBit(reservation_left, v->cargo_type);
|
||||
reservation_left.Set(v->cargo_type);
|
||||
}
|
||||
|
||||
/* Store whether the maximum possible load amount was loaded or not.*/
|
||||
if (loaded == cap_left) {
|
||||
SetBit(full_load_amount, v->cargo_type);
|
||||
full_load_amount.Set(v->cargo_type);
|
||||
} else {
|
||||
ClrBit(full_load_amount, v->cargo_type);
|
||||
full_load_amount.Reset(v->cargo_type);
|
||||
}
|
||||
|
||||
/* TODO: Regarding this, when we do gradual loading, we
|
||||
|
@ -1826,9 +1826,9 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
}
|
||||
|
||||
if (v->cargo.StoredCount() >= v->cargo_cap) {
|
||||
SetBit(cargo_full, v->cargo_type);
|
||||
cargo_full.Set(v->cargo_type);
|
||||
} else {
|
||||
SetBit(cargo_not_full, v->cargo_type);
|
||||
cargo_not_full.Set(v->cargo_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1858,7 +1858,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
}
|
||||
/* We loaded less cargo than possible for all cargo types and it's not full
|
||||
* load and we're not supposed to wait any longer: stop loading. */
|
||||
if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !(front->current_order.GetLoadType() & OLFB_FULL_LOAD) &&
|
||||
if (!anything_unloaded && full_load_amount.None() && reservation_left.None() && !(front->current_order.GetLoadType() & OLFB_FULL_LOAD) &&
|
||||
front->current_order_time >= std::max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) {
|
||||
front->vehicle_flags.Set(VehicleFlag::StopLoading);
|
||||
}
|
||||
|
@ -1872,10 +1872,10 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
/* if the aircraft carries passengers and is NOT full, then
|
||||
* continue loading, no matter how much mail is in */
|
||||
if ((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CargoClass::Passengers) && front->cargo_cap > front->cargo.StoredCount()) ||
|
||||
(cargo_not_full != 0 && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes
|
||||
(cargo_not_full.Any() && cargo_full.Reset(cargo_not_full).None())) { // There are still non-full cargoes
|
||||
finished_loading = false;
|
||||
}
|
||||
} else if (cargo_not_full != 0) {
|
||||
} else if (cargo_not_full.Any()) {
|
||||
finished_loading = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -927,7 +927,7 @@ static CompanyID GetPreviewCompany(Engine *e)
|
|||
/* Check whether the company uses similar vehicles */
|
||||
for (const Vehicle *v : Vehicle::Iterate()) {
|
||||
if (v->owner != c->index || v->type != e->type) continue;
|
||||
if (!v->GetEngine()->CanCarryCargo() || !HasBit(cargomask, v->cargo_type)) continue;
|
||||
if (!v->GetEngine()->CanCarryCargo() || !cargomask.Test(v->cargo_type)) continue;
|
||||
|
||||
best_hist = c->old_economy[0].performance_history;
|
||||
best_company = c->index;
|
||||
|
@ -1294,7 +1294,7 @@ bool IsEngineRefittable(EngineID engine)
|
|||
if (!e->CanCarryCargo()) return false;
|
||||
|
||||
const EngineInfo *ei = &e->info;
|
||||
if (ei->refit_mask == 0) return false;
|
||||
if (ei->refit_mask.None()) return false;
|
||||
|
||||
/* Are there suffixes?
|
||||
* Note: This does not mean the suffixes are actually available for every consist at any time. */
|
||||
|
@ -1302,9 +1302,7 @@ bool IsEngineRefittable(EngineID engine)
|
|||
|
||||
/* Is there any cargo except the default cargo? */
|
||||
CargoType default_cargo = e->GetDefaultCargoType();
|
||||
CargoTypes default_cargo_mask = 0;
|
||||
SetBit(default_cargo_mask, default_cargo);
|
||||
return IsValidCargoType(default_cargo) && ei->refit_mask != default_cargo_mask;
|
||||
return IsValidCargoType(default_cargo) && ei->refit_mask != default_cargo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1106,7 +1106,7 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
this->cargo_types = this->GetCargoTypes(number);
|
||||
|
||||
this->vscroll = this->GetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR);
|
||||
this->vscroll->SetCount(CountBits(this->cargo_types));
|
||||
this->vscroll->SetCount(this->cargo_types.Count());
|
||||
|
||||
auto *wid = this->GetWidget<NWidgetCore>(WID_GRAPH_FOOTER);
|
||||
wid->SetString(TimerGameEconomy::UsingWallclockUnits() ? footer_wallclock : footer_calendar);
|
||||
|
@ -1126,10 +1126,10 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
if (row >= this->vscroll->GetCount()) return std::nullopt;
|
||||
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
if (!HasBit(this->cargo_types, cs->Index())) continue;
|
||||
if (!this->cargo_types.Test(cs->Index())) continue;
|
||||
if (row-- > 0) continue;
|
||||
|
||||
return cs->Index();
|
||||
return cs->Index().base();
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
|
@ -1150,7 +1150,7 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
|
||||
size.height = GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.framerect.Vertical();
|
||||
|
||||
for (CargoType cargo_type : SetCargoBitIterator(this->cargo_types)) {
|
||||
for (CargoType cargo_type : this->cargo_types) {
|
||||
const CargoSpec *cs = CargoSpec::Get(cargo_type);
|
||||
|
||||
Dimension d = GetStringBoundingBox(GetString(STR_GRAPH_CARGO_PAYMENT_CARGO, cs->name));
|
||||
|
@ -1181,12 +1181,12 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
Rect line = r.WithHeight(this->line_height);
|
||||
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
if (!HasBit(this->cargo_types, cs->Index())) continue;
|
||||
if (!this->cargo_types.Test(cs->Index())) continue;
|
||||
|
||||
if (pos-- > 0) continue;
|
||||
if (--max < 0) break;
|
||||
|
||||
bool lowered = !HasBit(this->excluded_data, cs->Index());
|
||||
bool lowered = !HasBit(this->excluded_data, cs->Index().base());
|
||||
|
||||
/* Redraw frame if lowered */
|
||||
if (lowered) DrawFrameRect(line, COLOUR_BROWN, FrameFlag::Lowered);
|
||||
|
@ -1213,14 +1213,14 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
case WID_GRAPH_ENABLE_CARGOES:
|
||||
/* Remove all cargoes from the excluded lists. */
|
||||
this->GetExcludedCargoTypes() = {};
|
||||
this->excluded_data = this->GetExcludedCargoTypes();
|
||||
this->excluded_data = this->GetExcludedCargoTypes().base();
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_GRAPH_DISABLE_CARGOES: {
|
||||
/* Add all cargoes to the excluded lists. */
|
||||
this->GetExcludedCargoTypes() = this->cargo_types;
|
||||
this->excluded_data = this->GetExcludedCargoTypes();
|
||||
this->excluded_data = this->GetExcludedCargoTypes().base();
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
@ -1230,11 +1230,11 @@ struct BaseCargoGraphWindow : BaseGraphWindow {
|
|||
if (row >= this->vscroll->GetCount()) return;
|
||||
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
if (!HasBit(this->cargo_types, cs->Index())) continue;
|
||||
if (!this->cargo_types.Test(cs->Index())) continue;
|
||||
if (row-- > 0) continue;
|
||||
|
||||
ToggleBit(this->GetExcludedCargoTypes(), cs->Index());
|
||||
this->excluded_data = this->GetExcludedCargoTypes();
|
||||
this->GetExcludedCargoTypes().Flip(cs->Index());
|
||||
this->excluded_data = this->GetExcludedCargoTypes().base();
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
@ -1306,13 +1306,13 @@ struct PaymentRatesGraphWindow : BaseCargoGraphWindow {
|
|||
*/
|
||||
void UpdatePaymentRates()
|
||||
{
|
||||
this->excluded_data = this->GetExcludedCargoTypes();
|
||||
this->excluded_data = this->GetExcludedCargoTypes().base();
|
||||
|
||||
this->data.clear();
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
DataSet &dataset = this->data.emplace_back();
|
||||
dataset.colour = cs->legend_colour;
|
||||
dataset.exclude_bit = cs->Index();
|
||||
dataset.exclude_bit = cs->Index().base();
|
||||
|
||||
for (uint j = 0; j != this->num_on_x_axis; j++) {
|
||||
dataset.values[j] = GetTransportedGoodsIncome(10, 20, j * 4 + 4, cs->Index());
|
||||
|
@ -1619,7 +1619,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
|
|||
CargoTypes cargo_types{};
|
||||
const Industry *i = Industry::Get(window_number);
|
||||
for (const auto &p : i->produced) {
|
||||
if (IsValidCargoType(p.cargo)) SetBit(cargo_types, p.cargo);
|
||||
if (IsValidCargoType(p.cargo)) cargo_types.Set(p.cargo);
|
||||
}
|
||||
return cargo_types;
|
||||
}
|
||||
|
@ -1645,12 +1645,12 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
|
|||
mo += 12;
|
||||
}
|
||||
|
||||
if (!initialize && this->excluded_data == this->GetExcludedCargoTypes() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) {
|
||||
if (!initialize && this->excluded_data == this->GetExcludedCargoTypes().base() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) {
|
||||
/* There's no reason to get new stats */
|
||||
return;
|
||||
}
|
||||
|
||||
this->excluded_data = this->GetExcludedCargoTypes();
|
||||
this->excluded_data = this->GetExcludedCargoTypes().base();
|
||||
this->year = yr;
|
||||
this->month = mo;
|
||||
|
||||
|
@ -1663,7 +1663,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
|
|||
|
||||
DataSet &produced = this->data.emplace_back();
|
||||
produced.colour = cs->legend_colour;
|
||||
produced.exclude_bit = cs->Index();
|
||||
produced.exclude_bit = cs->Index().base();
|
||||
produced.range_bit = 0;
|
||||
|
||||
for (uint j = 0; j < GRAPH_NUM_MONTHS; j++) {
|
||||
|
@ -1672,7 +1672,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
|
|||
|
||||
DataSet &transported = this->data.emplace_back();
|
||||
transported.colour = cs->legend_colour;
|
||||
transported.exclude_bit = cs->Index();
|
||||
transported.exclude_bit = cs->Index().base();
|
||||
transported.range_bit = 1;
|
||||
transported.dash = 2;
|
||||
|
||||
|
|
|
@ -708,7 +708,7 @@ public:
|
|||
return;
|
||||
|
||||
case WID_GL_FILTER_BY_CARGO: // Select filtering criteria dropdown menu
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(false), this->cargo_filter_criteria, widget);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(false), this->cargo_filter_criteria.base(), widget);
|
||||
break;
|
||||
|
||||
case WID_GL_ALL_VEHICLES: // All vehicles button
|
||||
|
@ -999,7 +999,7 @@ public:
|
|||
break;
|
||||
|
||||
case WID_GL_FILTER_BY_CARGO: // Select a cargo filter criteria
|
||||
this->SetCargoFilter(index);
|
||||
this->SetCargoFilter(static_cast<CargoType>(index));
|
||||
break;
|
||||
|
||||
case WID_GL_MANAGE_VEHICLES_DROPDOWN:
|
||||
|
|
|
@ -74,14 +74,14 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
|||
};
|
||||
|
||||
struct ProducedCargo {
|
||||
CargoType cargo = 0; ///< Cargo type
|
||||
CargoType cargo = INVALID_CARGO; ///< Cargo type
|
||||
uint16_t waiting = 0; ///< Amount of cargo produced
|
||||
uint8_t rate = 0; ///< Production rate
|
||||
std::array<ProducedHistory, 25> history{}; ///< History of cargo produced and transported for this month and 24 previous months
|
||||
};
|
||||
|
||||
struct AcceptedCargo {
|
||||
CargoType cargo = 0; ///< Cargo type
|
||||
CargoType cargo = INVALID_CARGO; ///< Cargo type
|
||||
uint16_t waiting = 0; ///< Amount of cargo waiting to processed
|
||||
TimerGameEconomy::Date last_accepted{}; ///< Last day cargo was accepted by this industry
|
||||
};
|
||||
|
|
|
@ -462,13 +462,13 @@ static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, Ca
|
|||
acceptance[cargo] += cargo_acceptance[i];
|
||||
|
||||
/* Maybe set 'always accepted' bit (if it's not set already) */
|
||||
if (HasBit(always_accepted, cargo)) continue;
|
||||
if (always_accepted.Test(cargo)) continue;
|
||||
|
||||
/* Test whether the industry itself accepts the cargo type */
|
||||
if (ind->IsCargoAccepted(cargo)) continue;
|
||||
|
||||
/* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
|
||||
SetBit(always_accepted, cargo);
|
||||
always_accepted.Set(cargo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1308,12 +1308,12 @@ static bool CargoFilter(const Industry * const *industry, const std::pair<CargoT
|
|||
|
||||
bool accepted_cargo_matches;
|
||||
|
||||
switch (accepted_cargo) {
|
||||
case CargoFilterCriteria::CF_ANY:
|
||||
switch (accepted_cargo.base()) {
|
||||
case CargoFilterCriteria::CF_ANY.base():
|
||||
accepted_cargo_matches = true;
|
||||
break;
|
||||
|
||||
case CargoFilterCriteria::CF_NONE:
|
||||
case CargoFilterCriteria::CF_NONE.base():
|
||||
accepted_cargo_matches = !(*industry)->IsCargoAccepted();
|
||||
break;
|
||||
|
||||
|
@ -1324,12 +1324,12 @@ static bool CargoFilter(const Industry * const *industry, const std::pair<CargoT
|
|||
|
||||
bool produced_cargo_matches;
|
||||
|
||||
switch (produced_cargo) {
|
||||
case CargoFilterCriteria::CF_ANY:
|
||||
switch (produced_cargo.base()) {
|
||||
case CargoFilterCriteria::CF_ANY.base():
|
||||
produced_cargo_matches = true;
|
||||
break;
|
||||
|
||||
case CargoFilterCriteria::CF_NONE:
|
||||
case CargoFilterCriteria::CF_NONE.base():
|
||||
produced_cargo_matches = !(*industry)->IsCargoProduced();
|
||||
break;
|
||||
|
||||
|
@ -1415,9 +1415,9 @@ protected:
|
|||
|
||||
StringID GetCargoFilterLabel(CargoType cargo_type) const
|
||||
{
|
||||
switch (cargo_type) {
|
||||
case CargoFilterCriteria::CF_ANY: return STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
|
||||
case CargoFilterCriteria::CF_NONE: return STR_INDUSTRY_DIRECTORY_FILTER_NONE;
|
||||
switch (cargo_type.base()) {
|
||||
case CargoFilterCriteria::CF_ANY.base(): return STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
|
||||
case CargoFilterCriteria::CF_NONE.base(): return STR_INDUSTRY_DIRECTORY_FILTER_NONE;
|
||||
default: return CargoSpec::Get(cargo_type)->name;
|
||||
}
|
||||
}
|
||||
|
@ -1795,14 +1795,14 @@ public:
|
|||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY.base()));
|
||||
/* Add item for industries not producing anything, e.g. power plants */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE.base()));
|
||||
|
||||
/* Add cargos */
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index().base()));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -1821,11 +1821,11 @@ public:
|
|||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_ACC_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->accepted_cargo_filter_criteria, widget);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->accepted_cargo_filter_criteria.base(), widget);
|
||||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_PROD_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->produced_cargo_filter_criteria, widget);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->produced_cargo_filter_criteria.base(), widget);
|
||||
break;
|
||||
|
||||
case WID_ID_INDUSTRY_LIST: {
|
||||
|
@ -1854,13 +1854,13 @@ public:
|
|||
}
|
||||
|
||||
case WID_ID_FILTER_BY_ACC_CARGO: {
|
||||
this->SetAcceptedCargoFilter(index);
|
||||
this->SetAcceptedCargoFilter(static_cast<CargoType>(index));
|
||||
this->BuildSortIndustriesList();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_ID_FILTER_BY_PROD_CARGO: {
|
||||
this->SetProducedCargoFilter(index);
|
||||
this->SetProducedCargoFilter(static_cast<CargoType>(index));
|
||||
this->BuildSortIndustriesList();
|
||||
break;
|
||||
}
|
||||
|
@ -2667,7 +2667,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
const IndustrySpec *indsp = GetIndustrySpec(this->ind_cargo);
|
||||
return GetString(STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION, indsp->name);
|
||||
} else {
|
||||
const CargoSpec *csp = CargoSpec::Get(this->ind_cargo - NUM_INDUSTRYTYPES);
|
||||
const CargoSpec *csp = CargoSpec::Get(static_cast<CargoType>(this->ind_cargo - NUM_INDUSTRYTYPES));
|
||||
return GetString(STR_INDUSTRY_CARGOES_CARGO_CAPTION, csp->name);
|
||||
}
|
||||
}
|
||||
|
@ -2680,9 +2680,9 @@ struct IndustryCargoesWindow : public Window {
|
|||
*/
|
||||
static bool HasCommonValidCargo(const std::span<const CargoType> cargoes1, const std::span<const CargoType> cargoes2)
|
||||
{
|
||||
for (const CargoType cargo_type1 : cargoes1) {
|
||||
for (const CargoType &cargo_type1 : cargoes1) {
|
||||
if (!IsValidCargoType(cargo_type1)) continue;
|
||||
for (const CargoType cargo_type2 : cargoes2) {
|
||||
for (const CargoType &cargo_type2 : cargoes2) {
|
||||
if (cargo_type1 == cargo_type2) return true;
|
||||
}
|
||||
}
|
||||
|
@ -2696,7 +2696,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
*/
|
||||
static bool HousesCanSupply(const std::span<const CargoType> cargoes)
|
||||
{
|
||||
for (const CargoType cargo_type : cargoes) {
|
||||
for (const CargoType &cargo_type : cargoes) {
|
||||
if (!IsValidCargoType(cargo_type)) continue;
|
||||
TownProductionEffect tpe = CargoSpec::Get(cargo_type)->town_production_effect;
|
||||
if (tpe == TPE_PASSENGERS || tpe == TPE_MAIL) return true;
|
||||
|
@ -2713,7 +2713,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
{
|
||||
HouseZones climate_mask = GetClimateMaskForLandscape();
|
||||
|
||||
for (const CargoType cargo_type : cargoes) {
|
||||
for (const CargoType &cargo_type : cargoes) {
|
||||
if (!IsValidCargoType(cargo_type)) continue;
|
||||
|
||||
for (const auto &hs : HouseSpec::Specs()) {
|
||||
|
@ -2894,7 +2894,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
*/
|
||||
void ComputeCargoDisplay(CargoType cargo_type)
|
||||
{
|
||||
this->ind_cargo = cargo_type + NUM_INDUSTRYTYPES;
|
||||
this->ind_cargo = cargo_type.base() + NUM_INDUSTRYTYPES;
|
||||
_displayed_industries.reset();
|
||||
|
||||
this->fields.clear();
|
||||
|
@ -3107,7 +3107,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
DropDownList lst;
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
||||
lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index().base()));
|
||||
}
|
||||
if (!lst.empty()) {
|
||||
int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1;
|
||||
|
@ -3138,7 +3138,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
|
||||
switch (widget) {
|
||||
case WID_IC_CARGO_DROPDOWN:
|
||||
this->ComputeCargoDisplay(index);
|
||||
this->ComputeCargoDisplay(static_cast<CargoType>(index));
|
||||
break;
|
||||
|
||||
case WID_IC_IND_DROPDOWN:
|
||||
|
|
|
@ -86,7 +86,7 @@ void LinkGraphOverlay::RebuildCache()
|
|||
StationLinkMap &seen_links = this->cached_links[from];
|
||||
|
||||
uint supply = 0;
|
||||
for (CargoType cargo : SetCargoBitIterator(this->cargo_mask)) {
|
||||
for (CargoType cargo : this->cargo_mask) {
|
||||
if (!CargoSpec::Get(cargo)->IsValid()) continue;
|
||||
if (!LinkGraph::IsValidID(sta->goods[cargo].link_graph)) continue;
|
||||
const LinkGraph &lg = *LinkGraph::Get(sta->goods[cargo].link_graph);
|
||||
|
@ -212,7 +212,7 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe
|
|||
*/
|
||||
void LinkGraphOverlay::AddLinks(const Station *from, const Station *to)
|
||||
{
|
||||
for (CargoType cargo : SetCargoBitIterator(this->cargo_mask)) {
|
||||
for (CargoType cargo : this->cargo_mask) {
|
||||
if (!CargoSpec::Get(cargo)->IsValid()) continue;
|
||||
const GoodsEntry &ge = from->goods[cargo];
|
||||
if (!LinkGraph::IsValidID(ge.link_graph) ||
|
||||
|
@ -566,7 +566,7 @@ void LinkGraphLegendWindow::SetOverlay(std::shared_ptr<LinkGraphOverlay> overlay
|
|||
}
|
||||
CargoTypes cargoes = this->overlay->GetCargoMask();
|
||||
for (uint c = 0; c < this->num_cargo; c++) {
|
||||
this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, HasBit(cargoes, _sorted_cargo_specs[c]->Index()));
|
||||
this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, cargoes.Test(_sorted_cargo_specs[c]->Index()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,10 +669,10 @@ void LinkGraphLegendWindow::UpdateOverlayCompanies()
|
|||
*/
|
||||
void LinkGraphLegendWindow::UpdateOverlayCargoes()
|
||||
{
|
||||
CargoTypes mask = 0;
|
||||
CargoTypes mask{};
|
||||
for (uint c = 0; c < num_cargo; c++) {
|
||||
if (!this->IsWidgetLowered(WID_LGL_CARGO_FIRST + c)) continue;
|
||||
SetBit(mask, _sorted_cargo_specs[c]->Index());
|
||||
mask.Set(_sorted_cargo_specs[c]->Index());
|
||||
}
|
||||
this->overlay->SetCargoMask(mask);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ bool LinkRefresher::HandleRefit(CargoType refit_cargo)
|
|||
bool any_refit = false;
|
||||
for (Vehicle *v = this->vehicle; v != nullptr; v = v->Next()) {
|
||||
const Engine *e = Engine::Get(v->engine_type);
|
||||
if (!HasBit(e->info.refit_mask, this->cargo)) {
|
||||
if (!e->info.refit_mask.Test(this->cargo)) {
|
||||
++refit_it;
|
||||
continue;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ void LinkRefresher::RefreshStats(VehicleOrderID cur, VehicleOrderID next)
|
|||
Station *st = Station::GetIfValid(orders[cur].GetDestination().ToStationID());
|
||||
if (st != nullptr && next_station != StationID::Invalid() && next_station != st->index) {
|
||||
Station *st_to = Station::Get(next_station);
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
/* Refresh the link and give it a minimum capacity. */
|
||||
|
||||
uint cargo_quantity = this->capacities[cargo];
|
||||
|
@ -260,7 +260,7 @@ void LinkRefresher::RefreshLinks(VehicleOrderID cur, VehicleOrderID next, Refres
|
|||
} else if (!flags.Test(RefreshFlag::InAutorefit)) {
|
||||
flags.Set(RefreshFlag::InAutorefit);
|
||||
LinkRefresher backup(*this);
|
||||
for (CargoType cargo = 0; cargo != NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
if (CargoSpec::Get(cargo)->IsValid() && this->HandleRefit(cargo)) {
|
||||
this->RefreshLinks(cur, next, flags, num_hops);
|
||||
*this = backup;
|
||||
|
|
|
@ -221,14 +221,14 @@ struct MainWindow : Window
|
|||
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
|
||||
nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZoomLevel::Viewport));
|
||||
|
||||
this->viewport->overlay = std::make_shared<LinkGraphOverlay>(this, WID_M_VIEWPORT, 0, CompanyMask{}, 2);
|
||||
this->viewport->overlay = std::make_shared<LinkGraphOverlay>(this, WID_M_VIEWPORT, CargoTypes{}, CompanyMask{}, 2);
|
||||
this->refresh_timeout.Reset();
|
||||
}
|
||||
|
||||
/** Refresh the link-graph overlay. */
|
||||
void RefreshLinkGraph()
|
||||
{
|
||||
if (this->viewport->overlay->GetCargoMask() == 0 ||
|
||||
if (this->viewport->overlay->GetCargoMask().None() ||
|
||||
this->viewport->overlay->GetCompanyMask().None()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -310,10 +310,10 @@ EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal
|
|||
*/
|
||||
CargoTypes TranslateRefitMask(uint32_t refit_mask)
|
||||
{
|
||||
CargoTypes result = 0;
|
||||
CargoTypes result{};
|
||||
for (uint8_t bit : SetBitIterator(refit_mask)) {
|
||||
CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
|
||||
if (IsValidCargoType(cargo)) SetBit(result, cargo);
|
||||
if (IsValidCargoType(cargo)) result.Set(cargo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -641,9 +641,9 @@ static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoT
|
|||
*/
|
||||
static void CalculateRefitMasks()
|
||||
{
|
||||
CargoTypes original_known_cargoes = 0;
|
||||
for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
|
||||
if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
|
||||
CargoTypes original_known_cargoes{};
|
||||
for (CargoType cargo_type{}; cargo_type != NUM_CARGO; ++cargo_type) {
|
||||
if (IsDefaultCargo(cargo_type)) original_known_cargoes.Set(cargo_type);
|
||||
}
|
||||
|
||||
for (Engine *e : Engine::Iterate()) {
|
||||
|
@ -738,13 +738,13 @@ static void CalculateRefitMasks()
|
|||
}
|
||||
_gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
|
||||
|
||||
if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
|
||||
if (IsValidCargoType(ei->cargo_type)) _gted[engine].ctt_exclude_mask.Reset(ei->cargo_type);
|
||||
}
|
||||
|
||||
/* Compute refittability */
|
||||
{
|
||||
CargoTypes mask = 0;
|
||||
CargoTypes not_mask = 0;
|
||||
CargoTypes mask{};
|
||||
CargoTypes not_mask{};
|
||||
CargoTypes xor_mask = ei->refit_mask;
|
||||
|
||||
/* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
|
||||
|
@ -754,16 +754,17 @@ static void CalculateRefitMasks()
|
|||
if (_gted[engine].cargo_allowed.Any()) {
|
||||
/* Build up the list of cargo types from the set cargo classes. */
|
||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||
if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
|
||||
if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
|
||||
if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) mask.Set(cs->Index());
|
||||
if (cs->classes.Any(_gted[engine].cargo_disallowed)) not_mask.Set(cs->Index());
|
||||
}
|
||||
}
|
||||
|
||||
ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
|
||||
CargoTypes invalid_mask = CargoTypes{_cargo_mask}.Flip();
|
||||
ei->refit_mask = mask.Reset(not_mask).Flip(xor_mask).Reset(invalid_mask);
|
||||
|
||||
/* Apply explicit refit includes/excludes. */
|
||||
ei->refit_mask |= _gted[engine].ctt_include_mask;
|
||||
ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
|
||||
ei->refit_mask.Set(_gted[engine].ctt_include_mask);
|
||||
ei->refit_mask.Reset(_gted[engine].ctt_exclude_mask);
|
||||
|
||||
/* Custom refit mask callback. */
|
||||
const GRFFile *file = _gted[e->index].defaultcargo_grf;
|
||||
|
@ -776,8 +777,8 @@ static void CalculateRefitMasks()
|
|||
case CALLBACK_FAILED:
|
||||
case 0:
|
||||
break; // Do nothing.
|
||||
case 1: SetBit(ei->refit_mask, cs->Index()); break;
|
||||
case 2: ClrBit(ei->refit_mask, cs->Index()); break;
|
||||
case 1: ei->refit_mask.Set(cs->Index()); break;
|
||||
case 2: ei->refit_mask.Reset(cs->Index()); break;
|
||||
|
||||
default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
|
||||
}
|
||||
|
@ -786,24 +787,24 @@ static void CalculateRefitMasks()
|
|||
}
|
||||
|
||||
/* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
|
||||
if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
|
||||
if (IsValidCargoType(ei->cargo_type) && !_cargo_mask.Test(ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
|
||||
|
||||
/* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
|
||||
* Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
|
||||
if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
|
||||
if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !ei->refit_mask.Test(ei->cargo_type)) {
|
||||
ei->cargo_type = INVALID_CARGO;
|
||||
}
|
||||
|
||||
/* Check if this engine's cargo type is valid. If not, set to the first refittable
|
||||
* cargo type. Finally disable the vehicle, if there is still no cargo. */
|
||||
if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
|
||||
if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask.Any()) {
|
||||
/* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
|
||||
const GRFFile *file = _gted[engine].defaultcargo_grf;
|
||||
if (file == nullptr) file = e->GetGRF();
|
||||
if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
|
||||
/* Use first refittable cargo from cargo translation table */
|
||||
uint8_t best_local_slot = UINT8_MAX;
|
||||
for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
|
||||
for (CargoType cargo_type : ei->refit_mask) {
|
||||
uint8_t local_slot = file->cargo_map[cargo_type];
|
||||
if (local_slot < best_local_slot) {
|
||||
best_local_slot = local_slot;
|
||||
|
@ -814,7 +815,7 @@ static void CalculateRefitMasks()
|
|||
|
||||
if (!IsValidCargoType(ei->cargo_type)) {
|
||||
/* Use first refittable cargo slot */
|
||||
ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
|
||||
ei->cargo_type = *ei->refit_mask.begin();
|
||||
}
|
||||
}
|
||||
if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) {
|
||||
|
@ -822,14 +823,14 @@ static void CalculateRefitMasks()
|
|||
* Fallback to the first available instead, if the cargo type has not been changed (as indicated by
|
||||
* cargo_label not being CT_INVALID). */
|
||||
if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
|
||||
ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
|
||||
ei->cargo_type = *_standard_cargo_mask.begin();
|
||||
}
|
||||
}
|
||||
if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
|
||||
|
||||
/* Clear refit_mask for not refittable ships */
|
||||
if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
|
||||
ei->refit_mask = 0;
|
||||
ei->refit_mask.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ struct GRFFile {
|
|||
std::vector<GRFLabel> labels{}; ///< List of labels
|
||||
|
||||
std::vector<CargoLabel> cargo_list{}; ///< Cargo translation table (local ID -> label)
|
||||
std::array<uint8_t, NUM_CARGO> cargo_map{}; ///< Inverse cargo translation table (CargoType -> local ID)
|
||||
TypedIndexContainer<std::array<uint8_t, NUM_CARGO>, CargoType> cargo_map{}; ///< Inverse cargo translation table (CargoType -> local ID)
|
||||
|
||||
std::vector<BadgeID> badge_list{}; ///< Badge translation table (local index -> global index)
|
||||
std::unordered_map<uint16_t, BadgeID> badge_map{};
|
||||
|
|
|
@ -153,10 +153,10 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint first, uint last, int pro
|
|||
_gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
|
||||
if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur_gps.grffile;
|
||||
CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
|
||||
ctt = 0;
|
||||
ctt.Reset();
|
||||
while (count--) {
|
||||
CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile);
|
||||
if (IsValidCargoType(ctype)) SetBit(ctt, ctype);
|
||||
if (IsValidCargoType(ctype)) ctt.Set(ctype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -34,16 +34,16 @@ static ChangeInfoResult CargoReserveInfo(uint first, uint last, int prop, ByteRe
|
|||
}
|
||||
|
||||
for (uint id = first; id < last; ++id) {
|
||||
CargoSpec *cs = CargoSpec::Get(id);
|
||||
CargoSpec *cs = CargoSpec::Get(static_cast<CargoType>(id));
|
||||
|
||||
switch (prop) {
|
||||
case 0x08: // Bit number of cargo
|
||||
cs->bitnum = buf.ReadByte();
|
||||
if (cs->IsValid()) {
|
||||
cs->grffile = _cur_gps.grffile;
|
||||
SetBit(_cargo_mask, id);
|
||||
_cargo_mask.Set(cs->Index());
|
||||
} else {
|
||||
ClrBit(_cargo_mask, id);
|
||||
_cargo_mask.Reset(cs->Index());
|
||||
}
|
||||
BuildCargoLabelMap();
|
||||
break;
|
||||
|
|
|
@ -305,7 +305,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint first, uint last, int prop, Byt
|
|||
uint8_t count = buf.ReadByte();
|
||||
for (uint8_t j = 0; j < count; j++) {
|
||||
CargoType cargo = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile);
|
||||
if (IsValidCargoType(cargo)) SetBit(housespec->watched_cargoes, cargo);
|
||||
if (IsValidCargoType(cargo)) housespec->watched_cargoes.Set(cargo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -194,10 +194,10 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint first, uint last, int prop, B
|
|||
_gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
|
||||
if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur_gps.grffile;
|
||||
CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
|
||||
ctt = 0;
|
||||
ctt.Reset();
|
||||
while (count--) {
|
||||
CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile);
|
||||
if (IsValidCargoType(ctype)) SetBit(ctt, ctype);
|
||||
if (IsValidCargoType(ctype)) ctt.Set(ctype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -173,10 +173,10 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint first, uint last, int prop, B
|
|||
_gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
|
||||
if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur_gps.grffile;
|
||||
CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
|
||||
ctt = 0;
|
||||
ctt.Reset();
|
||||
while (count--) {
|
||||
CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile);
|
||||
if (IsValidCargoType(ctype)) SetBit(ctt, ctype);
|
||||
if (IsValidCargoType(ctype)) ctt.Set(ctype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -292,10 +292,10 @@ ChangeInfoResult RailVehicleChangeInfo(uint first, uint last, int prop, ByteRead
|
|||
_gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
|
||||
if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur_gps.grffile;
|
||||
CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
|
||||
ctt = 0;
|
||||
ctt.Reset();
|
||||
while (count--) {
|
||||
CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile);
|
||||
if (IsValidCargoType(ctype)) SetBit(ctt, ctype);
|
||||
if (IsValidCargoType(ctype)) ctt.Set(ctype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -379,7 +379,7 @@ static void CargoMapSpriteGroup(ByteReader &buf, uint8_t idcount)
|
|||
continue;
|
||||
}
|
||||
|
||||
CargoSpec *cs = CargoSpec::Get(cargo_type);
|
||||
CargoSpec *cs = CargoSpec::Get(static_cast<CargoType>(cargo_type));
|
||||
cs->grffile = _cur_gps.grffile;
|
||||
cs->group = _cur_gps.spritegroups[groupid];
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ struct AnimationBase {
|
|||
* @param random_animation Whether to pass random bits to the "next frame" callback.
|
||||
* @param extra_data Custom extra callback data.
|
||||
*/
|
||||
static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = 0)
|
||||
static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = {})
|
||||
{
|
||||
assert(spec != nullptr);
|
||||
|
||||
|
@ -128,7 +128,7 @@ struct AnimationBase {
|
|||
* @param trigger What triggered this update? To be passed as parameter to the NewGRF.
|
||||
* @param extra_data Custom extra data for callback processing.
|
||||
*/
|
||||
static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32_t random_bits, uint32_t trigger, Textra extra_data = 0)
|
||||
static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32_t random_bits, uint32_t trigger, Textra extra_data = {})
|
||||
{
|
||||
uint16_t callback = GetCallback(cb, random_bits, trigger, spec, obj, tile, extra_data);
|
||||
if (callback == CALLBACK_FAILED) return;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "sprite.h"
|
||||
#include "core/alloc_type.hpp"
|
||||
#include "core/convertible_through_base.hpp"
|
||||
#include "command_type.h"
|
||||
#include "direction_type.h"
|
||||
#include "company_type.h"
|
||||
|
@ -454,9 +455,9 @@ struct VariableGRFFileProps : GRFFilePropsBase {
|
|||
* Sprite groups indexed by CargoType.
|
||||
*/
|
||||
struct CargoGRFFileProps : VariableGRFFileProps<CargoType> {
|
||||
static constexpr CargoType SG_DEFAULT = NUM_CARGO; ///< Default type used when no more-specific cargo matches.
|
||||
static constexpr CargoType SG_PURCHASE = NUM_CARGO + 1; ///< Used in purchase lists before an item exists.
|
||||
static constexpr CargoType SG_DEFAULT_NA = NUM_CARGO + 2; ///< Used only by stations and roads when no more-specific cargo matches.
|
||||
static constexpr CargoType SG_DEFAULT{NUM_CARGO}; ///< Default type used when no more-specific cargo matches.
|
||||
static constexpr CargoType SG_PURCHASE{NUM_CARGO + 1}; ///< Used in purchase lists before an item exists.
|
||||
static constexpr CargoType SG_DEFAULT_NA{NUM_CARGO + 2}; ///< Used only by stations and roads when no more-specific cargo matches.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -426,7 +426,7 @@ struct NewGRFInspectWindow : Window {
|
|||
{
|
||||
switch (nip.type) {
|
||||
case NIT_INT: return GetString(STR_JUST_INT, value);
|
||||
case NIT_CARGO: return GetString(IsValidCargoType(value) ? CargoSpec::Get(value)->name : STR_QUANTITY_N_A);
|
||||
case NIT_CARGO: return GetString(IsValidCargoType(static_cast<CargoType>(value)) ? CargoSpec::Get(static_cast<CargoType>(value))->name : STR_QUANTITY_N_A);
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -435,7 +435,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
|
||||
case 0x42: { // Consist cargo information
|
||||
if (!HasBit(v->grf_cache.cache_valid, NCVV_CONSIST_CARGO_INFORMATION)) {
|
||||
std::array<uint8_t, NUM_CARGO> common_cargoes{};
|
||||
TypedIndexContainer<std::array<uint8_t, NUM_CARGO>, CargoType> common_cargoes{};
|
||||
uint8_t cargo_classes = 0;
|
||||
uint8_t user_def_data = 0;
|
||||
|
||||
|
@ -470,12 +470,12 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
|
||||
/* Note: We have to store the untranslated cargotype in the cache as the cache can be read by different NewGRFs,
|
||||
* which will need different translations */
|
||||
v->grf_cache.consist_cargo_information = cargo_classes | (common_cargo_type << 8) | (common_subtype << 16) | (user_def_data << 24);
|
||||
v->grf_cache.consist_cargo_information = cargo_classes | (common_cargo_type.base() << 8) | (common_subtype << 16) | (user_def_data << 24);
|
||||
SetBit(v->grf_cache.cache_valid, NCVV_CONSIST_CARGO_INFORMATION);
|
||||
}
|
||||
|
||||
/* The cargo translation is specific to the accessing GRF, and thus cannot be cached. */
|
||||
CargoType common_cargo_type = (v->grf_cache.consist_cargo_information >> 8) & 0xFF;
|
||||
CargoType common_cargo_type = static_cast<CargoType>(GB(v->grf_cache.consist_cargo_information, 8, 8));
|
||||
|
||||
/* Note:
|
||||
* - Unlike everywhere else the cargo translation table is only used since grf version 8, not 7.
|
||||
|
@ -822,7 +822,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
case 0x36: return v->subspeed;
|
||||
case 0x37: return v->acceleration;
|
||||
case 0x38: break; // not implemented
|
||||
case 0x39: return v->cargo_type;
|
||||
case 0x39: return v->cargo_type.base();
|
||||
case 0x3A: return v->cargo_cap;
|
||||
case 0x3B: return GB(v->cargo_cap, 8, 8);
|
||||
case 0x3C: return ClampTo<uint16_t>(v->cargo.StoredCount());
|
||||
|
|
|
@ -36,7 +36,7 @@ struct GenericScopeResolver : public ScopeResolver {
|
|||
* @param ai_callback Callback comes from the AI.
|
||||
*/
|
||||
GenericScopeResolver(ResolverObject &ro, bool ai_callback)
|
||||
: ScopeResolver(ro), cargo_type(0), default_selection(0), src_industry(0), dst_industry(0), distance(0),
|
||||
: ScopeResolver(ro), cargo_type(INVALID_CARGO), default_selection(0), src_industry(0), dst_industry(0), distance(0),
|
||||
event(), count(0), station_size(0), feature(GSF_INVALID), ai_callback(ai_callback)
|
||||
{
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ void AddGenericCallback(GrfSpecFeature feature, const GRFFile *file, const Sprit
|
|||
switch (variable) {
|
||||
case 0x40: return this->ro.grffile->cargo_map[this->cargo_type];
|
||||
|
||||
case 0x80: return this->cargo_type;
|
||||
case 0x80: return this->cargo_type.base();
|
||||
case 0x81: return CargoSpec::Get(this->cargo_type)->bitnum;
|
||||
case 0x82: return this->default_selection;
|
||||
case 0x83: return this->src_industry;
|
||||
|
|
|
@ -402,7 +402,7 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex start_ti
|
|||
}
|
||||
|
||||
/* Cargo triggered CB 148? */
|
||||
if (HasBit(this->watched_cargo_triggers, cargo_type)) SetBit(res, 4);
|
||||
if (this->watched_cargo_triggers.Test(cargo_type)) SetBit(res, 4);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -739,9 +739,9 @@ void TriggerHouseAnimation_WatchedCargoAccepted(TileIndex tile, CargoTypes trigg
|
|||
HouseID id = GetHouseType(tile);
|
||||
const HouseSpec *hs = HouseSpec::Get(id);
|
||||
|
||||
trigger_cargoes &= hs->watched_cargoes;
|
||||
trigger_cargoes = trigger_cargoes & hs->watched_cargoes;
|
||||
/* None of the trigger cargoes is watched? */
|
||||
if (trigger_cargoes == 0) return;
|
||||
if (trigger_cargoes.None()) return;
|
||||
|
||||
/* Same random value for all tiles of a multi-tile house. */
|
||||
uint16_t r = Random();
|
||||
|
|
|
@ -55,7 +55,7 @@ struct HouseResolverObject : public SpecializedResolverObject<HouseRandomTrigger
|
|||
|
||||
HouseResolverObject(HouseID house_id, TileIndex tile, Town *town,
|
||||
CallbackID callback = CBID_NO_CALLBACK, uint32_t param1 = 0, uint32_t param2 = 0,
|
||||
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0);
|
||||
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = {}, int view = 0);
|
||||
|
||||
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ void TriggerHouseAnimation_ConstructionStageChanged(TileIndex tile, bool first_c
|
|||
void TriggerHouseAnimation_WatchedCargoAccepted(TileIndex tile, CargoTypes trigger_cargoes);
|
||||
|
||||
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, std::span<int32_t> regs100 = {},
|
||||
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0);
|
||||
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = {}, int view = 0);
|
||||
|
||||
bool CanDeleteHouse(TileIndex tile);
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(const ResolverObject &objec
|
|||
case 0x87: return this->industry->location.h;// xy dimensions
|
||||
|
||||
case 0x88:
|
||||
case 0x89: return this->industry->GetProduced(variable - 0x88).cargo;
|
||||
case 0x89: return this->industry->GetProduced(variable - 0x88).cargo.base();
|
||||
case 0x8A: return this->industry->GetProduced(0).waiting;
|
||||
case 0x8B: return GB(this->industry->GetProduced(0).waiting, 8, 8);
|
||||
case 0x8C: return this->industry->GetProduced(1).waiting;
|
||||
|
@ -380,7 +380,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(const ResolverObject &objec
|
|||
case 0x8F: return this->industry->GetProduced(variable - 0x8E).rate;
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0x92: return this->industry->GetAccepted(variable - 0x90).cargo;
|
||||
case 0x92: return this->industry->GetAccepted(variable - 0x90).cargo.base();
|
||||
case 0x93: return this->industry->prod_level;
|
||||
/* amount of cargo produced so far THIS month. */
|
||||
case 0x94: return this->industry->GetProduced(0).history[THIS_MONTH].production;
|
||||
|
|
|
@ -232,7 +232,7 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
|
|||
/* Pick the first cargo that we have waiting */
|
||||
for (const auto &[cargo, spritegroup] : roadstopspec->grf_prop.spritegroups) {
|
||||
if (cargo < NUM_CARGO && station->goods[cargo].HasData() && station->goods[cargo].GetData().cargo.TotalCount() > 0) {
|
||||
ctype = cargo;
|
||||
ctype = static_cast<CargoType>(cargo);
|
||||
this->root_spritegroup = spritegroup;
|
||||
break;
|
||||
}
|
||||
|
@ -422,18 +422,15 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom
|
|||
/* Check the cached cargo trigger bitmask to see if we need
|
||||
* to bother with any further processing.
|
||||
* Note: cached_roadstop_cargo_triggers must be non-zero even for cargo-independent triggers. */
|
||||
if (st->cached_roadstop_cargo_triggers == 0) return;
|
||||
if (IsValidCargoType(cargo_type) && !HasBit(st->cached_roadstop_cargo_triggers, cargo_type)) return;
|
||||
if (st->cached_roadstop_cargo_triggers.None()) return;
|
||||
if (IsValidCargoType(cargo_type) && !st->cached_roadstop_cargo_triggers.Test(cargo_type)) return;
|
||||
|
||||
st->waiting_random_triggers.Set(trigger);
|
||||
|
||||
uint32_t whole_reseed = 0;
|
||||
|
||||
/* Bitmask of completely empty cargo types to be matched. */
|
||||
CargoTypes empty_mask{};
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
empty_mask = GetEmptyMask(Station::From(st));
|
||||
}
|
||||
CargoTypes not_empty_mask = (trigger == StationRandomTrigger::CargoTaken) ? GetEmptyMask(Station::From(st)).Flip() : ALL_CARGOTYPES;
|
||||
|
||||
StationRandomTriggers used_random_triggers;
|
||||
auto process_tile = [&](TileIndex cur_tile) {
|
||||
|
@ -443,10 +440,10 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom
|
|||
/* Cargo taken "will only be triggered if all of those
|
||||
* cargo types have no more cargo waiting." */
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
if ((ss->cargo_triggers & ~empty_mask) != 0) return;
|
||||
if (ss->cargo_triggers.Any(not_empty_mask)) return;
|
||||
}
|
||||
|
||||
if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) {
|
||||
if (!IsValidCargoType(cargo_type) || ss->cargo_triggers.Test(cargo_type)) {
|
||||
RoadStopResolverObject object(ss, st, cur_tile, INVALID_ROADTYPE, GetStationType(cur_tile), GetStationGfx(cur_tile));
|
||||
object.SetWaitingRandomTriggers(st->waiting_random_triggers);
|
||||
|
||||
|
@ -621,7 +618,7 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex)
|
|||
} else {
|
||||
st->roadstop_speclist.clear();
|
||||
st->cached_roadstop_anim_triggers = {};
|
||||
st->cached_roadstop_cargo_triggers = 0;
|
||||
st->cached_roadstop_cargo_triggers.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -636,13 +633,13 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex)
|
|||
void RoadStopUpdateCachedTriggers(BaseStation *st)
|
||||
{
|
||||
st->cached_roadstop_anim_triggers = {};
|
||||
st->cached_roadstop_cargo_triggers = 0;
|
||||
st->cached_roadstop_cargo_triggers.Reset();
|
||||
|
||||
/* Combine animation trigger bitmask for all road stop specs
|
||||
* of this station. */
|
||||
for (const auto &sm : GetStationSpecList<RoadStopSpec>(st)) {
|
||||
if (sm.spec == nullptr) continue;
|
||||
st->cached_roadstop_anim_triggers.Set(sm.spec->animation.triggers);
|
||||
st->cached_roadstop_cargo_triggers |= sm.spec->cargo_triggers;
|
||||
st->cached_roadstop_cargo_triggers.Set(sm.spec->cargo_triggers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
|
|||
RoadStopCallbackMasks callback_mask{};
|
||||
RoadStopSpecFlags flags{};
|
||||
|
||||
CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing
|
||||
CargoTypes cargo_triggers{}; ///< Bitmask of cargo types which cause trigger re-randomizing
|
||||
|
||||
AnimationInfo<StationAnimationTriggers> animation;
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ uint32_t Station::GetNewGRFVariable(const ResolverObject &object, uint8_t variab
|
|||
{
|
||||
switch (variable) {
|
||||
case 0x48: { // Accepted cargo types
|
||||
uint32_t value = GetAcceptanceMask(this);
|
||||
uint32_t value = GetAcceptanceMask(this).base();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -514,14 +514,14 @@ uint32_t Waypoint::GetNewGRFVariable(const ResolverObject &, uint8_t variable, [
|
|||
uint cargo = 0;
|
||||
const Station *st = Station::From(this->station_scope.st);
|
||||
|
||||
switch (this->station_scope.cargo_type) {
|
||||
case INVALID_CARGO:
|
||||
case CargoGRFFileProps::SG_DEFAULT_NA:
|
||||
case CargoGRFFileProps::SG_PURCHASE:
|
||||
switch (this->station_scope.cargo_type.base()) {
|
||||
case INVALID_CARGO.base():
|
||||
case CargoGRFFileProps::SG_DEFAULT_NA.base():
|
||||
case CargoGRFFileProps::SG_PURCHASE.base():
|
||||
cargo = 0;
|
||||
break;
|
||||
|
||||
case CargoGRFFileProps::SG_DEFAULT:
|
||||
case CargoGRFFileProps::SG_DEFAULT.base():
|
||||
for (const GoodsEntry &ge : st->goods) {
|
||||
if (!ge.HasData()) continue;
|
||||
cargo += ge.GetData().cargo.TotalCount();
|
||||
|
@ -771,7 +771,7 @@ void DeallocateSpecFromStation(BaseStation *st, uint8_t specindex)
|
|||
} else {
|
||||
st->speclist.clear();
|
||||
st->cached_anim_triggers = {};
|
||||
st->cached_cargo_triggers = 0;
|
||||
st->cached_cargo_triggers.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -948,17 +948,14 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio
|
|||
/* Check the cached cargo trigger bitmask to see if we need
|
||||
* to bother with any further processing.
|
||||
* Note: cached_cargo_triggers must be non-zero even for cargo-independent triggers. */
|
||||
if (st->cached_cargo_triggers == 0) return;
|
||||
if (IsValidCargoType(cargo_type) && !HasBit(st->cached_cargo_triggers, cargo_type)) return;
|
||||
if (st->cached_cargo_triggers.None()) return;
|
||||
if (IsValidCargoType(cargo_type) && !st->cached_cargo_triggers.Test(cargo_type)) return;
|
||||
|
||||
uint32_t whole_reseed = 0;
|
||||
ETileArea area = ETileArea(st, trigger_tile, tas[static_cast<size_t>(trigger)]);
|
||||
|
||||
/* Bitmask of completely empty cargo types to be matched. */
|
||||
CargoTypes empty_mask{};
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
empty_mask = GetEmptyMask(Station::From(st));
|
||||
}
|
||||
CargoTypes not_empty_mask = (trigger == StationRandomTrigger::CargoTaken) ? GetEmptyMask(Station::From(st)).Flip() : ALL_CARGOTYPES;
|
||||
|
||||
/* Store triggers now for var 5F */
|
||||
st->waiting_random_triggers.Set(trigger);
|
||||
|
@ -973,10 +970,10 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio
|
|||
/* Cargo taken "will only be triggered if all of those
|
||||
* cargo types have no more cargo waiting." */
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
if ((ss->cargo_triggers & ~empty_mask) != 0) continue;
|
||||
if (ss->cargo_triggers.Any(not_empty_mask)) continue;
|
||||
}
|
||||
|
||||
if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) {
|
||||
if (!IsValidCargoType(cargo_type) || ss->cargo_triggers.Test(cargo_type)) {
|
||||
StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
|
||||
object.SetWaitingRandomTriggers(st->waiting_random_triggers);
|
||||
|
||||
|
@ -1016,14 +1013,14 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio
|
|||
void StationUpdateCachedTriggers(BaseStation *st)
|
||||
{
|
||||
st->cached_anim_triggers = {};
|
||||
st->cached_cargo_triggers = 0;
|
||||
st->cached_cargo_triggers.Reset();
|
||||
|
||||
/* Combine animation trigger bitmask for all station specs
|
||||
* of this station. */
|
||||
for (const auto &sm : GetStationSpecList<StationSpec>(st)) {
|
||||
if (sm.spec == nullptr) continue;
|
||||
st->cached_anim_triggers.Set(sm.spec->animation.triggers);
|
||||
st->cached_cargo_triggers |= sm.spec->cargo_triggers;
|
||||
st->cached_cargo_triggers.Set(sm.spec->cargo_triggers);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ using StationSpecFlags = EnumBitSet<StationSpecFlag, uint8_t>;
|
|||
struct StationSpec : NewGRFSpecBase<StationClassID> {
|
||||
StationSpec() : name(0),
|
||||
disallowed_platforms(0), disallowed_lengths(0),
|
||||
cargo_threshold(0), cargo_triggers(0),
|
||||
cargo_threshold(0), cargo_triggers{},
|
||||
callback_mask(0), flags(0)
|
||||
{}
|
||||
|
||||
|
|
|
@ -862,7 +862,7 @@ static void ProcessNewGRFStringControlCode(char32_t scc, StringConsumer &consume
|
|||
|
||||
case SCC_NEWGRF_PRINT_WORD_CARGO_NAME: {
|
||||
CargoType cargo = GetCargoTranslation(stack.PopUnsignedWord(), stack.grffile);
|
||||
params.emplace_back(cargo < NUM_CARGO ? 1ULL << cargo : 0);
|
||||
params.emplace_back(cargo < NUM_CARGO ? CargoTypes{cargo}.base() : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -635,7 +635,7 @@ static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, Carg
|
|||
CargoType pass = GetCargoTypeByLabel(CT_PASSENGERS);
|
||||
if (IsValidCargoType(pass)) {
|
||||
acceptance[pass] += std::max(1U, level);
|
||||
SetBit(always_accepted, pass);
|
||||
always_accepted.Set(pass);
|
||||
}
|
||||
|
||||
/* Top town building generates 4, HQ can make up to 8. The
|
||||
|
@ -645,7 +645,7 @@ static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, Carg
|
|||
CargoType mail = GetCargoTypeByLabel(CT_MAIL);
|
||||
if (IsValidCargoType(mail)) {
|
||||
acceptance[mail] += std::max(1U, level / 2);
|
||||
SetBit(always_accepted, mail);
|
||||
always_accepted.Set(mail);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
|
|||
|
||||
if (v->HasArticulatedPart()) {
|
||||
CargoArray max_cargo{};
|
||||
std::array<StringID, NUM_CARGO> subtype_text{};
|
||||
TypedIndexContainer<std::array<StringID, NUM_CARGO>, CargoType> subtype_text{};
|
||||
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
max_cargo[u->cargo_type] += u->cargo_cap;
|
||||
|
|
|
@ -383,7 +383,7 @@ public:
|
|||
{
|
||||
Station *st = Station::From(bst);
|
||||
|
||||
SlSetStructListLength(NUM_CARGO);
|
||||
SlSetStructListLength(std::size(st->goods));
|
||||
|
||||
for (GoodsEntry &ge : st->goods) {
|
||||
SlStationGoods::cargo_reserved_count = ge.HasData() ? ge.GetData().cargo.reserved_count : 0;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
{
|
||||
if (!IsValidCargo(cargo_type)) return std::nullopt;
|
||||
|
||||
return ::StrMakeValid(::GetString(STR_JUST_CARGO_LIST, 1ULL << cargo_type), {});
|
||||
return ::StrMakeValid(::GetString(STR_JUST_CARGO_LIST, CargoTypes{cargo_type}), {});
|
||||
}
|
||||
|
||||
/* static */ std::optional<std::string> ScriptCargo::GetCargoLabel(CargoType cargo_type)
|
||||
|
|
|
@ -60,9 +60,9 @@ public:
|
|||
*/
|
||||
enum SpecialCargoType {
|
||||
/* Note: these values represent part of the in-game CargoTypes enum */
|
||||
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.
|
||||
CT_AUTO_REFIT = ::CARGO_AUTO_REFIT.base(), ///< Automatically choose cargo type when doing auto-refitting.
|
||||
CT_NO_REFIT = ::CARGO_NO_REFIT.base(), ///< Do not refit cargo of a vehicle.
|
||||
CT_INVALID = ::INVALID_CARGO.base(), ///< An invalid cargo type.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
ScriptCargoList::ScriptCargoList()
|
||||
{
|
||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||
this->AddItem(cs->Index());
|
||||
this->AddItem(cs->Index().base());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ ScriptCargoList_IndustryAccepting::ScriptCargoList_IndustryAccepting(IndustryID
|
|||
const Industry *ind = ::Industry::Get(industry_id);
|
||||
for (const auto &a : ind->accepted) {
|
||||
if (::IsValidCargoType(a.cargo)) {
|
||||
this->AddItem(a.cargo);
|
||||
this->AddItem(a.cargo.base());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ ScriptCargoList_IndustryProducing::ScriptCargoList_IndustryProducing(IndustryID
|
|||
const Industry *ind = ::Industry::Get(industry_id);
|
||||
for (const auto &p : ind->produced) {
|
||||
if (::IsValidCargoType(p.cargo)) {
|
||||
this->AddItem(p.cargo);
|
||||
this->AddItem(p.cargo.base());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ ScriptCargoList_StationAccepting::ScriptCargoList_StationAccepting(StationID sta
|
|||
if (!ScriptStation::IsValidStation(station_id)) return;
|
||||
|
||||
const Station *st = ::Station::Get(station_id);
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
if (st->goods[cargo].status.Test(GoodsEntry::State::Acceptance)) this->AddItem(cargo);
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
if (st->goods[cargo].status.Test(GoodsEntry::State::Acceptance)) this->AddItem(cargo.base());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
if (!IsValidEngine(engine_id)) return false;
|
||||
if (!ScriptCargo::IsValidCargo(cargo_type)) return false;
|
||||
|
||||
return HasBit(::GetUnionOfArticulatedRefitMasks(engine_id, true), cargo_type);
|
||||
return ::GetUnionOfArticulatedRefitMasks(engine_id, true).Test(cargo_type);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptEngine::CanPullCargo(EngineID engine_id, CargoType cargo_type)
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
ScriptList *list = new ScriptList();
|
||||
for (const CargoType &cargo : ins->produced_cargo) {
|
||||
if (::IsValidCargoType(cargo)) list->AddItem(cargo);
|
||||
if (::IsValidCargoType(cargo)) list->AddItem(cargo.base());
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -86,7 +86,7 @@
|
|||
|
||||
ScriptList *list = new ScriptList();
|
||||
for (const CargoType &cargo : ins->accepts_cargo) {
|
||||
if (::IsValidCargoType(cargo)) list->AddItem(cargo);
|
||||
if (::IsValidCargoType(cargo)) list->AddItem(cargo.base());
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -227,7 +227,7 @@ void BuildLinkStatsLegend()
|
|||
|
||||
_legend_linkstats[i].legend = cs->name;
|
||||
_legend_linkstats[i].colour = cs->legend_colour;
|
||||
_legend_linkstats[i].type = cs->Index();
|
||||
_legend_linkstats[i].type = cs->Index().base(); /// IndustryType!?
|
||||
_legend_linkstats[i].show_on_map = true;
|
||||
}
|
||||
|
||||
|
@ -1254,9 +1254,9 @@ protected:
|
|||
*/
|
||||
void SetOverlayCargoMask()
|
||||
{
|
||||
CargoTypes cargo_mask = 0;
|
||||
CargoTypes cargo_mask{};
|
||||
for (int i = 0; i != _smallmap_cargo_count; ++i) {
|
||||
if (_legend_linkstats[i].show_on_map) SetBit(cargo_mask, _legend_linkstats[i].type);
|
||||
if (_legend_linkstats[i].show_on_map) cargo_mask.Set(static_cast<CargoType>(_legend_linkstats[i].type));
|
||||
}
|
||||
this->overlay->SetCargoMask(cargo_mask);
|
||||
}
|
||||
|
@ -1453,7 +1453,7 @@ public:
|
|||
SmallMapWindow(WindowDesc &desc, int window_number) : Window(desc)
|
||||
{
|
||||
_smallmap_industry_highlight = IT_INVALID;
|
||||
this->overlay = std::make_unique<LinkGraphOverlay>(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
|
||||
this->overlay = std::make_unique<LinkGraphOverlay>(this, WID_SM_MAP, CargoTypes{}, this->GetOverlayCompanyMask(), 1);
|
||||
this->CreateNestedTree();
|
||||
this->LowerWidget(WID_SM_CONTOUR + this->map_type);
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ Station::~Station()
|
|||
if (a->targetairport == this->index) a->targetairport = StationID::Invalid();
|
||||
}
|
||||
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
LinkGraph *lg = LinkGraph::GetIfValid(this->goods[cargo].link_graph);
|
||||
if (lg == nullptr) continue;
|
||||
|
||||
|
|
|
@ -526,7 +526,7 @@ public:
|
|||
|
||||
uint8_t last_vehicle_type = 0;
|
||||
std::list<Vehicle *> loading_vehicles{};
|
||||
std::array<GoodsEntry, NUM_CARGO> goods; ///< Goods at this station
|
||||
TypedIndexContainer<std::array<GoodsEntry, NUM_CARGO>, CargoType> goods; ///< Goods at this station
|
||||
CargoTypes always_accepted{}; ///< Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept cargo)
|
||||
|
||||
IndustryList industries_near{}; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry()
|
||||
|
|
|
@ -499,10 +499,10 @@ void ClearAllStationCachedNames()
|
|||
*/
|
||||
CargoTypes GetAcceptanceMask(const Station *st)
|
||||
{
|
||||
CargoTypes mask = 0;
|
||||
CargoTypes mask{};
|
||||
|
||||
for (auto it = std::begin(st->goods); it != std::end(st->goods); ++it) {
|
||||
if (it->status.Test(GoodsEntry::State::Acceptance)) SetBit(mask, std::distance(std::begin(st->goods), it));
|
||||
if (it->status.Test(GoodsEntry::State::Acceptance)) mask.Set(static_cast<CargoType>(std::distance(std::begin(st->goods), it)));
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
@ -514,10 +514,10 @@ CargoTypes GetAcceptanceMask(const Station *st)
|
|||
*/
|
||||
CargoTypes GetEmptyMask(const Station *st)
|
||||
{
|
||||
CargoTypes mask = 0;
|
||||
CargoTypes mask{};
|
||||
|
||||
for (auto it = std::begin(st->goods); it != std::end(st->goods); ++it) {
|
||||
if (!it->HasData() || it->GetData().cargo.TotalCount() == 0) SetBit(mask, std::distance(std::begin(st->goods), it));
|
||||
if (!it->HasData() || it->GetData().cargo.TotalCount() == 0) mask.Set(static_cast<CargoType>(std::distance(std::begin(st->goods), it)));
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ CargoArray GetProductionAroundTiles(TileIndex north_tile, int w, int h, int rad)
|
|||
CargoArray GetAcceptanceAroundTiles(TileIndex center_tile, int w, int h, int rad, CargoTypes *always_accepted)
|
||||
{
|
||||
CargoArray acceptance{};
|
||||
if (always_accepted != nullptr) *always_accepted = 0;
|
||||
if (always_accepted != nullptr) always_accepted->Reset();
|
||||
|
||||
TileArea ta = TileArea(center_tile, w, h).Expand(rad);
|
||||
|
||||
|
@ -604,7 +604,7 @@ CargoArray GetAcceptanceAroundTiles(TileIndex center_tile, int w, int h, int rad
|
|||
static CargoArray GetAcceptanceAroundStation(const Station *st, CargoTypes *always_accepted)
|
||||
{
|
||||
CargoArray acceptance{};
|
||||
if (always_accepted != nullptr) *always_accepted = 0;
|
||||
if (always_accepted != nullptr) always_accepted->Reset();
|
||||
|
||||
BitmapTileIterator it(st->catchment_tiles);
|
||||
for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
|
||||
|
@ -631,7 +631,7 @@ void UpdateStationAcceptance(Station *st, bool show_msg)
|
|||
}
|
||||
|
||||
/* Adjust in case our station only accepts fewer kinds of goods */
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
uint amt = acceptance[cargo];
|
||||
|
||||
/* Make sure the station can accept the goods type. */
|
||||
|
@ -655,12 +655,12 @@ void UpdateStationAcceptance(Station *st, bool show_msg)
|
|||
/* show a message to report that the acceptance was changed? */
|
||||
if (show_msg && st->owner == _local_company && st->IsInUse()) {
|
||||
/* Combine old and new masks to get changes */
|
||||
CargoTypes accepts = new_acc & ~old_acc;
|
||||
CargoTypes rejects = ~new_acc & old_acc;
|
||||
CargoTypes accepts = new_acc & CargoTypes{old_acc}.Flip();
|
||||
CargoTypes rejects = CargoTypes{new_acc}.Flip() & old_acc;
|
||||
|
||||
/* Show news message if there are any changes */
|
||||
if (accepts != 0) ShowRejectOrAcceptNews(st, accepts, false);
|
||||
if (rejects != 0) ShowRejectOrAcceptNews(st, rejects, true);
|
||||
if (accepts.Any()) ShowRejectOrAcceptNews(st, accepts, false);
|
||||
if (rejects.Any()) ShowRejectOrAcceptNews(st, rejects, true);
|
||||
}
|
||||
|
||||
/* redraw the station view since acceptance changed */
|
||||
|
@ -3760,13 +3760,13 @@ static VehicleEnterTileStates VehicleEnter_Station(Vehicle *v, TileIndex tile, i
|
|||
void TriggerWatchedCargoCallbacks(Station *st)
|
||||
{
|
||||
/* Collect cargoes accepted since the last big tick. */
|
||||
CargoTypes cargoes = 0;
|
||||
for (CargoType cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
|
||||
if (st->goods[cargo_type].status.Test(GoodsEntry::State::AcceptedBigtick)) SetBit(cargoes, cargo_type);
|
||||
CargoTypes cargoes{};
|
||||
for (CargoType cargo_type{}; cargo_type < NUM_CARGO; ++cargo_type) {
|
||||
if (st->goods[cargo_type].status.Test(GoodsEntry::State::AcceptedBigtick)) cargoes.Set(cargo_type);
|
||||
}
|
||||
|
||||
/* Anything to do? */
|
||||
if (cargoes == 0) return;
|
||||
if (cargoes.None()) return;
|
||||
|
||||
/* Loop over all houses in the catchment. */
|
||||
BitmapTileIterator it(st->catchment_tiles);
|
||||
|
@ -4027,7 +4027,7 @@ void RerouteCargo(Station *st, CargoType cargo, StationID avoid, StationID avoid
|
|||
*/
|
||||
void DeleteStaleLinks(Station *from)
|
||||
{
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
const bool auto_distributed = (_settings_game.linkgraph.GetDistributionType(cargo) != DT_MANUAL);
|
||||
GoodsEntry &ge = from->goods[cargo];
|
||||
LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph);
|
||||
|
|
|
@ -76,7 +76,7 @@ using RoadWaypointTypeFilter = GenericWaypointTypeFilter<true, MP_ROAD>;
|
|||
int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad, bool supplies)
|
||||
{
|
||||
TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y);
|
||||
CargoTypes cargo_mask = 0;
|
||||
CargoTypes cargo_mask{};
|
||||
if (_thd.drawstyle == HT_RECT && tile < Map::Size()) {
|
||||
CargoArray cargoes;
|
||||
if (supplies) {
|
||||
|
@ -86,14 +86,14 @@ int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad,
|
|||
}
|
||||
|
||||
/* Convert cargo counts to a set of cargo bits, and draw the result. */
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
switch (sct) {
|
||||
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(cargo, CargoClass::Passengers)) continue; break;
|
||||
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(cargo, CargoClass::Passengers)) continue; break;
|
||||
case SCT_ALL: break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
if (cargoes[cargo] >= (supplies ? 1U : 8U)) SetBit(cargo_mask, cargo);
|
||||
if (cargoes[cargo] >= (supplies ? 1U : 8U)) cargo_mask.Set(cargo);
|
||||
}
|
||||
}
|
||||
return DrawStringMultiLine(r, GetString(supplies ? STR_STATION_BUILD_SUPPLIES_CARGO : STR_STATION_BUILD_ACCEPTS_CARGO, cargo_mask));
|
||||
|
@ -291,7 +291,7 @@ protected:
|
|||
Scrollbar *vscroll = nullptr;
|
||||
uint rating_width = 0;
|
||||
bool filter_expanded = false;
|
||||
std::array<uint16_t, NUM_CARGO> stations_per_cargo_type{}; ///< Number of stations with a rating for each cargo type.
|
||||
TypedIndexContainer<std::array<uint16_t, NUM_CARGO>, CargoType> stations_per_cargo_type{}; ///< Number of stations with a rating for each cargo type.
|
||||
uint16_t stations_per_cargo_type_no_rating = 0; ///< Number of stations without a rating.
|
||||
|
||||
/**
|
||||
|
@ -314,13 +314,13 @@ protected:
|
|||
if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) {
|
||||
bool has_rating = false;
|
||||
/* Add to the station/cargo counts. */
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
if (st->goods[cargo].HasRating()) this->stations_per_cargo_type[cargo]++;
|
||||
}
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
if (st->goods[cargo].HasRating()) {
|
||||
has_rating = true;
|
||||
if (HasBit(this->filter.cargoes, cargo)) {
|
||||
if (this->filter.cargoes.Test(cargo)) {
|
||||
this->stations.push_back(st);
|
||||
break;
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ protected:
|
|||
{
|
||||
int diff = 0;
|
||||
|
||||
for (CargoType cargo : SetCargoBitIterator(cargo_filter)) {
|
||||
for (CargoType cargo : cargo_filter) {
|
||||
diff += (a->goods[cargo].HasData() ? a->goods[cargo].GetData().cargo.TotalCount() : 0) - (b->goods[cargo].HasData() ? b->goods[cargo].GetData().cargo.TotalCount() : 0);
|
||||
}
|
||||
|
||||
|
@ -371,7 +371,7 @@ protected:
|
|||
{
|
||||
int diff = 0;
|
||||
|
||||
for (CargoType cargo : SetCargoBitIterator(cargo_filter)) {
|
||||
for (CargoType cargo : cargo_filter) {
|
||||
diff += (a->goods[cargo].HasData() ? a->goods[cargo].GetData().cargo.AvailableCount() : 0) - (b->goods[cargo].HasData() ? b->goods[cargo].GetData().cargo.AvailableCount() : 0);
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ protected:
|
|||
uint8_t maxr1 = 0;
|
||||
uint8_t maxr2 = 0;
|
||||
|
||||
for (CargoType cargo : SetCargoBitIterator(cargo_filter)) {
|
||||
for (CargoType cargo : cargo_filter) {
|
||||
if (a->goods[cargo].HasRating()) maxr1 = std::max(maxr1, a->goods[cargo].rating);
|
||||
if (b->goods[cargo].HasRating()) maxr2 = std::max(maxr2, b->goods[cargo].rating);
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ protected:
|
|||
uint8_t minr1 = 255;
|
||||
uint8_t minr2 = 255;
|
||||
|
||||
for (CargoType cargo : SetCargoBitIterator(cargo_filter)) {
|
||||
for (CargoType cargo : cargo_filter) {
|
||||
if (a->goods[cargo].HasRating()) minr1 = std::min(minr1, a->goods[cargo].rating);
|
||||
if (b->goods[cargo].HasRating()) minr2 = std::min(minr2, b->goods[cargo].rating);
|
||||
}
|
||||
|
@ -558,9 +558,9 @@ public:
|
|||
}
|
||||
|
||||
if (widget == WID_STL_CARGODROPDOWN) {
|
||||
if (this->filter.cargoes == 0) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ONLY_NO_RATING : STR_STATION_LIST_CARGO_FILTER_NO_CARGO_TYPES);
|
||||
if (this->filter.cargoes.None()) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ONLY_NO_RATING : STR_STATION_LIST_CARGO_FILTER_NO_CARGO_TYPES);
|
||||
if (this->filter.cargoes == _cargo_mask) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ALL_AND_NO_RATING : STR_CARGO_TYPE_FILTER_ALL);
|
||||
if (CountBits(this->filter.cargoes) == 1 && !this->filter.include_no_rating) return GetString(CargoSpec::Get(FindFirstBit(this->filter.cargoes))->name);
|
||||
if (this->filter.cargoes.Count() == 1 && !this->filter.include_no_rating) return GetString(CargoSpec::Get(*this->filter.cargoes.begin())->name);
|
||||
return GetString(STR_STATION_LIST_CARGO_FILTER_MULTIPLE);
|
||||
}
|
||||
|
||||
|
@ -573,7 +573,7 @@ public:
|
|||
using DropDownListCargoItem = DropDownCheck<DropDownString<DropDownListIconItem, FS_SMALL, true>>;
|
||||
|
||||
DropDownList list;
|
||||
list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_SELECT_ALL, CargoFilterCriteria::CF_SELECT_ALL));
|
||||
list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_SELECT_ALL, CargoFilterCriteria::CF_SELECT_ALL.base()));
|
||||
list.push_back(MakeDropDownListDividerItem());
|
||||
|
||||
bool any_hidden = false;
|
||||
|
@ -582,7 +582,7 @@ public:
|
|||
if (count == 0 && !expanded) {
|
||||
any_hidden = true;
|
||||
} else {
|
||||
list.push_back(std::make_unique<DropDownString<DropDownListCheckedItem, FS_SMALL, true>>(fmt::format("{}", count), 0, this->filter.include_no_rating, GetString(STR_STATION_LIST_CARGO_FILTER_NO_RATING), CargoFilterCriteria::CF_NO_RATING, false, count == 0));
|
||||
list.push_back(std::make_unique<DropDownString<DropDownListCheckedItem, FS_SMALL, true>>(fmt::format("{}", count), 0, this->filter.include_no_rating, GetString(STR_STATION_LIST_CARGO_FILTER_NO_RATING), CargoFilterCriteria::CF_NO_RATING.base(), false, count == 0));
|
||||
}
|
||||
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
|
@ -591,13 +591,13 @@ public:
|
|||
if (count == 0 && !expanded) {
|
||||
any_hidden = true;
|
||||
} else {
|
||||
list.push_back(std::make_unique<DropDownListCargoItem>(HasBit(this->filter.cargoes, cs->Index()), fmt::format("{}", count), d, cs->GetCargoIcon(), PAL_NONE, GetString(cs->name), cs->Index(), false, count == 0));
|
||||
list.push_back(std::make_unique<DropDownListCargoItem>(this->filter.cargoes.Test(cs->Index()), fmt::format("{}", count), d, cs->GetCargoIcon(), PAL_NONE, GetString(cs->name), cs->Index().base(), false, count == 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (!expanded && any_hidden) {
|
||||
if (list.size() > 2) list.push_back(MakeDropDownListDividerItem());
|
||||
list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_EXPAND, CargoFilterCriteria::CF_EXPAND_LIST));
|
||||
list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_EXPAND, CargoFilterCriteria::CF_EXPAND_LIST.base()));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -684,11 +684,11 @@ public:
|
|||
if (widget == WID_STL_CARGODROPDOWN) {
|
||||
FilterState oldstate = this->filter;
|
||||
|
||||
if (index >= 0 && index < NUM_CARGO) {
|
||||
if (IsInsideMM(index, 0, NUM_CARGO)) {
|
||||
if (_ctrl_pressed) {
|
||||
ToggleBit(this->filter.cargoes, index);
|
||||
this->filter.cargoes.Flip(static_cast<CargoType>(index));
|
||||
} else {
|
||||
this->filter.cargoes = 1ULL << index;
|
||||
this->filter.cargoes = static_cast<CargoType>(index);
|
||||
this->filter.include_no_rating = false;
|
||||
}
|
||||
} else if (index == CargoFilterCriteria::CF_NO_RATING) {
|
||||
|
@ -696,7 +696,7 @@ public:
|
|||
this->filter.include_no_rating = !this->filter.include_no_rating;
|
||||
} else {
|
||||
this->filter.include_no_rating = true;
|
||||
this->filter.cargoes = 0;
|
||||
this->filter.cargoes.Reset();
|
||||
}
|
||||
} else if (index == CargoFilterCriteria::CF_SELECT_ALL) {
|
||||
this->filter.cargoes = _cargo_mask;
|
||||
|
@ -1047,13 +1047,11 @@ private:
|
|||
void IncrementSize();
|
||||
|
||||
CargoDataEntry *parent; ///< the parent of this entry.
|
||||
const union {
|
||||
StationID station; ///< ID of the station this entry is associated with.
|
||||
struct {
|
||||
CargoType cargo; ///< ID of the cargo this entry is associated with.
|
||||
bool transfers; ///< If there are transfers for this cargo.
|
||||
};
|
||||
};
|
||||
|
||||
const StationID station = StationID::Invalid(); ///< ID of the station this entry is associated with.
|
||||
const CargoType cargo = INVALID_CARGO; ///< ID of the cargo this entry is associated with.
|
||||
bool transfers = false; ///< If there are transfers for this cargo.
|
||||
|
||||
uint num_children; ///< the number of subentries belonging to this entry.
|
||||
uint count; ///< sum of counts of all children or amount of cargo for this entry.
|
||||
std::unique_ptr<CargoDataSet> children; ///< the children of this entry.
|
||||
|
@ -1673,7 +1671,7 @@ struct StationViewWindow : public Window {
|
|||
*/
|
||||
void BuildCargoList(CargoDataEntry *entry, const Station *st)
|
||||
{
|
||||
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
|
||||
for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) {
|
||||
|
||||
if (this->cached_destinations.Retrieve(cargo) == nullptr) {
|
||||
this->RecalcDestinations(cargo);
|
||||
|
@ -2141,8 +2139,8 @@ struct StationViewWindow : public Window {
|
|||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (gui_scope) {
|
||||
if (data >= 0 && data < NUM_CARGO) {
|
||||
this->cached_destinations.Remove((CargoType)data);
|
||||
if (IsInsideMM(data, 0, NUM_CARGO)) {
|
||||
this->cached_destinations.Remove(static_cast<CargoType>(data));
|
||||
} else {
|
||||
this->ReInit();
|
||||
}
|
||||
|
|
|
@ -1332,10 +1332,10 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
|
|||
/* Tiny description of cargotypes. Layout:
|
||||
* param 1: cargo type
|
||||
* param 2: cargo count */
|
||||
CargoType cargo = args.GetNextParameter<CargoType>();
|
||||
CargoType cargo{args.GetNextParameter<CargoType::BaseType>()};
|
||||
int64_t amount = args.GetNextParameter<int64_t>();
|
||||
|
||||
if (cargo >= CargoSpec::GetArraySize()) {
|
||||
if (cargo.base() >= CargoSpec::GetArraySize()) {
|
||||
builder += "(invalid cargo type)";
|
||||
break;
|
||||
}
|
||||
|
@ -1361,10 +1361,10 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
|
|||
/* Short description of cargotypes. Layout:
|
||||
* param 1: cargo type
|
||||
* param 2: cargo count */
|
||||
CargoType cargo = args.GetNextParameter<CargoType>();
|
||||
CargoType cargo{args.GetNextParameter<CargoType::BaseType>()};
|
||||
int64_t amount = args.GetNextParameter<int64_t>();
|
||||
|
||||
if (cargo >= CargoSpec::GetArraySize()) {
|
||||
if (cargo.base() >= CargoSpec::GetArraySize()) {
|
||||
builder += "(invalid cargo type)";
|
||||
break;
|
||||
}
|
||||
|
@ -1398,9 +1398,9 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
|
|||
|
||||
case SCC_CARGO_LONG: { // {CARGO_LONG}
|
||||
/* First parameter is cargo type, second parameter is cargo count */
|
||||
CargoType cargo = args.GetNextParameter<CargoType>();
|
||||
CargoType cargo{args.GetNextParameter<CargoType::BaseType>()};
|
||||
int64_t amount = args.GetNextParameter<int64_t>();
|
||||
if (cargo < CargoSpec::GetArraySize()) {
|
||||
if (cargo.base() < CargoSpec::GetArraySize()) {
|
||||
auto tmp_args = MakeParameters(amount);
|
||||
GetStringWithArgs(builder, CargoSpec::Get(cargo)->quantifier, tmp_args);
|
||||
} else if (!IsValidCargoType(cargo)) {
|
||||
|
@ -1417,7 +1417,7 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
|
|||
|
||||
std::string_view list_separator = GetListSeparator();
|
||||
for (const auto &cs : _sorted_cargo_specs) {
|
||||
if (!HasBit(cmask, cs->Index())) continue;
|
||||
if (!cmask.Test(cs->Index())) continue;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
|
|
|
@ -296,8 +296,8 @@ bool FindSubsidyTownCargoRoute()
|
|||
|
||||
/* Choose a random cargo that is produced in the town. */
|
||||
uint8_t cargo_number = RandomRange(cargo_count);
|
||||
CargoType cargo_type;
|
||||
for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
|
||||
CargoType cargo_type{};
|
||||
for (; cargo_type < NUM_CARGO; ++cargo_type) {
|
||||
if (town_cargo_produced[cargo_type] > 0) {
|
||||
if (cargo_number == 0) break;
|
||||
cargo_number--;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* @param f Bitmask of the climates
|
||||
* @note the 5 between b and f is the load amount
|
||||
*/
|
||||
#define MT(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MT(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/**
|
||||
* Writes the properties of a multiple-unit train into the EngineInfo struct.
|
||||
|
@ -39,7 +39,7 @@
|
|||
* @param f Bitmask of the climates
|
||||
* @note the 5 between b and f is the load amount
|
||||
*/
|
||||
#define MM(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{EngineMiscFlag::RailIsMU}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MM(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{EngineMiscFlag::RailIsMU}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/**
|
||||
* Writes the properties of a train carriage into the EngineInfo struct.
|
||||
|
@ -52,7 +52,7 @@
|
|||
* @see MT
|
||||
* @note the 5 between b and f is the load amount
|
||||
*/
|
||||
#define MW(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MW(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/**
|
||||
* Writes the properties of a road vehicle into the EngineInfo struct.
|
||||
|
@ -65,7 +65,7 @@
|
|||
* @param f Bitmask of the climates
|
||||
* @note the 5 between b and f is the load amount
|
||||
*/
|
||||
#define MR(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MR(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/**
|
||||
* Writes the properties of a ship into the EngineInfo struct.
|
||||
|
@ -77,7 +77,7 @@
|
|||
* @param f Bitmask of the climates
|
||||
* @note the 10 between b and f is the load amount
|
||||
*/
|
||||
#define MS(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 10, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MS(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 10, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/**
|
||||
* Writes the properties of an aeroplane into the EngineInfo struct.
|
||||
|
@ -88,7 +88,7 @@
|
|||
* @param e Bitmask of the climates
|
||||
* @note the 20 between b and e is the load amount
|
||||
*/
|
||||
#define MA(a, b, c, d, e) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 20, e, INVALID_CARGO, CT_INVALID, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
#define MA(a, b, c, d, e) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 20, e, INVALID_CARGO, CT_INVALID, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() }
|
||||
|
||||
/* Climates
|
||||
* T = Temperate
|
||||
|
|
|
@ -270,8 +270,8 @@ static const NIFeature _nif_industrytile = {
|
|||
|
||||
|
||||
/*** NewGRF industries ***/
|
||||
#define NIP_PRODUCED_CARGO(prop, base_class, slot, type, name) { name, [] (const void *b) -> uint32_t { return static_cast<const base_class *>(b)->GetProduced(slot).cargo; }, prop, type }
|
||||
#define NIP_ACCEPTED_CARGO(prop, base_class, slot, type, name) { name, [] (const void *b) -> uint32_t { return static_cast<const base_class *>(b)->GetAccepted(slot).cargo; }, prop, type }
|
||||
#define NIP_PRODUCED_CARGO(prop, base_class, slot, type, name) { name, [] (const void *b) -> uint32_t { return static_cast<const base_class *>(b)->GetProduced(slot).cargo.base(); }, prop, type }
|
||||
#define NIP_ACCEPTED_CARGO(prop, base_class, slot, type, name) { name, [] (const void *b) -> uint32_t { return static_cast<const base_class *>(b)->GetAccepted(slot).cargo.base(); }, prop, type }
|
||||
|
||||
static const NIProperty _nip_industries[] = {
|
||||
NIP_PRODUCED_CARGO(0x25, Industry, 0, NIT_CARGO, "produced cargo 0"),
|
||||
|
|
|
@ -1814,7 +1814,7 @@ static_assert(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4);
|
|||
{ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
|
||||
{INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO}, \
|
||||
bf, ba, true, SubstituteGRFFileProps(INVALID_HOUSE_ID), HouseCallbackMasks{}, {COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN}, \
|
||||
16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo<void>{}, 0, 0, 0, {}, {cg1, cg2, cg3}, }
|
||||
16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo<void>{}, 0, 0, CargoTypes{}, {}, {cg1, cg2, cg3}, }
|
||||
/** House specifications from original data */
|
||||
extern const HouseSpec _original_house_specs[] = {
|
||||
/**
|
||||
|
|
|
@ -169,7 +169,7 @@ inline void AddAcceptedCargo(TileIndex tile, CargoArray &acceptance, CargoTypes
|
|||
{
|
||||
AddAcceptedCargoProc *proc = _tile_type_procs[GetTileType(tile)]->add_accepted_cargo_proc;
|
||||
if (proc == nullptr) return;
|
||||
CargoTypes dummy = 0; // use dummy bitmask so there don't need to be several 'always_accepted != nullptr' checks
|
||||
CargoTypes dummy{}; // use dummy bitmask so there don't need to be several 'always_accepted != nullptr' checks
|
||||
proc(tile, acceptance, always_accepted == nullptr ? dummy : *always_accepted);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
|||
uint8_t exclusive_counter = 0; ///< months till the exclusivity expires
|
||||
TypedIndexContainer<std::array<int16_t, MAX_COMPANIES>, CompanyID> ratings{}; ///< ratings of each company for this town
|
||||
|
||||
std::array<TransportedCargoStat<uint32_t>, NUM_CARGO> supplied{}; ///< Cargo statistics about supplied cargo.
|
||||
TypedIndexContainer<std::array<TransportedCargoStat<uint32_t>, NUM_CARGO>, CargoType> supplied{}; ///< Cargo statistics about supplied cargo.
|
||||
std::array<TransportedCargoStat<uint16_t>, NUM_TAE> received{}; ///< Cargo statistics about received cargotypes.
|
||||
std::array<uint32_t, NUM_TAE> goal{}; ///< Amount of cargo required for the town to grow.
|
||||
|
||||
|
|
|
@ -783,7 +783,7 @@ static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &ac
|
|||
{
|
||||
if (!IsValidCargoType(cargo) || amount == 0) return;
|
||||
acceptance[cargo] += amount;
|
||||
SetBit(always_accepted, cargo);
|
||||
always_accepted.Set(cargo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -400,7 +400,7 @@ public:
|
|||
for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
|
||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
|
||||
CargoType cargo_type = cs->Index();
|
||||
DrawString(tr, GetString(str_last_period, 1ULL << cargo_type, this->town->supplied[cargo_type].old_act, this->town->supplied[cargo_type].old_max));
|
||||
DrawString(tr, GetString(str_last_period, CargoTypes{cargo_type}, this->town->supplied[cargo_type].old_act, this->town->supplied[cargo_type].old_max));
|
||||
tr.top += GetCharacterHeight(FS_NORMAL);
|
||||
}
|
||||
}
|
||||
|
@ -1616,12 +1616,12 @@ static CargoTypes GetProducedCargoOfHouse(const HouseSpec *hs)
|
|||
uint amt = GB(callback, 0, 8);
|
||||
if (amt == 0) continue;
|
||||
|
||||
SetBit(produced, cargo);
|
||||
produced.Set(cargo);
|
||||
}
|
||||
} else {
|
||||
/* Cargo is not controlled by NewGRF, town production effect is used instead. */
|
||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) SetBit(produced, cs->Index());
|
||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) SetBit(produced, cs->Index());
|
||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) produced.Set(cs->Index());
|
||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) produced.Set(cs->Index());
|
||||
}
|
||||
return produced;
|
||||
}
|
||||
|
@ -1707,7 +1707,7 @@ struct BuildHouseWindow : public PickerWindow {
|
|||
}
|
||||
|
||||
CargoTypes produced = GetProducedCargoOfHouse(hs);
|
||||
if (produced != 0) {
|
||||
if (produced.Any()) {
|
||||
line << "\n";
|
||||
line << GetString(STR_HOUSE_PICKER_CARGO_PRODUCED, produced);
|
||||
}
|
||||
|
|
|
@ -246,10 +246,10 @@ bool Vehicle::NeedsServicing() const
|
|||
CargoTypes available_cargo_types, union_mask;
|
||||
GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types);
|
||||
/* Is there anything to refit? */
|
||||
if (union_mask != 0) {
|
||||
if (union_mask.Any()) {
|
||||
CargoType cargo_type;
|
||||
CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type);
|
||||
if (!HasAtMostOneBit(cargo_mask)) {
|
||||
if (!HasAtMostOneBit(cargo_mask.base())) {
|
||||
CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(new_engine);
|
||||
if ((cargo_mask & new_engine_default_cargoes) != cargo_mask) {
|
||||
/* We cannot refit to mixed cargoes in an automated way */
|
||||
|
@ -260,7 +260,7 @@ bool Vehicle::NeedsServicing() const
|
|||
/* Did the old vehicle carry anything? */
|
||||
if (IsValidCargoType(cargo_type)) {
|
||||
/* We can't refit the vehicle to carry the cargo we want */
|
||||
if (!HasBit(available_cargo_types, cargo_type)) continue;
|
||||
if (!available_cargo_types.Test(cargo_type)) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ static std::tuple<CommandCost, uint, uint16_t, CargoArray> RefitVehicle(Vehicle
|
|||
|
||||
/* If the vehicle is not refittable, or does not allow automatic refitting,
|
||||
* count its capacity nevertheless if the cargo matches */
|
||||
bool refittable = HasBit(e->info.refit_mask, new_cargo_type) && (!auto_refit || e->info.misc_flags.Test(EngineMiscFlag::AutoRefit));
|
||||
bool refittable = e->info.refit_mask.Test(new_cargo_type) && (!auto_refit || e->info.misc_flags.Test(EngineMiscFlag::AutoRefit));
|
||||
if (!refittable && v->cargo_type != new_cargo_type) {
|
||||
uint amount = e->DetermineCapacity(v, nullptr);
|
||||
if (amount > 0) cargo_capacities[v->cargo_type] += amount;
|
||||
|
|
|
@ -227,10 +227,10 @@ void BaseVehicleListWindow::BuildVehicleList()
|
|||
|
||||
GenerateVehicleSortList(&this->vehicles, this->vli);
|
||||
|
||||
CargoTypes used = 0;
|
||||
CargoTypes used{};
|
||||
for (const Vehicle *v : this->vehicles) {
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
if (u->cargo_cap > 0) SetBit(used, u->cargo_type);
|
||||
if (u->cargo_cap > 0) used.Set(u->cargo_type);
|
||||
}
|
||||
}
|
||||
this->used_cargoes = used;
|
||||
|
@ -483,10 +483,10 @@ void BaseVehicleListWindow::OnInit()
|
|||
|
||||
StringID BaseVehicleListWindow::GetCargoFilterLabel(CargoType cargo_type) const
|
||||
{
|
||||
switch (cargo_type) {
|
||||
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;
|
||||
switch (cargo_type.base()) {
|
||||
case CargoFilterCriteria::CF_ANY.base(): return STR_CARGO_TYPE_FILTER_ALL;
|
||||
case CargoFilterCriteria::CF_FREIGHT.base(): return STR_CARGO_TYPE_FILTER_FREIGHT;
|
||||
case CargoFilterCriteria::CF_NONE.base(): return STR_CARGO_TYPE_FILTER_NONE;
|
||||
default: return CargoSpec::Get(cargo_type)->name;
|
||||
}
|
||||
}
|
||||
|
@ -501,17 +501,17 @@ DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const
|
|||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY.base()));
|
||||
/* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT.base()));
|
||||
/* Add item for vehicles not carrying anything, e.g. train engines. */
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE.base()));
|
||||
|
||||
/* Add cargos */
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
if (!full && !HasBit(this->used_cargoes, cs->Index())) continue;
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index())));
|
||||
if (!full && !this->used_cargoes.Test(cs->Index())) continue;
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index().base(), false, !this->used_cargoes.Test(cs->Index())));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -619,7 +619,7 @@ uint8_t GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoType dest_ca
|
|||
for (Vehicle *v = v_for; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) {
|
||||
const Engine *e = v->GetEngine();
|
||||
if (!e->CanCarryCargo() || !e->info.callback_mask.Test(VehicleCallbackMask::CargoSuffix)) continue;
|
||||
if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
|
||||
if (!e->info.refit_mask.Test(dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
|
||||
|
||||
CargoType old_cargo_type = v->cargo_type;
|
||||
uint8_t old_cargo_subtype = v->cargo_subtype;
|
||||
|
@ -791,7 +791,7 @@ struct RefitWindow : public Window {
|
|||
for (const auto &cs : _sorted_cargo_specs) {
|
||||
CargoType cargo_type = cs->Index();
|
||||
/* Skip cargo type if it's not listed */
|
||||
if (!HasBit(cmask, cargo_type)) continue;
|
||||
if (!cmask.Test(cargo_type)) continue;
|
||||
|
||||
auto &list = this->refit_list[cargo_type];
|
||||
bool first_vehicle = list.empty();
|
||||
|
@ -1359,25 +1359,24 @@ void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *pare
|
|||
uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
|
||||
{
|
||||
/* List of cargo types of this engine */
|
||||
CargoTypes cmask = GetUnionOfArticulatedRefitMasks(engine, false);
|
||||
/* List of cargo types available in this climate */
|
||||
CargoTypes lmask = _cargo_mask;
|
||||
CargoTypes present = GetUnionOfArticulatedRefitMasks(engine, false);
|
||||
|
||||
/* Draw nothing if the engine is not refittable */
|
||||
if (HasAtMostOneBit(cmask)) return y;
|
||||
if (HasAtMostOneBit(present.base())) return y;
|
||||
|
||||
std::string str;
|
||||
if (cmask == lmask) {
|
||||
if (present == _cargo_mask) {
|
||||
/* Engine can be refitted to all types in this climate */
|
||||
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_TYPES, std::monostate{});
|
||||
} else {
|
||||
/* Check if we are able to refit to more cargo types and unable to. If
|
||||
* so, invert the cargo types to list those that we can't refit to. */
|
||||
if (CountBits(cmask ^ lmask) < CountBits(cmask) && CountBits(cmask ^ lmask) <= 7) {
|
||||
cmask ^= lmask;
|
||||
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, cmask);
|
||||
CargoTypes excluded = CargoTypes{present}.Flip(_cargo_mask);
|
||||
uint num_excluded = excluded.Count();
|
||||
if (num_excluded < present.Count() && num_excluded <= 7) {
|
||||
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, excluded);
|
||||
} else {
|
||||
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, cmask);
|
||||
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, present);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1793,12 +1792,12 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
|
|||
|
||||
if (_settings_client.gui.show_cargo_in_vehicle_lists) {
|
||||
/* Get the cargoes the vehicle can carry */
|
||||
CargoTypes vehicle_cargoes = 0;
|
||||
CargoTypes vehicle_cargoes{};
|
||||
|
||||
for (auto u = v; u != nullptr; u = u->Next()) {
|
||||
if (u->cargo_cap == 0) continue;
|
||||
|
||||
SetBit(vehicle_cargoes, u->cargo_type);
|
||||
vehicle_cargoes.Set(u->cargo_type);
|
||||
}
|
||||
|
||||
if (!v->name.empty()) {
|
||||
|
@ -2110,7 +2109,7 @@ public:
|
|||
return;
|
||||
|
||||
case WID_VL_FILTER_BY_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(false), this->cargo_filter_criteria, widget);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(false), this->cargo_filter_criteria.base(), widget);
|
||||
break;
|
||||
|
||||
case WID_VL_LIST: { // Matrix to show vehicles
|
||||
|
@ -2182,7 +2181,7 @@ public:
|
|||
break;
|
||||
|
||||
case WID_VL_FILTER_BY_CARGO:
|
||||
this->SetCargoFilter(index);
|
||||
this->SetCargoFilter(static_cast<CargoType>(index));
|
||||
break;
|
||||
|
||||
case WID_VL_MANAGE_VEHICLES_DROPDOWN:
|
||||
|
|
|
@ -116,7 +116,7 @@ struct BaseVehicleListWindow : public Window {
|
|||
void UpdateVehicleGroupBy(GroupBy group_by);
|
||||
void SortVehicleList();
|
||||
void BuildVehicleList();
|
||||
void SetCargoFilter(uint8_t index);
|
||||
void SetCargoFilter(CargoType index);
|
||||
void SetCargoFilterArray();
|
||||
void FilterVehicleList();
|
||||
StringID GetCargoFilterLabel(CargoType cargo_type) const;
|
||||
|
|
|
@ -1825,7 +1825,7 @@ void ViewportDoDraw(const Viewport &vp, int left, int top, int right, int bottom
|
|||
dp.height = UnScaleByZoom(dp.height, zoom);
|
||||
AutoRestoreBackup cur_dpi(_cur_dpi, &dp);
|
||||
|
||||
if (vp.overlay != nullptr && vp.overlay->GetCargoMask() != 0 && vp.overlay->GetCompanyMask().Any()) {
|
||||
if (vp.overlay != nullptr && vp.overlay->GetCargoMask().Any() && vp.overlay->GetCompanyMask().Any()) {
|
||||
/* translate to window coordinates */
|
||||
dp.left = x;
|
||||
dp.top = y;
|
||||
|
@ -2499,7 +2499,7 @@ void RebuildViewportOverlay(Window *w)
|
|||
{
|
||||
if (w->viewport->overlay != nullptr &&
|
||||
w->viewport->overlay->GetCompanyMask().Any() &&
|
||||
w->viewport->overlay->GetCargoMask() != 0) {
|
||||
w->viewport->overlay->GetCargoMask().Any()) {
|
||||
w->viewport->overlay->SetDirty();
|
||||
w->SetDirty();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue