diff --git a/dataobj/settings.cc b/dataobj/settings.cc index 899f4b85c94..b8fcd2d7e5f 100644 --- a/dataobj/settings.cc +++ b/dataobj/settings.cc @@ -451,6 +451,11 @@ settings_t::settings_t() : max_small_city_size = 1000; max_city_size = 5000; + // 0 values for these mean that the above absolute threasholds are used instead. + // Set values in simuconf.tab to activate this feature. + capital_threshold_percentage = 0; + city_threshold_percentage = 0; + power_revenue_factor_percentage=100; allow_making_public = true; @@ -1471,6 +1476,11 @@ void settings_t::rdwr(loadsave_t *file) } file->rdwr_long(capital_threshold_size); file->rdwr_long(city_threshold_size); + if (file->get_extended_version() >= 15 || (file->get_extended_version() >= 14 && file->get_extended_revision() >= 15)) + { + file->rdwr_byte(capital_threshold_percentage); + file->rdwr_byte(city_threshold_percentage); + } } if( file->get_version()>=110001 ) { @@ -2569,6 +2579,9 @@ void settings_t::parse_simuconf(tabfile_t& simuconf, sint16& disp_width, sint16& capital_threshold_size = contents.get_int("capital_threshold_size", capital_threshold_size); max_small_city_size = contents.get_int("max_small_city_size", max_small_city_size); max_city_size = contents.get_int("max_city_size", max_city_size); + capital_threshold_percentage = contents.get_int("capial_threshold_percentage", capital_threshold_percentage); + city_threshold_percentage = contents.get_int("city_threshold_percentage", city_threshold_percentage); + spacing_shift_mode = contents.get_int("spacing_shift_mode", spacing_shift_mode); spacing_shift_divisor = contents.get_int("spacing_shift_divisor", spacing_shift_divisor); diff --git a/dataobj/settings.h b/dataobj/settings.h index c75e87077e0..52d45661bbb 100644 --- a/dataobj/settings.h +++ b/dataobj/settings.h @@ -619,6 +619,9 @@ class settings_t uint32 max_small_city_size; uint32 max_city_size; + uint8 capital_threshold_percentage; + uint8 city_threshold_percentage; + // The factor percentage of power revenue // default: 100 // @author: Phystam @@ -1044,6 +1047,11 @@ class settings_t uint32 get_max_city_size() const { return max_city_size; } void set_max_city_size(uint32 value) { max_city_size = value; } + uint8 get_capital_threshold_percentage() const { return capital_threshold_percentage; } + void set_capital_threshold_percentage(uint8 value) { capital_threshold_percentage = value; } + uint8 get_city_threshold_percentage() const { return city_threshold_percentage; } + void set_city_threshold_percentage(uint8 value) { city_threshold_percentage = value; } + uint16 get_default_increase_maintenance_after_years(waytype_t wtype) const { return default_increase_maintenance_after_years[wtype]; } void set_default_increase_maintenance_after_years(waytype_t wtype, uint16 value) { default_increase_maintenance_after_years[wtype] = value; } uint32 get_server_frames_ahead() const { return server_frames_ahead; } diff --git a/gui/settings_stats.cc b/gui/settings_stats.cc index 2b4957f34a6..7108d691cd6 100644 --- a/gui/settings_stats.cc +++ b/gui/settings_stats.cc @@ -217,6 +217,8 @@ void settings_extended_general_stats_t::init( settings_t *sets ) INIT_NUM( "city_threshold_size", sets->get_city_threshold_size(), 1000, 100000, gui_numberinput_t::AUTOLINEAR, false ); INIT_NUM( "capital_threshold_size", sets->get_capital_threshold_size(), 10000, 1000000, gui_numberinput_t::AUTOLINEAR, false ); + INIT_NUM( "city_threshold_percentage", sets->get_city_threshold_percentage(), 0, 100, gui_numberinput_t::PLAIN, false); + INIT_NUM( "capital_threshold_percentage", sets->get_capital_threshold_percentage(), 0, 100, gui_numberinput_t::PLAIN, false); INIT_NUM( "max_small_city_size", sets->get_max_small_city_size(), 1000, 100000, gui_numberinput_t::AUTOLINEAR, false ); INIT_NUM( "max_city_size", sets->get_max_city_size(), 10000, 1000000, gui_numberinput_t::AUTOLINEAR, false ); INIT_NUM( "congestion_density_factor", sets->get_congestion_density_factor(), 0, 1024, gui_numberinput_t::AUTOLINEAR, false ); @@ -320,6 +322,8 @@ void settings_extended_general_stats_t::read(settings_t *sets) READ_NUM( sets->set_city_threshold_size ); READ_NUM( sets->set_capital_threshold_size ); + READ_NUM( sets->set_city_threshold_percentage ); + READ_NUM(sets->set_capital_threshold_percentage); READ_NUM( sets->set_max_small_city_size ); READ_NUM( sets->set_max_city_size ); READ_NUM( sets->set_congestion_density_factor ); diff --git a/simcity.cc b/simcity.cc index 7fe181a5e83..5af52d401e6 100644 --- a/simcity.cc +++ b/simcity.cc @@ -2912,21 +2912,75 @@ void stadt_t::calc_growth() settings_t const& s = welt->get_settings(); // smaller towns should grow slower to have villages for a longer time - sint32 const weight_factor = - get_city_population() < s.get_city_threshold_size() ? welt->get_settings().get_growthfactor_small() : - get_city_population() < s.get_capital_threshold_size() ? welt->get_settings().get_growthfactor_medium() : - welt->get_settings().get_growthfactor_large(); + // New for January 2020: what counts as a "smaller town" can be proportional to the size of towns if threshold percentages are set. + sint32 weight_factor; + + if (s.get_capital_threshold_percentage() == 0 && s.get_city_threshold_percentage() == 0) + { + // Percentages specified as zero - use the old algorithm + weight_factor = + get_city_population() < s.get_city_threshold_size() ? welt->get_settings().get_growthfactor_small() : + get_city_population() < s.get_capital_threshold_size() ? welt->get_settings().get_growthfactor_medium() : + s.get_growthfactor_large(); + } + else + { + // It is possible that only one threshold percentage is set. In this case, assume the other. + uint8 capital_threshold_percentage = s.get_capital_threshold_percentage() ? s.get_capital_threshold_percentage() : s.get_city_threshold_percentage() / 4; + capital_threshold_percentage = capital_threshold_percentage ? capital_threshold_percentage : 1; + uint8 city_threshold_percentage = s.get_city_threshold_percentage() ? s.get_city_threshold_percentage() : capital_threshold_percentage * 4; + + // Now that we have the percentages, calculate how large that this city is compared to others in the game. + uint32 number_of_larger_cities = 0; + uint32 number_of_smaller_cities = 0; + FOR(const weighted_vector_tpl, const& city, welt->get_cities()) + { + if (city == this) + { + continue; + } + if (city->get_city_population() > get_city_population()) + { + number_of_larger_cities++; + } + else + { + number_of_smaller_cities++; + } + } + + const uint32 total_cities = number_of_larger_cities + number_of_smaller_cities + 1; + const uint32 rank = number_of_larger_cities + 1; + const uint32 percentage = (rank * 100) / total_cities; + + if (rank == 1 || percentage <= s.get_capital_threshold_percentage()) + { + weight_factor = s.get_growthfactor_large(); + } + else if (percentage <= s.get_city_threshold_percentage()) + { + weight_factor = s.get_growthfactor_medium(); + } + else + { + weight_factor = s.get_growthfactor_small(); + } + } // now compute the growth for this step sint32 growth_factor = weight_factor > 0 ? total_supply_percentage / weight_factor : 0; + // Formerly, congestion directly affected growth. However, this is not realistic: it should only + // affect growth indirectly by reducing the proportion of successful journeys. In any event, + // the percentage now has a new meaning: the percentage by which car journeys are slowed down. +#if 0 // Congestion adversely impacts on growth. At 100% congestion, there will be no growth. if(city_history_month[0][HIST_CONGESTION] > 0) { const uint32 congestion_factor = city_history_month[0][HIST_CONGESTION]; growth_factor -= (congestion_factor * growth_factor) / 100; } - +#endif // Scale up growth to have a larger fractional component. This allows small growth units to accumulate in the case of long months. sint64 new_unsupplied_city_growth = (sint64)growth_factor * (CITYGROWTH_PER_CITICEN / 16ll); diff --git a/simutrans/config/simuconf.tab b/simutrans/config/simuconf.tab index fed80d4ecf5..59f40809a30 100644 --- a/simutrans/config/simuconf.tab +++ b/simutrans/config/simuconf.tab @@ -164,6 +164,34 @@ growthfactor_villages = 400 growthfactor_cities = 200 growthfactor_capitals = 100 +# The rate at which towns grow depends on their size. There are three different size categories: +# "Villages", "Cities" and "Capitals". The following settings define the thresholds (in numbers +# of population) above which towns become "Cities" and "Capitals". Anything smaller than +# city_threshold_size is a "Village". These settings are overriden if any value in +# city_threshold_percentage or capital_threshold_percentage be set. + +city_threshold_size = 2500 +capital_threshold_size = 25000 + +# These values determine which rates of town growth apply depending, not on the absolute size +# of the city, but rather its size relative to other cities in the game. If capital_threshold_percentage +# is 5, for example, any city in the top 5% of cities by population count will be a capital. +# These settings override the absolute values in city_threshold_size and capital_threshold_size +# unless their values are 0, which is the default. It is recommended to use these rather than absolute +# values, especially in longer games, where all towns may grow to the size of "capitals" eventually. + +city_threshold_percentage = 20 +capital_threshold_percentage = 2 + +# These values are used in the city generation algorithm to determine the maximum size of cities. +# max_city_size is the maximum size, in citizens, of any city at the point of generation. +# max_small_city_size is the size, in citizens, of any city other than a "big city" at the point of generation. +# +# TIP: Set a lower number for these values the earlier that the game is started. + +max_city_size = 20000 +max_small_city_size = 3000 + # Enable this to use the old algorithm for city growth from Standard. # NOTE: The renovation_percentage in cityrules.tab should be increased if this be done. quick_city_growth = 0 diff --git a/simversion.h b/simversion.h index 9d71832d39c..f7991cb6af0 100644 --- a/simversion.h +++ b/simversion.h @@ -28,8 +28,8 @@ extern "C" FILE * __cdecl __iob_func(void) { return _iob; } #define SIM_SERVER_MINOR 4 #define EX_VERSION_MAJOR 14 -#define EX_VERSION_MINOR 5 -#define EX_SAVE_MINOR 14 +#define EX_VERSION_MINOR 6 +#define EX_SAVE_MINOR 15 // Do not forget to increment the save game versions in settings_stats.cc when changing this