From cfa34f5f045170a68bf658fec3d0ca7776b99e94 Mon Sep 17 00:00:00 2001 From: osuphobia Date: Mon, 27 May 2024 00:18:50 +0800 Subject: [PATCH 1/2] Correctly display pain penalties. --- src/avatar.cpp | 13 +++++++++---- src/character.cpp | 24 ++++++++++++++++++++---- src/character.h | 8 ++++++++ src/medical_ui.cpp | 2 +- src/player_display.cpp | 2 +- tests/enchantments_test.cpp | 6 +++--- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/avatar.cpp b/src/avatar.cpp index b0ed97fac3136..b1d98d8142cf3 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -1017,10 +1017,15 @@ void avatar::reset_stats() // Pain if( get_perceived_pain() > 0 ) { const stat_mod ppen = get_pain_penalty(); - mod_str_bonus( -ppen.strength ); - mod_dex_bonus( -ppen.dexterity ); - mod_int_bonus( -ppen.intelligence ); - mod_per_bonus( -ppen.perception ); + ppen_str = ppen.strength; + ppen_dex = ppen.dexterity; + ppen_int = ppen.intelligence; + ppen_per = ppen.perception; + ppen_spd = ppen.speed; + mod_str_bonus( -ppen_str ); + mod_dex_bonus( -ppen_dex ); + mod_int_bonus( -ppen_int ); + mod_per_bonus( -ppen_per ); if( ppen.dexterity > 0 ) { add_miss_reason( _( "Your pain distracts you!" ), static_cast( ppen.dexterity ) ); } diff --git a/src/character.cpp b/src/character.cpp index c51123d74d729..ec0e47778c774 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -557,6 +557,11 @@ Character::Character() : dex_bonus = 0; per_bonus = 0; int_bonus = 0; + ppen_str = 0; + ppen_dex = 0; + ppen_int = 0; + ppen_per = 0; + ppen_spd = 0; lifestyle = 0; daily_health = 0; health_tally = 0; @@ -12343,10 +12348,10 @@ stat_mod Character::get_pain_penalty() const // Prevent negative penalties, there is better ways to give bonuses for pain // Also not make character has 0 stats - ret.strength = std::max( ret.strength, 1 ); - ret.dexterity = std::max( ret.dexterity, 1 ); - ret.intelligence = std::max( ret.intelligence, 1 ); - ret.perception = std::max( ret.perception, 1 ); + ret.strength = std::min( get_str() - 1, std::max( ret.strength, 1 ) ); + ret.dexterity = std::min( get_dex() - 1, std::max( ret.dexterity, 1 ) ); + ret.intelligence = std::min( get_int() - 1, std::max( ret.intelligence, 1 ) ); + ret.perception = std::min( get_per() - 1, std::max( ret.perception, 1 ) ); int speed_penalty = std::pow( pain, 0.7f ); @@ -12358,6 +12363,17 @@ stat_mod Character::get_pain_penalty() const return ret; } +stat_mod Character::read_pain_penalty() const +{ + stat_mod ret; + ret.strength = ppen_str; + ret.dexterity = ppen_dex; + ret.intelligence = ppen_int; + ret.perception = ppen_per; + ret.speed = ppen_spd; + return ret; +} + int Character::get_lift_str() const { int str = get_arm_str(); diff --git a/src/character.h b/src/character.h index 0c3a17ef8d75d..9c7b415988273 100644 --- a/src/character.h +++ b/src/character.h @@ -579,6 +579,13 @@ class Character : public Creature, public visitable int int_cur; int per_cur; + // Used to display pain penalties + int ppen_str; + int ppen_dex; + int ppen_int; + int ppen_per; + int ppen_spd; + int kill_xp = 0; // Level-up points spent on Stats through Kills int spent_upgrade_points = 0; @@ -916,6 +923,7 @@ class Character : public Creature, public visitable static int thirst_speed_penalty( int thirst ); /** Returns the effect of pain on stats */ stat_mod get_pain_penalty() const; + stat_mod read_pain_penalty() const; /** returns players strength adjusted by any traits that affect strength during lifting jobs */ int get_lift_str() const; /** Takes off an item, returning false on fail. The taken off item is processed in the interact */ diff --git a/src/medical_ui.cpp b/src/medical_ui.cpp index b65a86cd547cf..2fa1292c601b2 100644 --- a/src/medical_ui.cpp +++ b/src/medical_ui.cpp @@ -613,7 +613,7 @@ static medical_column draw_stats_summary( const int column_count, avatar *player speed_detail_str += colorize( string_format( _( "%s -%2d%%\n" ), pge_str, pen ), c_red ); } - pen = player->get_pain_penalty().speed; + pen = player->ppen_spd; if( pen >= 1 ) { pge_str = pgettext( "speed penalty", "Pain " ); speed_detail_str += colorize( string_format( _( "%s -%2d%%\n" ), pge_str, pen ), c_red ); diff --git a/src/player_display.cpp b/src/player_display.cpp index b678e3c5f133d..c723d8f5c4ddb 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -1544,7 +1544,7 @@ void Character::disp_info( bool customize_character ) } } if( get_perceived_pain() > 0 ) { - const stat_mod ppen = get_pain_penalty(); + const stat_mod ppen = read_pain_penalty(); std::pair pain_desc = display::pain_text_color( *this ); std::string pain_text; pain_desc.first = string_format( _( "You are in %s\n" ), pain_desc.first ); diff --git a/tests/enchantments_test.cpp b/tests/enchantments_test.cpp index 369b6a0f32f91..81c76bedd03d2 100644 --- a/tests/enchantments_test.cpp +++ b/tests/enchantments_test.cpp @@ -369,7 +369,7 @@ TEST_CASE( "Enchantment_PAIN_PENALTY_MOD_test", "[magic][enchantments]" ) INFO( "Character has 50 pain, not affected by enchantments" ); guy.set_pain( 50 ); advance_turn( guy ); - INFO( "Stats are: 6 str, 5 dex, 3 int, 3 per, 85 speed" ); + INFO( "Stats are: 6 str, 5 dex, 4 int, 4 per, 85 speed" ); REQUIRE( guy.get_str() == 6 ); REQUIRE( guy.get_dex() == 5 ); REQUIRE( guy.get_int() == 4 ); @@ -381,10 +381,10 @@ TEST_CASE( "Enchantment_PAIN_PENALTY_MOD_test", "[magic][enchantments]" ) guy.i_add( item( "test_PAIN_PENALTY_MOD_ench_item_1" ) ); guy.recalculate_enchantment_cache(); advance_turn( guy ); - INFO( "Stats are: 4 str, 7 dex, 7 int, 0 per, 89 speed" ); + INFO( "Stats are: 4 str, 7 dex, 7 int, 1 per, 89 speed" ); REQUIRE( guy.get_str() == 4 ); REQUIRE( guy.get_dex() == 7 ); REQUIRE( guy.get_int() == 7 ); - REQUIRE( guy.get_per() == 0 ); + REQUIRE( guy.get_per() == 1 ); REQUIRE( guy.get_speed() == 89 ); } From 1059f6b49f5b243916e2593870a0b3edb87639f4 Mon Sep 17 00:00:00 2001 From: osuphobia <78858975+osuphobia@users.noreply.github.com> Date: Mon, 27 May 2024 12:13:49 +0800 Subject: [PATCH 2/2] use std::clamp for readability --- src/character.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index ec0e47778c774..574739832931d 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -12348,10 +12348,10 @@ stat_mod Character::get_pain_penalty() const // Prevent negative penalties, there is better ways to give bonuses for pain // Also not make character has 0 stats - ret.strength = std::min( get_str() - 1, std::max( ret.strength, 1 ) ); - ret.dexterity = std::min( get_dex() - 1, std::max( ret.dexterity, 1 ) ); - ret.intelligence = std::min( get_int() - 1, std::max( ret.intelligence, 1 ) ); - ret.perception = std::min( get_per() - 1, std::max( ret.perception, 1 ) ); + ret.strength = std::clamp( ret.strength, 1, get_str() - 1 ); + ret.dexterity = std::clamp( ret.dexterity, 1, get_dex() - 1 ); + ret.intelligence = std::clamp( ret.intelligence, 1, get_int() - 1 ); + ret.perception = std::clamp( ret.perception, 1, get_per() - 1 ); int speed_penalty = std::pow( pain, 0.7f );