Changeset - r23403:d1046b8440da
[Not reviewed]
master
0 8 0
Niels Martin Hansen - 6 years ago 2018-11-07 18:06:39
nielsm@indvikleren.dk
Add: Option for population-linear town cargo generation

Introduce a new default algorithm for town cargo generation (passengers and mail), and a game setting to choose between the new and original algorithm.

The original town cargo generation algorithm has the property of the generated amount relating to the square of each building's population, meaning large towns easily produce more cargo than can realistically be transported. The problem is excessive cargo is amplified if playing with cargodist.

The new algorithm introduced instead has a linear relation to the population. The result is that smaller towns will produce slightly more cargo, while the largest towns will produce about a fourth of what they would with the original algorithm.

Existing savegames will use the original algorithm, while new games will default to the new algorithm.
8 files changed with 83 insertions and 14 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -1583,6 +1583,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEX
 
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
src/saveload/afterload.cpp
Show inline comments
 
@@ -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;
src/saveload/saveload.h
Show inline comments
 
@@ -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
 
};
src/settings_gui.cpp
Show inline comments
 
@@ -1733,6 +1733,7 @@ static SettingsContainer &GetSettingsTre
 
				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));
src/settings_type.h
Show inline comments
 
@@ -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
src/table/settings.ini
Show inline comments
 
@@ -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]
src/town_cmd.cpp
Show inline comments
 
@@ -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;
 

	
 
			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());
 
		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 (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;
 

	
 
			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;
 

	
 
			default:
 
				NOT_REACHED();
 
		}
 
	}
 

	
src/town_type.h
Show inline comments
 
@@ -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. */
0 comments (0 inline, 0 general)