diff --git a/src/bionics.cpp b/src/bionics.cpp index 9d52031247cba..6de4a9cbd7926 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -2569,6 +2569,8 @@ void load_bionic( const JsonObject &jsobj ) new_bionic.weight_capacity_modifier = jsobj.get_float( "weight_capacity_modifier", 1.0 ); + assign( jsobj, "enchantments", new_bionic.enchantments ); + assign( jsobj, "weight_capacity_bonus", new_bionic.weight_capacity_bonus, false, 0_gram ); assign( jsobj, "exothermic_power_gen", new_bionic.exothermic_power_gen ); assign( jsobj, "power_gen_emission", new_bionic.power_gen_emission ); @@ -2638,6 +2640,11 @@ void check_bionics() bio.first.c_str(), mid.c_str() ); } } + for( const enchantment_id &eid : bio.first->enchantments ) { + if( !eid.is_valid() ) { + debugmsg( "Bionic %s uses undefined enchantment %s", bio.first.c_str(), eid.c_str() ); + } + } for( const bionic_id &bid : bio.second.included_bionics ) { if( !bid.is_valid() ) { debugmsg( "Bionic %s includes undefined bionic %s", diff --git a/src/bionics.h b/src/bionics.h index 8df7196e9e5de..050ee104227bd 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -109,6 +109,9 @@ struct bionic_data { /**Amount of cut protection offered by this bionic*/ std::map cut_protec; + /** bionic enchantments */ + std::vector enchantments; + /** * Body part slots used to install this bionic, mapped to the amount of space required. */ diff --git a/src/character.cpp b/src/character.cpp index 8c868ae44fd8c..97bd446838efb 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1544,6 +1544,8 @@ void Character::process_turn() } } + enchantment_cache.activate_passive( *this ); + Creature::process_turn(); } @@ -7945,6 +7947,20 @@ void Character::recalculate_enchantment_cache() } } } + + for( const bionic &bio : *my_bionics ) { + const bionic_id &bid = bio.id; + if( bid->toggled && !bio.powered ) { + continue; + } + + for( const enchantment_id &ench_id : bid->enchantments ) { + const enchantment &ench = ench_id.obj(); + if( ench.is_active( *this ) ) { + enchantment_cache.force_add( ench ); + } + } + } } double Character::calculate_by_enchantment( double modify, enchantment::mod value, diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index bbe8cddd75be6..bea03daec3878 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -240,6 +240,10 @@ void enchantment::load( const JsonObject &jo, const std::string & ) active_conditions.second = io::string_to_enum( jo.get_string( "condition", "ALWAYS" ) ); + for( JsonObject jsobj : jo.get_array( "ench_effects" ) ) { + ench_effects.emplace( jsobj.get_string( "effect" ), jsobj.get_int( "intensity" ) ); + } + if( jo.has_array( "values" ) ) { for( const JsonObject value_obj : jo.get_array( "values" ) ) { const enchantment::mod value = io::string_to_enum( value_obj.get_string( "value" ) ); @@ -399,6 +403,9 @@ void enchantment::activate_passive( Character &guy ) const if( emitter ) { g->m.emit_field( guy.pos(), *emitter ); } + for( const std::pair eff : ench_effects ) { + guy.add_effect( eff.first, 1_seconds, num_bp, false, eff.second ); + } for( const std::pair> &activation : intermittent_activation ) { // a random approximation! diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index 7d3e1bb3ff372..94e004bc707b8 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -146,6 +146,7 @@ class enchantment void cast_hit_me( Character &caster, const Creature *target ) const; private: cata::optional emitter; + std::map ench_effects; // values that add to the base value std::map values_add; // values that get multiplied to the base value