diff --git a/src/economy.cpp b/src/economy.cpp index 89e52081d9..f982e71f13 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2453,16 +2453,16 @@ CommandCost CmdDeclineBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, return CommandCost(); } -uint ScaleQuantity(uint amount, int scale_factor) +uint ScaleQuantity(uint amount, int scale_factor, bool allow_trunc) { scale_factor += 200; // ensure factor is positive assert(scale_factor >= 0); int cf = (scale_factor / 10) - 20; int fine = scale_factor % 10; - return ScaleQuantity(amount, cf, fine); + return ScaleQuantity(amount, cf, fine, allow_trunc); } -uint ScaleQuantity(uint amount, int cf, int fine) +uint ScaleQuantity(uint amount, int cf, int fine, bool allow_trunc) { if (fine != 0) { // 2^0.1 << 16 to 2^0.9 << 16 @@ -2474,9 +2474,12 @@ uint ScaleQuantity(uint amount, int cf, int fine) // apply scale factor if (cf < 0) { // approx (amount / 2^cf) - // adjust with a constant offset of {(2 ^ cf) - 1} (i.e. add cf * 1-bits) before dividing to ensure that it doesn't become zero + // when allow_trunc is false: adjust with a constant offset of {(2 ^ cf) - 1} (i.e. add cf * 1-bits) before dividing to ensure that it doesn't become zero // this skews the curve a little so that isn't entirely exponential, but will still decrease - amount = (amount + ((1 << -cf) - 1)) >> -cf; + // when allow_trunc is true: adjust with a randomised offset + uint offset = ((1 << -cf) - 1); + if (allow_trunc) offset &= Random(); + amount = (amount + offset) >> -cf; } else if (cf > 0) { // approx (amount * 2^cf) amount = amount << cf; diff --git a/src/economy_func.h b/src/economy_func.h index 9fd99dd635..4ab9dacbcd 100644 --- a/src/economy_func.h +++ b/src/economy_func.h @@ -49,7 +49,7 @@ static inline bool EconomyIsInRecession() return _economy.fluct <= 0; } -uint ScaleQuantity(uint amount, int scale_factor); -uint ScaleQuantity(uint amount, int cf, int fine); +uint ScaleQuantity(uint amount, int scale_factor, bool allow_trunc = false); +uint ScaleQuantity(uint amount, int cf, int fine, bool allow_trunc = false); #endif /* ECONOMY_FUNC_H */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 3f51ccd5ef..79356008df 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -652,7 +652,9 @@ static void TownGenerateCargo (Town *t, CargoID ct, uint amount, StationFinder & amount = (amount + 1) >> 1; } - amount = ScaleQuantity(amount, _settings_game.economy.town_cargo_scale_factor); + amount = ScaleQuantity(amount, _settings_game.economy.town_cargo_scale_factor, true); + + if (amount == 0) return; // calculate for town stats