summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/newgrf.cpp147
1 files changed, 89 insertions, 58 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index dd03e2327..29b6a4903 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -8725,64 +8725,115 @@ 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.
*/
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()) {
EngineID engine = e->index;
EngineInfo *ei = &e->info;
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 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. */
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. */
- if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
+ /* Compute refittability */
+ {
CargoTypes mask = 0;
CargoTypes not_mask = 0;
CargoTypes xor_mask = ei->refit_mask;
/* 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. */
- only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
+ only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
if (_gted[engine].cargo_allowed != 0) {
/* Build up the list of cargo types from the set cargo classes. */
@@ -8797,26 +8848,6 @@ static void CalculateRefitMasks()
/* Apply explicit refit includes/excludes. */
ei->refit_mask |= _gted[engine].ctt_include_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) */