@ -8724,65 +8724,116 @@ GRFFile::~GRFFile()
}
}
/**
* List of what cargo labels are refittable for the given the vehicle - type .
* Only currently active labels are applied .
*/
static const CargoLabel _default_refitmasks_rail [ ] = {
' PASS ' , ' COAL ' , ' MAIL ' , ' LVST ' , ' GOOD ' , ' GRAI ' , ' WHEA ' , ' MAIZ ' , ' WOOD ' ,
' IORE ' , ' STEL ' , ' VALU ' , ' GOLD ' , ' DIAM ' , ' PAPR ' , ' FOOD ' , ' FRUT ' , ' CORE ' ,
' WATR ' , ' SUGR ' , ' TOYS ' , ' BATT ' , ' SWET ' , ' TOFF ' , ' COLA ' , ' CTCD ' , ' BUBL ' ,
' PLST ' , ' FZDR ' ,
0 } ;
static const CargoLabel _default_refitmasks_road [ ] = {
0 } ;
static const CargoLabel _default_refitmasks_ships [ ] = {
' COAL ' , ' MAIL ' , ' LVST ' , ' GOOD ' , ' GRAI ' , ' WHEA ' , ' MAIZ ' , ' WOOD ' , ' IORE ' ,
' STEL ' , ' VALU ' , ' GOLD ' , ' DIAM ' , ' PAPR ' , ' FOOD ' , ' FRUT ' , ' CORE ' , ' WATR ' ,
' RUBR ' , ' SUGR ' , ' TOYS ' , ' BATT ' , ' SWET ' , ' TOFF ' , ' COLA ' , ' CTCD ' , ' BUBL ' ,
' PLST ' , ' FZDR ' ,
0 } ;
static const CargoLabel _default_refitmasks_aircraft [ ] = {
' PASS ' , ' MAIL ' , ' GOOD ' , ' VALU ' , ' GOLD ' , ' DIAM ' , ' FOOD ' , ' FRUT ' , ' SUGR ' ,
' TOYS ' , ' BATT ' , ' SWET ' , ' TOFF ' , ' COLA ' , ' CTCD ' , ' BUBL ' , ' PLST ' , ' FZDR ' ,
0 } ;
static const CargoLabel * const _default_refitmasks [ ] = {
_default_refitmasks_rail ,
_default_refitmasks_road ,
_default_refitmasks_ships ,
_default_refitmasks_aircraft ,
} ;
/**
/**
* Precalculate refit masks from cargo classes for all vehicles .
* Precalculate refit masks from cargo classes for all vehicles .
*/
*/
static void CalculateRefitMasks ( )
static void CalculateRefitMasks ( )
{
{
CargoTypes original_known_cargoes = 0 ;
for ( int ct = 0 ; ct ! = NUM_ORIGINAL_CARGO ; + + ct ) {
CargoID cid = GetDefaultCargoID ( _settings_game . game_creation . landscape , static_cast < CargoType > ( ct ) ) ;
if ( cid ! = CT_INVALID ) SetBit ( original_known_cargoes , cid ) ;
}
for ( Engine * e : Engine : : Iterate ( ) ) {
for ( Engine * e : Engine : : Iterate ( ) ) {
EngineID engine = e - > index ;
EngineID engine = e - > index ;
EngineInfo * ei = & e - > info ;
EngineInfo * ei = & e - > info ;
bool only_defaultcargo ; ///< Set if the vehicle shall carry only the default cargo
bool only_defaultcargo ; ///< Set if the vehicle shall carry only the default cargo
/* If the NewGRF did not set any cargo properties, we apply default cargo translation. */
/* If the NewGRF did not set any cargo properties, we apply default values. */
if ( _gted [ engine ] . defaultcargo_grf = = nullptr ) {
if ( _gted [ engine ] . defaultcargo_grf = = nullptr ) {
/* If the vehicle has any capacity, apply the default refit masks */
if ( e - > type ! = VEH_TRAIN | | e - > u . rail . capacity ! = 0 ) {
static constexpr byte T = 1 < < LT_TEMPERATE ;
static constexpr byte A = 1 < < LT_ARCTIC ;
static constexpr byte S = 1 < < LT_TROPIC ;
static constexpr byte Y = 1 < < LT_TOYLAND ;
static const struct DefaultRefitMasks {
byte climate ;
CargoType cargo_type ;
CargoTypes cargo_allowed ;
CargoTypes cargo_disallowed ;
} _default_refit_masks [ ] = {
{ T | A | S | Y , CT_PASSENGERS , CC_PASSENGERS , 0 } ,
{ T | A | S , CT_MAIL , CC_MAIL , 0 } ,
{ T | A | S , CT_VALUABLES , CC_ARMOURED , CC_LIQUID } ,
{ Y , CT_MAIL , CC_MAIL | CC_ARMOURED , CC_LIQUID } ,
{ T | A , CT_COAL , CC_BULK , 0 } ,
{ S , CT_COPPER_ORE , CC_BULK , 0 } ,
{ Y , CT_SUGAR , CC_BULK , 0 } ,
{ T | A | S , CT_OIL , CC_LIQUID , 0 } ,
{ Y , CT_COLA , CC_LIQUID , 0 } ,
{ T , CT_GOODS , CC_PIECE_GOODS | CC_EXPRESS , CC_LIQUID | CC_PASSENGERS } ,
{ A | S , CT_GOODS , CC_PIECE_GOODS | CC_EXPRESS , CC_LIQUID | CC_PASSENGERS | CC_REFRIGERATED } ,
{ A | S , CT_FOOD , CC_REFRIGERATED , 0 } ,
{ Y , CT_CANDY , CC_PIECE_GOODS | CC_EXPRESS , CC_LIQUID | CC_PASSENGERS } ,
} ;
if ( e - > type = = VEH_AIRCRAFT ) {
/* Aircraft default to "light" cargoes */
_gted [ engine ] . cargo_allowed = CC_PASSENGERS | CC_MAIL | CC_ARMOURED | CC_EXPRESS ;
_gted [ engine ] . cargo_disallowed = CC_LIQUID ;
} else if ( e - > type = = VEH_SHIP ) {
switch ( ei - > cargo_type ) {
case CT_PASSENGERS :
/* Ferries */
_gted [ engine ] . cargo_allowed = CC_PASSENGERS ;
_gted [ engine ] . cargo_disallowed = 0 ;
break ;
case CT_OIL :
/* Tankers */
_gted [ engine ] . cargo_allowed = CC_LIQUID ;
_gted [ engine ] . cargo_disallowed = 0 ;
break ;
default :
/* Cargo ships */
if ( _settings_game . game_creation . landscape = = LT_TOYLAND ) {
/* No tanker in toyland :( */
_gted [ engine ] . cargo_allowed = CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS | CC_LIQUID ;
_gted [ engine ] . cargo_disallowed = CC_PASSENGERS ;
} else {
_gted [ engine ] . cargo_allowed = CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS ;
_gted [ engine ] . cargo_disallowed = CC_LIQUID | CC_PASSENGERS ;
}
break ;
}
e - > u . ship . old_refittable = true ;
} else if ( e - > type = = VEH_TRAIN & & e - > u . rail . railveh_type ! = RAILVEH_WAGON ) {
/* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
* Trains loading multiple cargoes may start stations accepting unwanted cargoes . */
_gted [ engine ] . cargo_allowed = CC_PASSENGERS | CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS | CC_LIQUID ;
_gted [ engine ] . cargo_disallowed = 0 ;
} else {
/* Train wagons and road vehicles are classified by their default cargo type */
for ( const auto & drm : _default_refit_masks ) {
if ( ! HasBit ( drm . climate , _settings_game . game_creation . landscape ) ) continue ;
if ( drm . cargo_type ! = ei - > cargo_type ) continue ;
_gted [ engine ] . cargo_allowed = drm . cargo_allowed ;
_gted [ engine ] . cargo_disallowed = drm . cargo_disallowed ;
break ;
}
/* All original cargoes have specialised vehicles, so exclude them */
_gted [ engine ] . ctt_exclude_mask = original_known_cargoes ;
}
}
_gted [ engine ] . UpdateRefittability ( _gted [ engine ] . cargo_allowed ! = 0 ) ;
/* Translate cargo_type using the original climate-specific cargo table. */
/* Translate cargo_type using the original climate-specific cargo table. */
ei - > cargo_type = GetDefaultCargoID ( _settings_game . game_creation . landscape , static_cast < CargoType > ( ei - > cargo_type ) ) ;
ei - > cargo_type = GetDefaultCargoID ( _settings_game . game_creation . landscape , static_cast < CargoType > ( ei - > cargo_type ) ) ;
if ( ei - > cargo_type ! = CT_INVALID ) ClrBit ( _gted [ engine ] . ctt_exclude_mask , ei - > cargo_type ) ;
}
}
/* Did the newgrf specify any refitting? If not, use defaults. */
/* Compute refittability */
if ( _gted [ engine ] . refittability ! = GRFTempEngineData : : UNSET ) {
{
CargoTypes mask = 0 ;
CargoTypes mask = 0 ;
CargoTypes not_mask = 0 ;
CargoTypes not_mask = 0 ;
CargoTypes xor_mask = ei - > refit_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.
/* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
* Note : After applying the translations , the vehicle may end up carrying no defined cargo . It becomes unavailable in that case . */
* Note : After applying the translations , the vehicle may end up carrying no defined cargo . It becomes unavailable in that case . */
only_defaultcargo = _gted [ engine ] . refittability = = GRFTempEngineData : : EMPTY ;
only_defaultcargo = _gted [ engine ] . refittability ! = GRFTempEngineData : : NON EMPTY;
if ( _gted [ engine ] . cargo_allowed ! = 0 ) {
if ( _gted [ engine ] . cargo_allowed ! = 0 ) {
/* Build up the list of cargo types from the set cargo classes. */
/* Build up the list of cargo types from the set cargo classes. */
@ -8797,26 +8848,6 @@ static void CalculateRefitMasks()
/* Apply explicit refit includes/excludes. */
/* Apply explicit refit includes/excludes. */
ei - > refit_mask | = _gted [ engine ] . ctt_include_mask ;
ei - > refit_mask | = _gted [ engine ] . ctt_include_mask ;
ei - > refit_mask & = ~ _gted [ engine ] . ctt_exclude_mask ;
ei - > refit_mask & = ~ _gted [ engine ] . ctt_exclude_mask ;
} else {
CargoTypes xor_mask = 0 ;
/* Don't apply default refit mask to wagons nor engines with no capacity */
if ( e - > type ! = VEH_TRAIN | | ( e - > u . rail . capacity ! = 0 & & e - > u . rail . railveh_type ! = RAILVEH_WAGON ) ) {
const CargoLabel * cl = _default_refitmasks [ e - > type ] ;
for ( uint i = 0 ; ; i + + ) {
if ( cl [ i ] = = 0 ) break ;
CargoID cargo = GetCargoIDByLabel ( cl [ i ] ) ;
if ( cargo = = CT_INVALID ) continue ;
SetBit ( xor_mask , cargo ) ;
}
}
ei - > refit_mask = xor_mask & _cargo_mask ;
/* If the mask is zero, the vehicle shall only carry the default cargo */
only_defaultcargo = ( ei - > refit_mask = = 0 ) ;
}
}
/* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
/* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */