Skip to content

Commit 9b0efb8

Browse files
authored
Merge pull request #82309 from sparr/dedupe_effect_intensity_clamp
Refactor effect parameter updating
2 parents 683bfed + 318b79b commit 9b0efb8

File tree

5 files changed

+68
-79
lines changed

5 files changed

+68
-79
lines changed

src/creature.cpp

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,14 +1830,6 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
18301830
const int prev_int = e.get_intensity();
18311831
// If we do, mod the duration, factoring in the mod value
18321832
e.mod_duration( dur * e.get_dur_add_perc() / 100 );
1833-
// Limit to max duration
1834-
if( e.get_duration() > e.get_max_duration() ) {
1835-
e.set_duration( e.get_max_duration() );
1836-
}
1837-
// Adding a permanent effect makes it permanent
1838-
if( e.is_permanent() ) {
1839-
e.pause_effect();
1840-
}
18411833
// int_dur_factor overrides all other intensity settings
18421834
// ...but it's handled in set_duration, so explicitly do nothing here
18431835
if( e.get_int_dur_factor() > 0_turns ) {
@@ -1848,14 +1840,8 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
18481840
} else if( e.get_int_add_val() != 0 ) {
18491841
e.mod_intensity( e.get_int_add_val(), is_avatar() );
18501842
}
1851-
1852-
// Bound intensity by [1, max intensity]
1853-
if( e.get_intensity() < 1 ) {
1854-
add_msg_debug( debugmode::DF_CREATURE, "Bad intensity, ID: %s", e.get_id().c_str() );
1855-
e.set_intensity( 1 );
1856-
} else if( e.get_intensity() > e.get_max_intensity() ) {
1857-
e.set_intensity( e.get_max_intensity() );
1858-
}
1843+
// Bound new effect intensity by [1, max intensity]
1844+
e.clamp_intensity();
18591845
if( e.get_intensity() != prev_int ) {
18601846
on_effect_int_change( eff_id, e.get_intensity(), bp );
18611847
}
@@ -1867,23 +1853,7 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
18671853

18681854
// Now we can make the new effect for application
18691855
effect e( effect_source( source ), &type, dur, bp.id(), permanent, intensity, calendar::turn );
1870-
// Bound to max duration
1871-
if( e.get_duration() > e.get_max_duration() ) {
1872-
e.set_duration( e.get_max_duration() );
1873-
}
18741856

