From 8aa0a1bb8853071b90ae87a33f4f8b9cdf2dad96 Mon Sep 17 00:00:00 2001 From: scarf Date: Wed, 27 Sep 2023 13:02:36 +0900 Subject: [PATCH] perf: cache character's dead state (#3282) * perf: extract glass jaw to variable * perf: cache `Chracter::is_dead_state` see: https://github.com/CleverRaven/Cataclysm-DDA/pull/67535/commits/5c5b7ca9a3872a95b269b86b84634ef4232f3662 Co-authored-by: Andrew Krieger * refactor: reorganize suffer_in_sunlight * refactor: use std::any_of * style(autofix.ci): automated formatting --------- Co-authored-by: Andrew Krieger Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/character.cpp | 23 +++++++++++++++++++---- src/character.h | 8 +++++++- src/creature.h | 2 +- src/mutation.cpp | 11 ++++------- src/suffer.cpp | 48 ++++++++++++++++++++++++----------------------- 5 files changed, 56 insertions(+), 36 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 9d6b3c5debd7..29bb6b51d3c4 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1,4 +1,5 @@ #include "character.h" +#include "bodypart.h" #include "character_encumbrance.h" #include @@ -221,6 +222,7 @@ static const trait_id trait_ANTLERS( "ANTLERS" ); static const trait_id trait_ASTHMA( "ASTHMA" ); static const trait_id trait_BADBACK( "BADBACK" ); static const trait_id trait_CF_HAIR( "CF_HAIR" ); +static const trait_id trait_GLASSJAW( "GLASSJAW" ); static const trait_id trait_DEBUG_NODMG( "DEBUG_NODMG" ); static const trait_id trait_DEFT( "DEFT" ); static const trait_id trait_PROF_SKATER( "PROF_SKATER" ); @@ -505,13 +507,25 @@ character_id Character::getID() const return this->id; } -bool Character::is_dead_state() const +auto Character::is_dead_state() const -> bool { - const auto all_bps = get_all_body_parts( true ); + if( cached_dead_state.has_value() ) { + return cached_dead_state.value(); + } - return std::any_of( all_bps.begin(), all_bps.end(), [this]( const bodypart_id & bp ) { + const auto all_bps = get_all_body_parts( true ); + cached_dead_state = std::any_of( all_bps.begin(), all_bps.end(), [this]( const bodypart_id & bp ) { return bp->essential && get_part_hp_cur( bp ) <= 0; } ); + return *cached_dead_state; +} + +void Character::set_part_hp_cur( const bodypart_id &id, int set ) +{ + if( set < 0 ) { + cached_dead_state.reset(); + } + Creature::set_part_hp_cur( id, set ); } field_type_id Character::bloodType() const @@ -1604,6 +1618,7 @@ void Character::recalc_hp() float hp_mod = 1.0f + mutation_value( "hp_modifier" ) + mutation_value( "hp_modifier_secondary" ); float hp_adjustment = mutation_value( "hp_adjustment" ) + ( str_boost_val * 3 ); calc_all_parts_hp( hp_mod, hp_adjustment, get_str_base() ); + cached_dead_state.reset(); } void Character::calc_all_parts_hp( float hp_mod, float hp_adjustment, int str_max ) @@ -1612,7 +1627,7 @@ void Character::calc_all_parts_hp( float hp_mod, float hp_adjustment, int str_ma bodypart &bp = get_part( part.first ); int new_max = ( part.first->base_hp + str_max * 3 + hp_adjustment ) * hp_mod; - if( has_trait( trait_id( "GLASSJAW" ) ) && part.first == bodypart_str_id( "head" ) ) { + if( has_trait( trait_GLASSJAW ) && part.first == bodypart_str_id( "head" ) ) { new_max *= 0.8; } diff --git a/src/character.h b/src/character.h index 07214353d534..315e5b8a7275 100644 --- a/src/character.h +++ b/src/character.h @@ -242,7 +242,13 @@ class Character : public Creature, public visitable void setID( character_id i, bool force = false ); /** Returns true if the character should be dead */ - bool is_dead_state() const override; + auto is_dead_state() const -> bool override; + + private: + mutable std::optional cached_dead_state; + + public: + void set_part_hp_cur( const bodypart_id &id, int set ) override; field_type_id bloodType() const override; field_type_id gibType() const override; diff --git a/src/creature.h b/src/creature.h index f2ebc8b9398b..b046d80b3f10 100644 --- a/src/creature.h +++ b/src/creature.h @@ -522,7 +522,7 @@ class Creature int get_part_healed_total( const bodypart_id &id ) const; - void set_part_hp_cur( const bodypart_id &id, int set ); + virtual void set_part_hp_cur( const bodypart_id &id, int set ); void set_part_hp_max( const bodypart_id &id, int set ); void set_part_healed_total( const bodypart_id &id, int set ); void mod_part_hp_cur( const bodypart_id &id, int mod ); diff --git a/src/mutation.cpp b/src/mutation.cpp index a9d044dd5943..824ab98c4e83 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -105,13 +105,10 @@ bool Character::has_trait( const trait_id &b ) const bool Character::has_trait_flag( const trait_flag_str_id &b ) const { - for( const mutation_branch *mut : cached_mutations ) { - if( mut->flags.count( b ) > 0 ) { - return true; - } - } - - return false; + return std::any_of( cached_mutations.cbegin(), cached_mutations.cend(), + [&b]( const mutation_branch * mut ) -> bool { + return mut->flags.count( b ); + } ); } bool Character::has_base_trait( const trait_id &b ) const diff --git a/src/suffer.cpp b/src/suffer.cpp index 18f3ae6cb508..977863735989 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -801,39 +801,41 @@ void Character::suffer_feral_kill_withdrawl() void Character::suffer_in_sunlight() { - double sleeve_factor = armwear_factor(); - const bool has_hat = wearing_something_on( bodypart_id( "head" ) ); - const bool leafy = has_trait( trait_LEAVES ) || has_trait( trait_LEAVES2 ) || + if( !g->is_in_sunlight( pos() ) ) { + return; + } + + const bool leafy = has_trait( trait_LEAVES ) || + has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 ); - const bool leafier = has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 ); - const bool leafiest = has_trait( trait_LEAVES3 ); - int sunlight_nutrition = 0; - if( leafy && get_map().is_outside( pos() ) && ( g->light_level( pos().z ) >= 40 ) ) { + + if( leafy ) { + const bool leafier = has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 ); + const bool leafiest = has_trait( trait_LEAVES3 ); + double sleeve_factor = armwear_factor(); + const bool has_hat = wearing_something_on( bodypart_id( "head" ) ); const float weather_factor = ( get_weather().weather_id->sun_intensity >= sun_intensity_type::normal ) ? 1.0 : 0.5; const int player_local_temp = get_weather().get_temperature( pos() ); - int flux = ( player_local_temp - 65 ) / 2; + const int flux = ( player_local_temp - 65 ) / 2; + + int sunlight_nutrition = 0; if( !has_hat ) { sunlight_nutrition += ( 100 + flux ) * weather_factor; } - if( leafier ) { - int rate = ( ( 100 * sleeve_factor ) + flux ) * 2; + if( leafier || leafiest ) { + const int rate = ( ( 100 * sleeve_factor ) + flux ) * 2; sunlight_nutrition += ( rate * ( leafiest ? 2 : 1 ) ) * weather_factor; } - } - - if( x_in_y( sunlight_nutrition, 18000 ) ) { - vitamin_mod( vitamin_id( "vitA" ), 1, true ); - vitamin_mod( vitamin_id( "vitC" ), 1, true ); - } - - if( x_in_y( sunlight_nutrition, 12000 ) ) { - mod_stored_kcal( 10 ); - stomach.ate(); - } + if( x_in_y( sunlight_nutrition, 18000 ) ) { + vitamin_mod( vitamin_id( "vitA" ), 1, true ); + vitamin_mod( vitamin_id( "vitC" ), 1, true ); + } - if( !g->is_in_sunlight( pos() ) ) { - return; + if( x_in_y( sunlight_nutrition, 12000 ) ) { + mod_stored_kcal( 10 ); + stomach.ate(); + } } if( has_trait( trait_ALBINO ) || has_effect( effect_datura ) || has_trait( trait_SUNBURN ) ) {