Skip to content

Commit

Permalink
Regeneration Modifier Rework (#1619)
Browse files Browse the repository at this point in the history
* Rework Start

* Update numbers to function right

* Styling

* Styling json

* Documentation/fixes

* Update monster.cpp

* Fixes

* Bugfix

* Trying out new things.

* Overload

Update

* Pls Work

* Update regen messages to only when seen.

* Const Remove

* That ternary operator shouldn't be needed

Co-authored-by: Coolthulhu <[email protected]>
  • Loading branch information
2 people authored and joveeater committed Jul 10, 2022
1 parent fa8d78c commit e529ad7
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 23 deletions.
2 changes: 1 addition & 1 deletion data/json/monsters/mammal.json
Original file line number Diff line number Diff line change
Expand Up @@ -1848,7 +1848,7 @@
"fear_triggers": [ "FIRE" ],
"death_function": [ "NORMAL" ],
"regenerates": 10,
"regeneration_modifiers": [ [ "onfire", -0.5 ], [ "corroding", -0.4 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -0.3, "scaling_mod": -0.1 }, { "effect": "corroding", "base_mod": -0.4 } ],
"regen_morale": true,
"flags": [ "ATTACKMON", "BLEED", "BORES", "CAN_DIG", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SMELLS", "WARM" ],
"//": "Reinsert GOODHEARING when z-level tunneling is possible."
Expand Down
2 changes: 1 addition & 1 deletion data/json/monsters/misc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"harvest": "exempt",
"death_function": [ "MELT" ],
"regenerates": 50,
"regeneration_modifiers": [ [ "onfire", -0.5 ], [ "corroding", -0.8 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -0.3, "scaling_mod": -0.15 }, { "effect": "corroding", "base_mod": -0.8 } ],
"flags": [ "IMMOBILE", "NOT_HALLUCINATION", "FILTHY" ]
},
{
Expand Down
4 changes: 2 additions & 2 deletions data/json/monsters/mutant_human.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"death_drops": "mon_mutant_experimental_death_drops",
"upgrades": { "half_life": 50, "into": "mon_mutant_evolved" },
"regenerates": 1,
"regeneration_modifiers": [ [ "onfire", -1.0 ], [ "corroding", -1.0 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -1.0 }, { "effect": "corroding", "base_mod": -1.0 } ],
"regen_morale": true,
"flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "WARM", "BLEED", "BASHES", "PATH_AVOID_DANGER_2" ]
},
Expand Down Expand Up @@ -113,7 +113,7 @@
],
"death_drops": "mon_mutant_evolved_death_drops",
"regenerates": 1,
"regeneration_modifiers": [ [ "onfire", -1.0 ], [ "corroding", -1.0 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -1.0 }, { "effect": "corroding", "base_mod": -1.0 } ],
"regen_morale": true,
"flags": [
"SEES",
Expand Down
2 changes: 1 addition & 1 deletion data/json/monsters/nether.json
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@
"special_attacks": [ [ "PARROT", 40 ] ],
"death_function": [ "MELT" ],
"regenerates": 50,
"regeneration_modifiers": [ [ "onfire", -0.5 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -0.3, "scaling_mod": -0.15 } ],
"regen_morale": true,
"flags": [ "SEES", "SMELLS", "SWIMS", "PLASTIC", "SLUDGEPROOF", "ACID_BLOOD", "ACIDPROOF", "NOHEAD", "ABSORBS_SPLITS", "NOGIB" ]
},
Expand Down
2 changes: 1 addition & 1 deletion data/json/monsters/slugs.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"harvest": "exempt",
"death_function": [ "MELT" ],
"regenerates": 50,
"regeneration_modifiers": [ [ "onfire", -0.6 ], [ "corroding", -0.3 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -0.3, "scaling_mod": -0.2 }, { "effect": "corroding", "base_mod": -0.3 } ],
"flags": [ "NOHEAD", "SEES", "POISON", "HEARS", "SMELLS", "SLUDGEPROOF", "SLUDGETRAIL", "SWIMS", "FLAMMABLE", "NOGIB" ]
},
{
Expand Down
2 changes: 1 addition & 1 deletion data/json/monsters/zed_fusion.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"death_function": [ "NORMAL" ],
"regenerates": 1,
"regeneration_modifiers": [ [ "onfire", -1 ], [ "corroding", -1 ] ],
"regeneration_modifiers": [ { "effect": "onfire", "base_mod": -1.0 }, { "effect": "corroding", "base_mod": -1.0 } ],
"flags": [
"SEES",
"HEARS",
Expand Down
7 changes: 7 additions & 0 deletions doc/MONSTERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,13 @@ What field the monster emits and how often it does so. Time duration can use str

Number of hitpoints regenerated per turn.

## "regeneration_modifiers"
( array of objects consisting of effect, base_mod (float) and scaling_mod (float), optional )
"regeneration_modifiers": [ { "effect": "on_fire", "base_mod": -0.3, "scaling_mod": -0.15 } ],

What effects (if any) affect the monster's regeneration positively/negatively.
The mods stack additively (Intensity 2 on_fire produces a multiplier of 0.45) but are applied multiplicatively.

## "regenerates_in_dark"
(boolean, optional)

Expand Down
11 changes: 8 additions & 3 deletions src/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2530,18 +2530,23 @@ void monster::process_effects_internal()

//If this monster has the ability to heal in combat, do it now.
int regeneration_amount = type->regenerates;
float regen_multiplier = 0;
//Apply effect-triggered regeneration modifiers
for( const auto &regeneration_modifier : type->regeneration_modifiers ) {
if( has_effect( regeneration_modifier.first ) ) {
regeneration_amount *= 1 + regeneration_modifier.second;
effect &e = get_effect( regeneration_modifier.first );
regen_multiplier = 1.00 + regeneration_modifier.second.base_modifier +
( e.get_intensity() - 1 ) * regeneration_modifier.second.scale_modifier;
regeneration_amount = round( regeneration_amount * regen_multiplier );
}
}
//Prevent negative regeneration
if( regeneration_amount < 0 ) {
regeneration_amount = 0;
}
const int healed_amount = heal( regeneration_amount );
if( healed_amount > 0 && one_in( 2 ) ) {
const int healed_amount = heal( round( regeneration_amount ) );
if( healed_amount > 0 && one_in( 2 ) && g->u.sees( *this ) ) {
add_msg( m_debug, ( "Regen: %s" ), healed_amount );
std::string healing_format_string;
if( healed_amount >= 50 ) {
healing_format_string = _( "The %s is visibly regenerating!" );
Expand Down
22 changes: 11 additions & 11 deletions src/monstergenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1152,22 +1152,22 @@ void mtype::remove_special_attacks( const JsonObject &jo, const std::string &mem
}
}

void mtype::add_regeneration_modifier( JsonArray inner, const std::string & )
void mtype::add_regeneration_modifier( JsonObject inner, const std::string & )
{
const std::string effect_name = inner.get_string( 0 );
const std::string effect_name = inner.get_string( "effect" );
const efftype_id effect( effect_name );
//TODO: if invalid effect, throw error
// inner.throw_error( "Invalid regeneration_modifiers" );

if( regeneration_modifiers.count( effect ) > 0 ) {
regeneration_modifiers.erase( effect );
if( test_mode ) {
debugmsg( "%s specifies more than one regeneration modifer for effect %s, ignoring all but the last",
id.c_str(), effect_name );
}
debugmsg( "%s specifies more than one regeneration modifer for effect %s, ignoring all but the last",
id.c_str(), effect_name );
}
float amount = inner.get_float( 1 );
regeneration_modifiers.emplace( effect, amount );
const float base_mod = inner.get_float( "base_mod", 0.0f );
const float scaling_mod = inner.get_float( "scaling_mod", 0.0f );

regeneration_modifiers.emplace( effect, regen_modifier{ base_mod, scaling_mod } );
}

void mtype::add_regeneration_modifiers( const JsonObject &jo, const std::string &member,
Expand All @@ -1178,13 +1178,13 @@ void mtype::add_regeneration_modifiers( const JsonObject &jo, const std::string
}

for( const JsonValue entry : jo.get_array( member ) ) {
if( entry.test_array() ) {
add_regeneration_modifier( entry.get_array(), src );
if( entry.test_object() ) {
add_regeneration_modifier( entry.get_object(), src );
// TODO: add support for regeneration_modifer objects
//} else if ( entry.test_object() ) {
// add_regeneration_modifier( entry.get_object(), src );
} else {
entry.throw_error( "array element is not an array " );
entry.throw_error( "array element is not an object " );
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ struct mon_effect_data {
chance( nchance ), permanent( perm ) {}
};

struct regen_modifier {
float base_modifier;
float scale_modifier;
};

struct mtype {
private:
friend class MonsterGenerator;
Expand Down Expand Up @@ -229,7 +234,7 @@ struct mtype {
void remove_regeneration_modifiers( const JsonObject &jo, const std::string &member_name,
const std::string &src );

void add_regeneration_modifier( JsonArray inner, const std::string &src );
void add_regeneration_modifier( JsonObject inner, const std::string &src );

public:
mtype_id id;
Expand Down Expand Up @@ -267,7 +272,7 @@ struct mtype {
// Number of hitpoints regenerated per turn.
int regenerates = 0;
// Effects that can modify regeneration
std::map<efftype_id, float> regeneration_modifiers;
std::map<efftype_id, regen_modifier> regeneration_modifiers;
// Monster regenerates very quickly in poorly lit tiles.
bool regenerates_in_dark = false;
// Will stop fleeing if at max hp, and regen anger and morale.
Expand Down

0 comments on commit e529ad7

Please sign in to comment.