-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hot air from fires and direct heat radiation applies to tile temperatures #24956
Changes from all commits
1ecc2b0
96b0331
302fb2a
5ecb832
d7e72be
cec0b41
72efb9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1789,10 +1789,83 @@ void game::update_weather() | |
} | ||
} | ||
|
||
int get_heat_radiation( const tripoint &location, bool direct ) | ||
{ | ||
// Direct heat from fire sources | ||
// Cache fires to avoid scanning the map around us bp times | ||
// Stored as intensity-distance pairs | ||
int temp_mod = 0; | ||
std::vector<std::pair<int, int>> fires; | ||
fires.reserve( 13 * 13 ); | ||
int best_fire = 0; | ||
for( const tripoint &dest : g->m.points_in_radius( location, 6 ) ) { | ||
int heat_intensity = 0; | ||
|
||
int ffire = g->m.get_field_strength( dest, fd_fire ); | ||
if( ffire > 0 ) { | ||
heat_intensity = ffire; | ||
} else if( g->m.tr_at( dest ).loadid == tr_lava ) { | ||
heat_intensity = 3; | ||
} | ||
if( heat_intensity == 0 || !g->m.sees( location, dest, -1 ) ) { | ||
// No heat source here | ||
continue; | ||
} | ||
// Ensure fire_dist >= 1 to avoid divide-by-zero errors. | ||
const int fire_dist = std::max( 1, square_dist( dest, location ) ); | ||
fires.emplace_back( std::make_pair( heat_intensity, fire_dist ) ); | ||
if( fire_dist <= 1 ) { | ||
// Extend limbs/lean over a single adjacent fire to warm up | ||
best_fire = std::max( best_fire, heat_intensity ); | ||
} | ||
} | ||
|
||
for( const auto &intensity_dist : fires ) { | ||
const int intensity = intensity_dist.first; | ||
const int distance = intensity_dist.second; | ||
temp_mod += 6 * intensity * intensity / distance; | ||
} | ||
if( direct ) { | ||
return best_fire; | ||
} | ||
return temp_mod; | ||
} | ||
|
||
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 ); | ||
// directly on fire/lava tiles | ||
int tile_strength = g->m.get_field_strength( location, fd_fire ); | ||
if( tile_strength > 0 || trap_at_pos.loadid == tr_lava ) { | ||
temp_mod += 300; | ||
} | ||
// hot air of a fire/lava | ||
auto tile_strength_mod = []( const tripoint &loc, field_id fld, int case_1, int case_2, int case_3 ){ | ||
int strength = g->m.get_field_strength( loc, fld ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to changing from |
||
int cases[3] = { case_1, case_2, case_3 }; | ||
return ( strength > 0 && strength < 4 ) ? cases[ strength - 1 ] : 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having looked into things more carefully the condition isn't necessary. Can be modified to just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...and it sends the game into infinite loop with insane temperatures, stamina loss, and inevitable death. No, just no... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh I'm dumb. I was making an assumption and not validating that assumption. If the field does not exist at the location it's not going to be returning a value in range [1, 3]. Sorry for the bad suggestion. |
||
}; | ||
|
||
temp_mod += tile_strength_mod( location, fd_hot_air1, 2, 6, 10 ); | ||
temp_mod += tile_strength_mod( location, fd_hot_air2, 6, 16, 20 ); | ||
temp_mod += tile_strength_mod( location, fd_hot_air3, 16, 40, 70 ); | ||
temp_mod += tile_strength_mod( location, fd_hot_air4, 70, 100, 160 ); | ||
|
||
return temp_mod; | ||
} | ||
|
||
int game::get_temperature( const tripoint &location ) | ||
{ | ||
int temp_mod = 0; // local modifier | ||
|
||
if( !new_game ) { | ||
temp_mod += get_heat_radiation( location, false ); | ||
temp_mod += get_convection_temperature( location ); | ||
} | ||
//underground temperature = average New England temperature = 43F/6C rounded to int | ||
return ( location.z < 0 ? AVERAGE_ANNUAL_TEMPERATURE : temperature ) + ( new_game ? 0 : m.temperature( location ) ); | ||
return ( location.z < 0 ? AVERAGE_ANNUAL_TEMPERATURE : temperature ) + ( new_game ? 0 : ( m.temperature( location ) + temp_mod ) ); | ||
} | ||
|
||
int game::assign_mission_id() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whether function is moved from
class game
to be a free function, or remains as is, can shorten all instances ofg->m.__func__
to justm.__func__
Other lines impacted:
Function is only called currently as
g->get_heat_radiation
so it already has access to the global-g's map.