From 9305bc0e56cfb67d7b7ed5c5767c872fddbc42ef Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 03:20:10 -0500 Subject: [PATCH 1/8] process_temperature: add temperature-only weather_generator function In process_temperature_rot only the temperature value is used, so we don't need to generate the rest of the weather data for --- src/item.cpp | 4 ++-- src/weather_gen.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/weather_gen.h | 2 ++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 94667f04d0c8a..5511516baf148 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7475,8 +7475,8 @@ void item::process_temperature_rot( float insulation, const tripoint &pos, //Use weather if above ground, use map temp if below double env_temperature = 0; if( pos.z >= 0 ) { - w_point weather = wgen.get_weather( pos, time, seed ); - env_temperature = weather.temperature + enviroment_mod + local_mod; + double weather_temperature = wgen.get_weather_temperature( pos, time, seed ); + env_temperature = weather_temperature + enviroment_mod + local_mod; } else { env_temperature = AVERAGE_ANNUAL_TEMPERATURE + enviroment_mod + local_mod; } diff --git a/src/weather_gen.cpp b/src/weather_gen.cpp index e07c7d168c41f..30227c23b90cd 100644 --- a/src/weather_gen.cpp +++ b/src/weather_gen.cpp @@ -23,6 +23,42 @@ constexpr double tau = 2 * PI; weather_generator::weather_generator() = default; int weather_generator::current_winddir = 1000; +double weather_generator::get_weather_temperature( const tripoint &location, const time_point &t, + unsigned seed ) const { + const double x( location.x / 2000.0 ); + const double y( location.y / 2000.0 ); + const double z( to_turn( t + calendar::season_length() ) / 2000.0 ); + + const unsigned modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT; + const double dayFraction = time_past_midnight( t ) / 1_days; + + double T(raw_noise_4d( x, y, z, modSEED ) * 4.0 ); + + const double now( ( time_past_new_year( t ) + calendar::season_length() / 2 ) / + calendar::year_length() ); // [0,1) + const double ctn( cos( tau * now ) ); // [-1, 1] + + const season_type season = season_of_year( t ); + const int seasonal_temp_mod[4] = { spring_temp_manual_mod, summer_temp_manual_mod, autumn_temp_manual_mod, winter_temp_manual_mod }; + const double current_t( base_temperature + seasonal_temp_mod[ season ] ); + // Start and end at -1 going up to 1 in summer. + const double seasonal_variation( ctn * -1 ); // [-1, 1] + // Harsh winter nights, hot summers. + const double season_atenuation( ctn / 2 + 1 ); + // Make summers peak faster and winters not perma-frozen. + const double season_dispersion( pow( 2, + ctn + 1 ) - 2.3 ); + + // Day-night temperature variation. + double daily_variation( cos( tau * dayFraction - tau / 8 ) * -1 * season_atenuation / 2 + + season_dispersion * -1 ); + T += current_t; + T += seasonal_variation * 8 * exp( -pow( current_t * 2.7 / 10 - 0.5, 2 ) ); + T += daily_variation * 8 * exp( -pow( current_t / 30, 2 ) ); + T = T * 9 / 5 + 32; + + return T; +} w_point weather_generator::get_weather( const tripoint &location, const time_point &t, unsigned seed ) const { diff --git a/src/weather_gen.h b/src/weather_gen.h index 0b143a3792b1b..adc30359d4426 100644 --- a/src/weather_gen.h +++ b/src/weather_gen.h @@ -63,6 +63,8 @@ class weather_generator int get_water_temperature() const; void test_weather() const; + double get_weather_temperature( const tripoint &, const time_point &, unsigned ) const; + static weather_generator load( JsonObject &jo ); }; From a8bc3aabcc5c27a4b79caaf2863a7b20fc6ab216 Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 03:28:26 -0500 Subject: [PATCH 2/8] process_temperature: most items are not corpses Most items being processed are not corpses, and item::corpse is a nullptr. It's the easiest thing to check so do that before doing a string compare --- src/item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item.cpp b/src/item.cpp index 5511516baf148..c5f2e74fe858e 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5053,7 +5053,7 @@ bool item::is_med_container() const bool item::is_corpse() const { - return typeId() == "corpse" && corpse != nullptr; + return corpse != nullptr && typeId() == "corpse"; } const mtype *item::get_mtype() const From b4f37bdab3fcadb42a4cd2c47a433277433cab42 Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 04:20:37 -0500 Subject: [PATCH 3/8] process_temperature: use maptiles for heat radiation and convection calc Use maptiles to avoid as many map::get_submap_at calls as possible --- src/game.cpp | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 79fd36deb21aa..a677c908fbdab 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1715,6 +1715,15 @@ void game::set_critter_died() critter_died = true; } +static int maptile_field_intensity( maptile &mt, field_type_id fld ) { + auto field_ptr = mt.find_field( fld ); + + return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() ); +} +static bool maptile_trap_eq( maptile &mt, const trap_id &id ) { + return mt.get_trap_t().loadid == id; +} + int get_heat_radiation( const tripoint &location, bool direct ) { // Direct heat from fire sources @@ -1725,10 +1734,14 @@ int get_heat_radiation( const tripoint &location, bool direct ) for( const tripoint &dest : g->m.points_in_radius( location, 6 ) ) { int heat_intensity = 0; - int ffire = g->m.get_field_intensity( dest, fd_fire ); + maptile mt = g->m.maptile_at( dest ); + + //int ffire = g->m.get_field_intensity( dest, fd_fire ); + int ffire = maptile_field_intensity( mt, fd_fire ); if( ffire > 0 ) { heat_intensity = ffire; - } else if( g->m.tr_at( dest ).loadid == tr_lava ) { + } else if( maptile_trap_eq( mt, tr_lava ) ) { + //else if( g->m.tr_at( dest ).loadid == tr_lava ) { heat_intensity = 3; } if( heat_intensity == 0 ) { @@ -1760,29 +1773,29 @@ int get_convection_temperature( const tripoint &location ) { // Heat from hot air (fields) int temp_mod = 0; - const trap &trap_at_pos = g->m.tr_at( location ); + maptile mt = g->m.maptile_at( location ); // directly on fire/lava tiles - int tile_intensity = g->m.get_field_intensity( location, fd_fire ); - if( tile_intensity > 0 || trap_at_pos.loadid == tr_lava ) { + int tile_intensity = maptile_field_intensity( mt, fd_fire ); + if( tile_intensity > 0 || maptile_trap_eq( mt, tr_lava ) ) { temp_mod += 300; } // hot air of a fire/lava - auto tile_intensity_mod = []( const tripoint & loc, field_type_id fld, int case_1, int case_2, + auto tile_intensity_mod = []( maptile & mt, field_type_id fld, int case_1, int case_2, int case_3 ) { - int field_intensity = g->m.get_field_intensity( loc, fld ); + int field_intensity = maptile_field_intensity( mt, fld ); int cases[3] = { case_1, case_2, case_3 }; return ( field_intensity > 0 && field_intensity < 4 ) ? cases[ field_intensity - 1 ] : 0; }; // TODO: Jsonize - temp_mod += tile_intensity_mod( location, fd_hot_air1, 2, 6, 10 ); - temp_mod += tile_intensity_mod( location, fd_hot_air2, 6, 16, 20 ); - temp_mod += tile_intensity_mod( location, fd_hot_air3, 16, 40, 70 ); - temp_mod += tile_intensity_mod( location, fd_hot_air4, 70, 100, 160 ); - temp_mod -= tile_intensity_mod( location, fd_cold_air1, 2, 6, 10 ); - temp_mod -= tile_intensity_mod( location, fd_cold_air2, 6, 16, 20 ); - temp_mod -= tile_intensity_mod( location, fd_cold_air3, 16, 40, 70 ); - temp_mod -= tile_intensity_mod( location, fd_cold_air4, 70, 100, 160 ); + temp_mod += tile_intensity_mod( mt, fd_hot_air1, 2, 6, 10 ); + temp_mod += tile_intensity_mod( mt, fd_hot_air2, 6, 16, 20 ); + temp_mod += tile_intensity_mod( mt, fd_hot_air3, 16, 40, 70 ); + temp_mod += tile_intensity_mod( mt, fd_hot_air4, 70, 100, 160 ); + temp_mod -= tile_intensity_mod( mt, fd_cold_air1, 2, 6, 10 ); + temp_mod -= tile_intensity_mod( mt, fd_cold_air2, 6, 16, 20 ); + temp_mod -= tile_intensity_mod( mt, fd_cold_air3, 16, 40, 70 ); + temp_mod -= tile_intensity_mod( mt, fd_cold_air4, 70, 100, 160 ); return temp_mod; } From dd886f6b3e4bbabc15d064ab3b19e382fe7a5fea Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 06:19:01 -0500 Subject: [PATCH 4/8] process_temperature: add very short-term cache for item::goes_bad proc calling item::goes_bad without a cache is pretty expensive, and it is called repeatedly while processing an item. The value will not change during a call to item::process_temperature_rot, so cache the result then on exit invalidate the cache. --- src/item.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/item.cpp b/src/item.cpp index c5f2e74fe858e..0e00bc3e0acc8 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -161,6 +161,24 @@ item &null_item_reference() return result; } +namespace item_internal { +bool goes_bad_temp_cache = false; +bool goes_bad_temp_cache_set = false; +inline bool goes_bad_cache_fetch() { + return goes_bad_temp_cache; +} +inline void goes_bad_cache_set( bool v ) { + goes_bad_temp_cache = v; + goes_bad_temp_cache_set = true; +} +inline void goes_bad_cache_unset() { + goes_bad_temp_cache_set = goes_bad_temp_cache = false; +} +inline bool goes_bad_cache_is_set() { + return goes_bad_temp_cache_set; +} +} + const int item::INFINITE_CHARGES = INT_MAX; item::item() : bday( calendar::start ) @@ -4001,6 +4019,9 @@ std::set item::get_techniques() const bool item::goes_bad() const { + if( item_internal::goes_bad_cache_is_set() ) { + return item_internal::goes_bad_cache_fetch();; + } if( has_flag( "PROCESSING" ) ) { return false; } @@ -7439,6 +7460,7 @@ void item::process_temperature_rot( float insulation, const tripoint &pos, } time_point time; + item_internal::goes_bad_cache_set( goes_bad() ); if( goes_bad() ) { time = std::min( { last_rot_check, last_temp_check } ); } else { @@ -7517,6 +7539,7 @@ void item::process_temperature_rot( float insulation, const tripoint &pos, if( has_rotten_away() || ( is_corpse() && rot > 10_days ) ) { // No need to track item that will be gone + item_internal::goes_bad_cache_unset(); return; } } @@ -7528,6 +7551,7 @@ void item::process_temperature_rot( float insulation, const tripoint &pos, if( now - time > smallest_interval ) { calc_temp( temp, insulation, now ); calc_rot( now, temp ); + item_internal::goes_bad_cache_unset(); return; } @@ -7535,6 +7559,7 @@ void item::process_temperature_rot( float insulation, const tripoint &pos, if( specific_energy < 0 ) { set_item_temperature( temp_to_kelvin( temp ) ); } + item_internal::goes_bad_cache_unset(); } void item::calc_temp( const int temp, const float insulation, const time_point &time ) From b20497a1c8dc89d0cba7a5138001d84fae575b24 Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 07:41:35 -0500 Subject: [PATCH 5/8] process_temperature: astyle --- src/game.cpp | 8 +++++--- src/item.cpp | 15 ++++++++++----- src/weather_gen.cpp | 5 +++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index a677c908fbdab..b9940216193c9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1715,12 +1715,14 @@ void game::set_critter_died() critter_died = true; } -static int maptile_field_intensity( maptile &mt, field_type_id fld ) { +static int maptile_field_intensity( maptile &mt, field_type_id fld ) +{ auto field_ptr = mt.find_field( fld ); return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() ); } -static bool maptile_trap_eq( maptile &mt, const trap_id &id ) { +static bool maptile_trap_eq( maptile &mt, const trap_id &id ) +{ return mt.get_trap_t().loadid == id; } @@ -1741,7 +1743,7 @@ int get_heat_radiation( const tripoint &location, bool direct ) if( ffire > 0 ) { heat_intensity = ffire; } else if( maptile_trap_eq( mt, tr_lava ) ) { - //else if( g->m.tr_at( dest ).loadid == tr_lava ) { + //else if( g->m.tr_at( dest ).loadid == tr_lava ) { heat_intensity = 3; } if( heat_intensity == 0 ) { diff --git a/src/item.cpp b/src/item.cpp index 0e00bc3e0acc8..dc21169f73438 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -161,20 +161,25 @@ item &null_item_reference() return result; } -namespace item_internal { +namespace item_internal +{ bool goes_bad_temp_cache = false; bool goes_bad_temp_cache_set = false; -inline bool goes_bad_cache_fetch() { +inline bool goes_bad_cache_fetch() +{ return goes_bad_temp_cache; } -inline void goes_bad_cache_set( bool v ) { +inline void goes_bad_cache_set( bool v ) +{ goes_bad_temp_cache = v; goes_bad_temp_cache_set = true; } -inline void goes_bad_cache_unset() { +inline void goes_bad_cache_unset() +{ goes_bad_temp_cache_set = goes_bad_temp_cache = false; } -inline bool goes_bad_cache_is_set() { +inline bool goes_bad_cache_is_set() +{ return goes_bad_temp_cache_set; } } diff --git a/src/weather_gen.cpp b/src/weather_gen.cpp index 30227c23b90cd..bfccd32b84806 100644 --- a/src/weather_gen.cpp +++ b/src/weather_gen.cpp @@ -24,7 +24,8 @@ weather_generator::weather_generator() = default; int weather_generator::current_winddir = 1000; double weather_generator::get_weather_temperature( const tripoint &location, const time_point &t, - unsigned seed ) const { + unsigned seed ) const +{ const double x( location.x / 2000.0 ); const double y( location.y / 2000.0 ); const double z( to_turn( t + calendar::season_length() ) / 2000.0 ); @@ -32,7 +33,7 @@ double weather_generator::get_weather_temperature( const tripoint &location, con const unsigned modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT; const double dayFraction = time_past_midnight( t ) / 1_days; - double T(raw_noise_4d( x, y, z, modSEED ) * 4.0 ); + double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 ); const double now( ( time_past_new_year( t ) + calendar::season_length() / 2 ) / calendar::year_length() ); // [0,1) From a0a49aa9de68fa7af578aabfd0d007d3a23bfe2d Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 18:14:16 -0500 Subject: [PATCH 6/8] process_temperature: clang-tidy, remove commented code, typo --- src/game.cpp | 2 -- src/item.cpp | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index b9940216193c9..3e0eccca8d1aa 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1738,12 +1738,10 @@ int get_heat_radiation( const tripoint &location, bool direct ) maptile mt = g->m.maptile_at( dest ); - //int ffire = g->m.get_field_intensity( dest, fd_fire ); int ffire = maptile_field_intensity( mt, fd_fire ); if( ffire > 0 ) { heat_intensity = ffire; } else if( maptile_trap_eq( mt, tr_lava ) ) { - //else if( g->m.tr_at( dest ).loadid == tr_lava ) { heat_intensity = 3; } if( heat_intensity == 0 ) { diff --git a/src/item.cpp b/src/item.cpp index dc21169f73438..4ed284abcf2ed 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -182,7 +182,7 @@ inline bool goes_bad_cache_is_set() { return goes_bad_temp_cache_set; } -} +} // namespace item_internal const int item::INFINITE_CHARGES = INT_MAX; @@ -4025,7 +4025,7 @@ std::set item::get_techniques() const bool item::goes_bad() const { if( item_internal::goes_bad_cache_is_set() ) { - return item_internal::goes_bad_cache_fetch();; + return item_internal::goes_bad_cache_fetch(); } if( has_flag( "PROCESSING" ) ) { return false; From 9b2a067d3a7af3711f6c3b7207eb488218215f63 Mon Sep 17 00:00:00 2001 From: Oren Audeles Date: Thu, 4 Jul 2019 18:23:08 -0500 Subject: [PATCH 7/8] process_temperature: DRY, remove unnecessary type conversion weather_generator::get_weather_temperature shared nontrivial code with weather_generator::get_weather. Moved common data calculation, and created function to calculate temperature factor using common data --- src/game.cpp | 2 +- src/weather_gen.cpp | 125 ++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 3e0eccca8d1aa..f09a6ba964250 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1723,7 +1723,7 @@ static int maptile_field_intensity( maptile &mt, field_type_id fld ) } static bool maptile_trap_eq( maptile &mt, const trap_id &id ) { - return mt.get_trap_t().loadid == id; + return mt.get_trap() == id; } int get_heat_radiation( const tripoint &location, bool direct ) diff --git a/src/weather_gen.cpp b/src/weather_gen.cpp index bfccd32b84806..9687937a6b9f3 100644 --- a/src/weather_gen.cpp +++ b/src/weather_gen.cpp @@ -23,27 +23,55 @@ constexpr double tau = 2 * PI; weather_generator::weather_generator() = default; int weather_generator::current_winddir = 1000; -double weather_generator::get_weather_temperature( const tripoint &location, const time_point &t, - unsigned seed ) const +struct weather_gen_common { + double x, y, z; + double ctn; + double seasonal_variation; + unsigned modSEED; + season_type season; +}; + +static weather_gen_common get_common_data( const tripoint &location, const time_point &t, + unsigned seed ) { - const double x( location.x / 2000.0 ); - const double y( location.y / 2000.0 ); - const double z( to_turn( t + calendar::season_length() ) / 2000.0 ); + weather_gen_common result; + // Integer x position / widening factor of the Perlin function. + result.x = location.x / 2000.0; + // Integer y position / widening factor of the Perlin function. + result.y = location.y / 2000.0; + // Integer turn / widening factor of the Perlin function. + result.z = to_turn( t + calendar::season_length() ) / 2000.0; + // Limit the random seed during noise calculation, a large value flattens the noise generator to zero + // Windows has a rand limit of 32768, other operating systems can have higher limits + result.modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT; + const double now( ( time_past_new_year( t ) + calendar::season_length() / 2 ) / + calendar::year_length() ); // [0,1) + result.ctn = cos( tau * now ); // [-1, 1] + result.season = season_of_year( t ); + // Start and end at -1 going up to 1 in summer. + result.seasonal_variation = result.ctn * -1; // [-1, 1] - const unsigned modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT; - const double dayFraction = time_past_midnight( t ) / 1_days; + return result; +} - double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 ); +static double weather_temperature_from_common_data( const weather_generator &wg, + const weather_gen_common &common, const time_point &t ) +{ + const double x( common.x ); + const double y( common.y ); + const double z( common.z ); - const double now( ( time_past_new_year( t ) + calendar::season_length() / 2 ) / - calendar::year_length() ); // [0,1) - const double ctn( cos( tau * now ) ); // [-1, 1] + const unsigned modSEED = common.modSEED; + const double ctn( common.ctn ); // [-1, 1] + const season_type season = common.season; - const season_type season = season_of_year( t ); - const int seasonal_temp_mod[4] = { spring_temp_manual_mod, summer_temp_manual_mod, autumn_temp_manual_mod, winter_temp_manual_mod }; - const double current_t( base_temperature + seasonal_temp_mod[ season ] ); + const double dayFraction = time_past_midnight( t ) / 1_days; + + // manually specified seasonal temp variation from region_settings.json + const int seasonal_temp_mod[4] = { wg.spring_temp_manual_mod, wg.summer_temp_manual_mod, wg.autumn_temp_manual_mod, wg.winter_temp_manual_mod }; + const double current_t( wg.base_temperature + seasonal_temp_mod[ season ] ); // Start and end at -1 going up to 1 in summer. - const double seasonal_variation( ctn * -1 ); // [-1, 1] + const double seasonal_variation( common.seasonal_variation ); // [-1, 1] // Harsh winter nights, hot summers. const double season_atenuation( ctn / 2 + 1 ); // Make summers peak faster and winters not perma-frozen. @@ -53,72 +81,43 @@ double weather_generator::get_weather_temperature( const tripoint &location, con // Day-night temperature variation. double daily_variation( cos( tau * dayFraction - tau / 8 ) * -1 * season_atenuation / 2 + season_dispersion * -1 ); + + double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 ); T += current_t; T += seasonal_variation * 8 * exp( -pow( current_t * 2.7 / 10 - 0.5, 2 ) ); T += daily_variation * 8 * exp( -pow( current_t / 30, 2 ) ); - T = T * 9 / 5 + 32; - return T; + return T * 9 / 5 + 32; +} + +double weather_generator::get_weather_temperature( const tripoint &location, const time_point &t, + unsigned seed ) const +{ + return weather_temperature_from_common_data( *this, get_common_data( location, t, seed ), t ); } w_point weather_generator::get_weather( const tripoint &location, const time_point &t, unsigned seed ) const { - // Integer x position / widening factor of the Perlin function. - const double x( location.x / 2000.0 ); - // Integer y position / widening factor of the Perlin function. - const double y( location.y / 2000.0 ); - // Integer turn / widening factor of the Perlin function. - const double z( to_turn( t + calendar::season_length() ) / 2000.0 ); + const weather_gen_common common = get_common_data( location, t, seed ); - const double dayFraction = time_past_midnight( t ) / 1_days; + const double x( common.x ); + const double y( common.y ); + const double z( common.z ); + + const unsigned modSEED = common.modSEED; + const double ctn( common.ctn ); // [-1, 1] + const season_type season = common.season; - // Limit the random seed during noise calculation, a large value flattens the noise generator to zero - // Windows has a rand limit of 32768, other operating systems can have higher limits - const unsigned modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT; // Noise factors - double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 ); + const double T( weather_temperature_from_common_data( *this, common, t ) ); double H( raw_noise_4d( x, y, z / 5, modSEED + 101 ) ); double H2( raw_noise_4d( x, y, z, modSEED + 151 ) / 4 ); double P( raw_noise_4d( x / 2.5, y / 2.5, z / 30, modSEED + 211 ) * 70 ); double A( raw_noise_4d( x, y, z, modSEED ) * 8.0 ); double W( raw_noise_4d( x / 2.5, y / 2.5, z / 200, modSEED ) * 10.0 ); - const double now( ( time_past_new_year( t ) + calendar::season_length() / 2 ) / - calendar::year_length() ); // [0,1) - const double ctn( cos( tau * now ) ); - const season_type season = season_of_year( t ); - double mod_t( 0 ); // TODO: make this depend on latitude and altitude? - // manually specified seasonal temp variation from region_settings.json - if( season == WINTER ) { - mod_t += winter_temp_manual_mod; - } else if( season == SPRING ) { - mod_t += spring_temp_manual_mod; - } else if( season == SUMMER ) { - mod_t += summer_temp_manual_mod; - } else if( season == AUTUMN ) { - mod_t += autumn_temp_manual_mod; - } - const double current_t( base_temperature + - mod_t ); // Start and end at -1 going up to 1 in summer. - const double seasonal_variation( ctn * -1 ); - // Harsh winter nights, hot summers. - const double season_atenuation( ctn / 2 + 1 ); - // Make summers peak faster and winters not perma-frozen. - const double season_dispersion( pow( 2, - ctn + 1 ) - 2.3 ); - // Day-night temperature variation. - double daily_variation( cos( tau * dayFraction - tau / 8 ) * -1 * season_atenuation / 2 + - season_dispersion * -1 ); - // Add baseline to the noise. - T += current_t; - // Add season curve offset to account for the winter-summer difference in day-night difference. - T += seasonal_variation * 8 * exp( -pow( current_t * 2.7 / 10 - 0.5, - 2 ) ); - // Add daily variation scaled to the inverse of the current baseline. A very specific and finicky adjustment curve. - T += daily_variation * 8 * exp( -pow( current_t / 30, - 2 ) ); - T = T * 9 / 5 + 32; // Convert to imperial. =| + const double seasonal_variation( common.seasonal_variation ); // [-1, 1] // Humidity variation double mod_h( 0 ); From f723f51cdfef97d384904ce49a656c6e19b36806 Mon Sep 17 00:00:00 2001 From: OrenAudeles Date: Fri, 5 Jul 2019 04:27:43 -0500 Subject: [PATCH 8/8] Update src/weather_gen.cpp Co-Authored-By: ZhilkinSerg --- src/weather_gen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/weather_gen.cpp b/src/weather_gen.cpp index 9687937a6b9f3..f572df98df38d 100644 --- a/src/weather_gen.cpp +++ b/src/weather_gen.cpp @@ -24,7 +24,9 @@ weather_generator::weather_generator() = default; int weather_generator::current_winddir = 1000; struct weather_gen_common { - double x, y, z; + double x; + double y; + double z; double ctn; double seasonal_variation; unsigned modSEED;