diff --git a/src/cargotype.h b/src/cargotype.h index 06e2661461..4c83c3ceba 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -65,6 +65,8 @@ enum CargoClass { static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo +static const uint TOWN_PRODUCTION_DIVISOR = 256; + /** Specification of a cargo type. */ struct CargoSpec { CargoLabel label; ///< Unique label of the cargo type. @@ -80,6 +82,7 @@ struct CargoSpec { bool is_freight; ///< Cargo type is considered to be freight (affects train freight multiplier). TownAcceptanceEffect town_acceptance_effect; ///< The effect that delivering this cargo type has on towns. Also affects destination of subsidies. TownProductionEffect town_production_effect{INVALID_TPE}; ///< The effect on town cargo production. + uint16_t town_production_multiplier{TOWN_PRODUCTION_DIVISOR}; ///< Town production multipler, if commanded by TownProductionEffect. uint8_t callback_mask; ///< Bitmask of cargo callbacks that have to be called StringID name; ///< Name of this type of cargo. diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 4781e460a6..22455baf61 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -3091,6 +3091,24 @@ static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteRea cs->multiplier = std::max(1u, buf->ReadWord()); break; + case 0x1E: { // Town production substitute type + uint8_t substitute_type = buf->ReadByte(); + + switch (substitute_type) { + case 0x00: cs->town_production_effect = TPE_PASSENGERS; break; + case 0x02: cs->town_production_effect = TPE_MAIL; break; + default: + GrfMsg(1, "CargoChangeInfo: Unknown town production substitute value {}, setting to none.", substitute_type); + [[fallthrough]]; + case 0xFF: cs->town_production_effect = TPE_NONE; break; + } + break; + } + + case 0x1F: // Town production multiplier + cs->town_production_multiplier = std::max(1U, buf->ReadWord()); + break; + default: ret = CIR_UNKNOWN; break; diff --git a/src/table/cargo_const.h b/src/table/cargo_const.h index b7fc6213fd..f182e039df 100644 --- a/src/table/cargo_const.h +++ b/src/table/cargo_const.h @@ -44,7 +44,7 @@ * @param classes Classes of this cargo type. @see CargoClass */ #define MK(bt, label, colour, weight, mult, ip, td1, td2, freight, tae, str_plural, str_singular, str_volume, classes) \ - {label, bt, colour, colour, weight, mult, classes, ip, {td1, td2}, freight, tae, INVALID_TPE, 0, \ + {label, bt, colour, colour, weight, mult, classes, ip, {td1, td2}, freight, tae, INVALID_TPE, TOWN_PRODUCTION_DIVISOR, 0, \ MK_STR_CARGO_PLURAL(str_plural), MK_STR_CARGO_SINGULAR(str_singular), str_volume, MK_STR_QUANTITY(str_plural), MK_STR_ABBREV(str_plural), \ MK_SPRITE(str_plural), nullptr, nullptr, 0} diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 212c979eba..a2c3df76fb 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -558,7 +558,7 @@ static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t uint32_t r = Random(); if (GB(r, 0, 8) < rate) { CargoID cid = cs->Index(); - uint amt = GB(r, 0, 8) / 8 + 1; + uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1; TownGenerateCargo(t, cid, amt, stations, true); } @@ -583,7 +583,7 @@ static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_ uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1); /* Mask random value by potential pax and count number of actual pax. */ - uint amt = CountBits(r & genmask); + uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR; TownGenerateCargo(t, cid, amt, stations, true); }