Skip to content

Commit

Permalink
Merge pull request #32119 from OrenAudeles/process_item
Browse files Browse the repository at this point in the history
Speed up item processing
  • Loading branch information
kevingranade authored Jul 8, 2019
2 parents 9d36f0d + f723f51 commit 948b8a6
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 58 deletions.
43 changes: 28 additions & 15 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,17 @@ 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() == id;
}

int get_heat_radiation( const tripoint &location, bool direct )
{
// Direct heat from fire sources
Expand All @@ -1725,10 +1736,12 @@ 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 = 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 ) ) {
heat_intensity = 3;
}
if( heat_intensity == 0 ) {
Expand Down Expand Up @@ -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;
}
Expand Down
36 changes: 33 additions & 3 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,29 @@ 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;
}
} // namespace item_internal

const int item::INFINITE_CHARGES = INT_MAX;

item::item() : bday( calendar::start )
Expand Down Expand Up @@ -4005,6 +4028,9 @@ std::set<matec_id> 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;
}
Expand Down Expand Up @@ -5057,7 +5083,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
Expand Down Expand Up @@ -7443,6 +7469,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 {
Expand Down Expand Up @@ -7479,8 +7506,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;
}
Expand Down Expand Up @@ -7521,6 +7548,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;
}
}
Expand All @@ -7532,13 +7560,15 @@ 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;
}

// Just now created items will get here.
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 )
Expand Down
118 changes: 78 additions & 40 deletions src/weather_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,65 +23,103 @@ constexpr double tau = 2 * PI;
weather_generator::weather_generator() = default;
int weather_generator::current_winddir = 1000;

w_point weather_generator::get_weather( const tripoint &location, const time_point &t,
unsigned seed ) const
struct weather_gen_common {
double x;
double y;
double 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 )
{
weather_gen_common result;
// Integer x position / widening factor of the Perlin function.
const double x( location.x / 2000.0 );
result.x = location.x / 2000.0;
// Integer y position / widening factor of the Perlin function.
const double y( location.y / 2000.0 );
result.y = location.y / 2000.0;
// Integer turn / widening factor of the Perlin function.
const double z( to_turn<int>( t + calendar::season_length() ) / 2000.0 );

const double dayFraction = time_past_midnight( t ) / 1_days;

result.z = to_turn<int>( 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
const unsigned modSEED = seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT;
// Noise factors
double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 );
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 );

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)
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?
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]

return result;
}

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 unsigned modSEED = common.modSEED;
const double ctn( common.ctn ); // [-1, 1]
const season_type season = common.season;

const double dayFraction = time_past_midnight( t ) / 1_days;

// 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 );
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 );
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.
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.

double T( raw_noise_4d( x, y, z, modSEED ) * 4.0 );
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. =|
T += seasonal_variation * 8 * exp( -pow( current_t * 2.7 / 10 - 0.5, 2 ) );
T += daily_variation * 8 * exp( -pow( current_t / 30, 2 ) );

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
{
const weather_gen_common common = get_common_data( location, t, seed );

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;

// Noise factors
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 );

// Start and end at -1 going up to 1 in summer.
const double seasonal_variation( common.seasonal_variation ); // [-1, 1]

// Humidity variation
double mod_h( 0 );
Expand Down
2 changes: 2 additions & 0 deletions src/weather_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
};

Expand Down

0 comments on commit 948b8a6

Please sign in to comment.