summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang/english.txt4
-rw-r--r--src/saveload/afterload.cpp5
-rw-r--r--src/saveload/saveload.h1
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.ini15
-rw-r--r--src/town_cmd.cpp56
-rw-r--r--src/town_type.h8
8 files changed, 80 insertions, 11 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index c131fdabd..78b49280e 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1583,6 +1583,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Enabling this s
STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Forbidden
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Allowed
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Allowed, custom town layout
+STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Town cargo generation: {STRING2}
+STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :How much cargo is produced by houses in towns, relative to the overall population of the town.{}Quadratic growth: A town twice the size generates four times as many passengers.{}Linear growth: A town twice the size generates twice the amount of passengers.
+STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadratic (original)
+STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :In game placement of trees: {STRING2}
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Control random appearance of trees during the game. This might affect industries which rely on tree growth, for example lumber mills
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 0b570966d..55552413a 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -3080,6 +3080,11 @@ bool AfterLoadGame()
}
}
+ if (IsSavegameVersionBefore(SLV_TOWN_CARGOGEN)) {
+ /* Ensure the original cargo generation mode is used */
+ _settings_game.economy.town_cargogen_mode = TCGM_ORIGINAL;
+ }
+
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(SLV_127)) {
Station *st;
diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h
index c5e7489c1..36c9687ea 100644
--- a/src/saveload/saveload.h
+++ b/src/saveload/saveload.h
@@ -291,6 +291,7 @@ enum SaveLoadVersion : uint16 {
SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries.
SLV_SHIPS_STOP_IN_LOCKS, ///< 206 PR#7150 Ship/lock movement changes.
SLV_FIX_CARGO_MONITOR, ///< 207 PR#7175 v1.9 Cargo monitor data packing fix to support 64 cargotypes.
+ SLV_TOWN_CARGOGEN, ///< 208 PR#6965 New algorithms for town building cargo generation.
SL_MAX_VERSION, ///< Highest possible saveload version
};
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index c3a38b408..4d851333c 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1733,6 +1733,7 @@ static SettingsContainer &GetSettingsTree()
towns->Add(new SettingEntry("economy.allow_town_roads"));
towns->Add(new SettingEntry("economy.allow_town_level_crossings"));
towns->Add(new SettingEntry("economy.found_town"));
+ towns->Add(new SettingEntry("economy.town_cargogen_mode"));
}
SettingsPage *industries = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES));
diff --git a/src/settings_type.h b/src/settings_type.h
index 8f03b1dc1..6fba8ed2c 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -493,6 +493,7 @@ struct EconomySettings {
uint8 larger_towns; ///< the number of cities to build. These start off larger and grow twice as fast
uint8 initial_city_size; ///< multiplier for the initial size of the cities compared to towns
TownLayoutByte town_layout; ///< select town layout, @see TownLayout
+ TownCargoGenMode town_cargogen_mode; ///< algorithm for generating cargo from houses, @see TownCargoGenMode
bool allow_town_roads; ///< towns are allowed to build roads (always allowed when generating world / in SE)
TownFoundingByte found_town; ///< town founding, @see TownFounding
bool station_noise_level; ///< build new airports when the town noise level is still within accepted limits
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 5bb2c73aa..c2faa43ca 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -618,6 +618,21 @@ def = true
str = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS
strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT
+[SDT_VAR]
+base = GameSettings
+var = economy.town_cargogen_mode
+type = SLE_UINT8
+from = SLV_TOWN_CARGOGEN
+guiflags = SGF_MULTISTRING
+def = TCGM_BITCOUNT
+min = TCGM_BEGIN
+max = TCGM_END - 1
+interval = 1
+str = STR_CONFIG_SETTING_TOWN_CARGOGENMODE
+strhelp = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT
+strval = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL
+cat = SC_ADVANCED
+
; link graph
[SDT_VAR]
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 32875974c..d7cb45bb9 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -536,20 +536,54 @@ static void TileLoop_Town(TileIndex tile)
t->supplied[cs->Index()].new_act += moved;
}
} else {
- if (GB(r, 0, 8) < hs->population) {
- uint amt = GB(r, 0, 8) / 8 + 1;
+ switch (_settings_game.economy.town_cargogen_mode) {
+ case TCGM_ORIGINAL:
+ /* Original (quadratic) cargo generation algorithm */
+ if (GB(r, 0, 8) < hs->population) {
+ uint amt = GB(r, 0, 8) / 8 + 1;
+
+ if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
+ t->supplied[CT_PASSENGERS].new_max += amt;
+ t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
+ }
- if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
- t->supplied[CT_PASSENGERS].new_max += amt;
- t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
- }
+ if (GB(r, 8, 8) < hs->mail_generation) {
+ uint amt = GB(r, 8, 8) / 8 + 1;
+
+ if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
+ t->supplied[CT_MAIL].new_max += amt;
+ t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
+ }
+ break;
- if (GB(r, 8, 8) < hs->mail_generation) {
- uint amt = GB(r, 8, 8) / 8 + 1;
+ case TCGM_BITCOUNT:
+ /* Binomial distribution per tick, by a series of coin flips */
+ /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
+ * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
+ if (GB(_tick_counter, 8, 2) == GB(tile, 0, 2)) {
+ /* Make a bitmask with up to 32 bits set, one for each potential pax */
+ int genmax = (hs->population + 7) / 8;
+ uint32 genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
+ /* Mask random value by potential pax and count number of actual pax */
+ uint amt = CountBits(r & genmask);
+ /* Adjust and apply */
+ if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
+ t->supplied[CT_PASSENGERS].new_max += amt;
+ t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
+
+ /* Do the same for mail, with a fresh random */
+ r = Random();
+ genmax = (hs->mail_generation + 7) / 8;
+ genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
+ amt = CountBits(r & genmask);
+ if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
+ t->supplied[CT_MAIL].new_max += amt;
+ t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
+ }
+ break;
- if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
- t->supplied[CT_MAIL].new_max += amt;
- t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
+ default:
+ NOT_REACHED();
}
}
diff --git a/src/town_type.h b/src/town_type.h
index 0c93c8df8..608530106 100644
--- a/src/town_type.h
+++ b/src/town_type.h
@@ -105,6 +105,14 @@ enum TownFounding {
/** It needs to be 8bits, because we save and load it as such */
typedef SimpleTinyEnumT<TownFounding, byte> TownFoundingByte;
+/** Town cargo generation modes */
+enum TownCargoGenMode : byte {
+ TCGM_BEGIN = 0,
+ TCGM_ORIGINAL = 0, ///< Original algorithm (quadratic cargo by population)
+ TCGM_BITCOUNT, ///< Bit-counted algorithm (normal distribution from individual house population)
+ TCGM_END,
+};
+
static const uint MAX_LENGTH_TOWN_NAME_CHARS = 32; ///< The maximum length of a town name in characters including '\0'
/** Store the maximum and actually transported cargo amount for the current and the last month. */