1875-
// Force intensity if it is duration based
1876-
if( e.get_int_dur_factor() != 0_turns ) {
1877-
const int intensity = std::ceil( e.get_duration() / e.get_int_dur_factor() );
1878-
e.set_intensity( std::max( 1, intensity ) );
1879-
}
1880-
// Bound new effect intensity by [1, max intensity]
1881-
if( e.get_intensity() < 1 ) {
1882-
add_msg_debug( debugmode::DF_CREATURE, "Bad intensity, ID: %s", e.get_id().c_str() );
1883-
e.set_intensity( 1 );
1884-
} else if( e.get_intensity() > e.get_max_intensity() ) {
1885-
e.set_intensity( e.get_max_intensity() );
1886-
}
18871857
( *effects )[eff_id][bp] = e;
18881858
if( Character *ch = as_character() ) {
18891859
get_event_bus().send<event_type::character_gains_effect>( ch->getID(), bp.id(), eff_id, intensity );

src/effect.cpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,16 +1081,10 @@ time_duration effect::get_max_duration() const
10811081
void effect::set_duration( const time_duration &dur, bool alert )
10821082
{
10831083
duration = dur;
1084-
// Cap to max_duration
1085-
if( duration > eff_type->max_duration ) {
1086-
duration = eff_type->max_duration;
1087-
}
10881084

1089-
// Force intensity if it is duration based
1090-
if( eff_type->int_dur_factor != 0_turns ) {
1091-
const int intensity = std::ceil( duration / eff_type->int_dur_factor );
1092-
set_intensity( std::max( 1, intensity ), alert );
1093-
}
1085+
clamp_duration();
1086+
1087+
apply_int_dur_factor( alert );
10941088

10951089
add_msg_debug( debugmode::DF_EFFECT, "ID: %s, Duration %s", get_id().c_str(),
10961090
to_string_writable( duration ) );
@@ -1103,6 +1097,11 @@ void effect::mult_duration( double dur, bool alert )
11031097
{
11041098
set_duration( duration * dur, alert );
11051099
}
1100+
void effect::clamp_duration()
1101+
{
1102+
duration = std::min( duration, eff_type->max_duration );
1103+
1104+
}
11061105

11071106
static int cap_to_size( const int max, int attempt )
11081107
{
@@ -1213,13 +1212,9 @@ int effect::get_effective_intensity() const
12131212

12141213
int effect::set_intensity( int val, bool alert )
12151214
{
1216-
if( intensity < 1 ) {
1217-
// Fix bad intensity
1218-
add_msg_debug( debugmode::DF_EFFECT, "Bad intensity, ID: %s", get_id().c_str() );
1219-
intensity = 1;
1220-
}
1215+
clamp_intensity();
12211216

1222-
val = std::max( std::min( val, eff_type->max_intensity ), 0 );
1217+
val = std::clamp( val, 0, eff_type->max_intensity );
12231218
if( val == intensity ) {
12241219
// Nothing to change
12251220
return intensity;
@@ -1243,11 +1238,31 @@ int effect::set_intensity( int val, bool alert )
12431238
return intensity;
12441239
}
12451240

1241+
int effect::clamp_intensity()
1242+
{
1243+
if( intensity < 1 ) {
1244+
add_msg_debug( debugmode::DF_CREATURE, "Bad intensity, ID: %s", eff_type->id.c_str() );
1245+
intensity = 1;
1246+
} else if( intensity > eff_type->max_intensity ) {
1247+
intensity = eff_type->max_intensity;
1248+
}
1249+
return intensity;
1250+
}
1251+
12461252
int effect::mod_intensity( int mod, bool alert )
12471253
{
12481254
return set_intensity( intensity + mod, alert );
12491255
}
12501256

1257+
int effect::apply_int_dur_factor( bool alert )
1258+
{
1259+
if( eff_type->int_dur_factor != 0_turns ) {
1260+
const int new_intensity = std::ceil( duration / eff_type->int_dur_factor );
1261+
set_intensity( std::max( 1, new_intensity ), alert );
1262+
}
1263+
return intensity;
1264+
}
1265+
12511266
const std::vector<trait_id> &effect::get_resist_traits() const
12521267
{
12531268
return eff_type->resist_traits;

src/effect.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ class effect
277277
eff_type( peff_type ), duration( dur ), bp( part ),
278278
permanent( perm ), intensity( nintensity ), start_time( nstart_time ),
279279
source( source ) {
280+
clamp_duration();
281+
apply_int_dur_factor();
282+
clamp_intensity();
280283
}
281284
effect( const effect & ) = default;
282285
effect &operator=( const effect & ) = default;
@@ -318,6 +321,8 @@ class effect
318321
void mod_duration( const time_duration &dur, bool alert = false );
319322
/** Multiplies the duration, capping at max_duration. */
320323
void mult_duration( double dur, bool alert = false );
324+
/** Caps duration at max_duration. */
325+
void clamp_duration();
321326

322327
std::vector<vitamin_applied_effect> vit_effects( bool reduced ) const;
323328

@@ -353,6 +358,12 @@ class effect
353358
*/
354359
int set_intensity( int val, bool alert = false );
355360

361+
/**
362+
* Clamps intensity of effect to range [1..max_intensity]
363+
* @return new clamped intensity of the effect
364+
*/
365+
int clamp_intensity();
366+
356367
/**
357368
* Modify intensity of effect capped by range [1..max_intensity]
358369
* @param mod Amount to increase current intensity by
@@ -361,6 +372,12 @@ class effect
361372
*/
362373
int mod_intensity( int mod, bool alert = false );
363374

375+
/**
376+
* Set intensity of effect if it is duration based
377+
* @return potentially updated intensity of the effect
378+
*/
379+
int apply_int_dur_factor( bool alert = false );
380+
364381
/** Returns the string id of the resist trait to be used in has_trait("id"). */
365382
const std::vector<trait_id> &get_resist_traits() const;
366383
/** Returns the string id of the resist effect to be used in has_effect("id"). */

src/vehicle.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,14 +1580,6 @@ void vehicle::add_effect( const effect_source &source, const efftype_id &eff_id,
15801580
effect &e = found_effect->second;
15811581
// If we do, mod the duration, factoring in the mod value
15821582
e.mod_duration( dur * e.get_dur_add_perc() / 100 );
1583-
// Limit to max duration
1584-
if( e.get_duration() > e.get_max_duration() ) {
1585-
e.set_duration( e.get_max_duration() );
1586-
}
1587-
// Adding a permanent effect makes it permanent
1588-
if( e.is_permanent() ) {
1589-
e.pause_effect();
1590-
}
15911583
}
15921584

15931585
if( !found ) {
@@ -1596,23 +1588,7 @@ void vehicle::add_effect( const effect_source &source, const efftype_id &eff_id,
15961588
// Now we can make the new effect for application
15971589
effect e( effect_source( source ), &type, dur, bodypart_str_id::NULL_ID(), permanent, intensity,
15981590
calendar::turn );
1599-
// Bound to max duration
1600-
if( e.get_duration() > e.get_max_duration() ) {
1601-
e.set_duration( e.get_max_duration() );
1602-
}
16031591

1604-
// Force intensity if it is duration based
1605-
if( e.get_int_dur_factor() != 0_turns ) {
1606-
const int intensity = std::ceil( e.get_duration() / e.get_int_dur_factor() );
1607-
e.set_intensity( std::max( 1, intensity ) );
1608-
}
1609-
// Bound new effect intensity by [1, max intensity]
1610-
if( e.get_intensity() < 1 ) {
1611-
add_msg_debug( debugmode::DF_CREATURE, "Bad intensity, ID: %s", e.get_id().c_str() );
1612-
e.set_intensity( 1 );
1613-
} else if( e.get_intensity() > e.get_max_intensity() ) {
1614-
e.set_intensity( e.get_max_intensity() );
1615-
}
16161592
effects[eff_id] = e;
16171593
}
16181594
}

tests/effect_test.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,40 @@ static const vitamin_id vitamin_test_vitx( "test_vitx" );
5757
// effect::get_start_time
5858
//
5959
// Create an `effect` object with given parameters, and check they were initialized correctly.
60-
static void check_effect_init( const std::string &eff_name, const time_duration &dur,
61-
const std::string &bp_name, const bool permanent, const int intensity,
60+
static void check_effect_init( const std::string &eff_name,
61+
const time_duration &requested_dur, const time_duration &expected_dur,
62+
const std::string &bp_name, const bool permanent,
63+
const int requested_int, const int expected_int,
6264
const time_point &start_time )
6365
{
6466
const efftype_id eff_id( eff_name );
6567
const effect_type &type = eff_id.obj();
6668
const bodypart_str_id bp( bp_name );
6769

68-
effect effect_obj( effect_source::empty(), &type, dur, bp, permanent, intensity, start_time );
70+
effect effect_obj( effect_source::empty(), &type, requested_dur, bp, permanent, requested_int,
71+
start_time );
6972

70-
CHECK( dur == effect_obj.get_duration() );
73+
CHECK( expected_dur == effect_obj.get_duration() );
7174
CHECK( bp.id() == effect_obj.get_bp() );
7275
CHECK( permanent == effect_obj.is_permanent() );
73-
CHECK( intensity == effect_obj.get_intensity() );
76+
CHECK( expected_int == effect_obj.get_intensity() );
7477
CHECK( start_time == effect_obj.get_start_time() );
7578
}
7679

7780
TEST_CASE( "effect_initialization_test", "[effect][init]" )
7881
{
7982
// "debugged" effect is defined in data/mods/TEST_DATA/effects.json
80-
check_effect_init( "debugged", 1_days, "head", false, 5, calendar::turn_zero );
81-
check_effect_init( "bite", 1_minutes, "torso", true, 2, calendar::turn );
82-
check_effect_init( "grabbed", 1_turns, "arm_r", false, 1, calendar::turn + 1_hours );
83+
// "debugged" effect has max_duration 1 hour, so 1 day gets clamped
84+
check_effect_init( "debugged", 1_days, 1_hours, "head", false, 5, 5, calendar::turn_zero );
85+
check_effect_init( "debugged", 1_minutes, 1_minutes, "head", false, 5, 5, calendar::turn_zero );
86+
// "bite" effect has int_dur_factor, so intensity is calculated from duration regardless of requested intensity
87+
check_effect_init( "bite", 60_minutes, 60_minutes, "torso", true, 99, 2, calendar::turn );
88+
check_effect_init( "bite", 30_minutes, 30_minutes, "torso", true, 99, 1, calendar::turn );
89+
check_effect_init( "grabbed", 1_turns, 1_turns, "arm_r", false, 100, 100,
90+
calendar::turn + 1_hours );
91+
check_effect_init( "grabbed", 100_turns, 100_turns, "arm_r", false, 1, 1,
92+
calendar::turn + 1_hours );
93+
check_effect_init( "grabbed", 1_turns, 1_turns, "arm_r", false, 10, 10, calendar::turn + 1_hours );
8394
}
8495

8596
// Effect duration

0 commit comments

Comments
 (0)