diff --git a/src/magic.cpp b/src/magic.cpp index f0fd47bea7829..e64921c4aadc4 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -1343,6 +1343,12 @@ float spell::spell_fail( const Character &guy ) const if( has_flag( spell_flag::NO_FAIL ) ) { return 0.0f; } + if( type->magic_type.has_value() && + type->magic_type.value()->failure_chance_formula_id.has_value() ) { + const_dialogue d( get_const_talker_for( guy ), nullptr ); + return type->magic_type.value()->failure_chance_formula_id.value()->eval( d ); + } + const bool is_psi = has_flag( spell_flag::PSIONIC ); // formula is based on the following: diff --git a/src/magic_type.cpp b/src/magic_type.cpp index 4d95b6330257f..a001d9feade03 100644 --- a/src/magic_type.cpp +++ b/src/magic_type.cpp @@ -44,6 +44,7 @@ void magic_type::load( const JsonObject &jo, const std::string_view src ) id.c_str() ); } optional( jo, was_loaded, "casting_xp_formula_id", casting_xp_formula_id ); + optional( jo, was_loaded, "failure_chance_formula_id", failure_chance_formula_id ); optional( jo, was_loaded, "energy_source", energy_source ); if( jo.has_array( "cannot_cast_flags" ) ) { for( auto &cannot_cast_flag : jo.get_string_array( "cannot_cast_flags" ) ) { @@ -80,6 +81,7 @@ void magic_type::serialize( JsonOut &json ) const json.member( "get_level_formula_id", get_level_formula_id ); json.member( "exp_for_level_formula_id", exp_for_level_formula_id ); json.member( "casting_xp_formula_id", casting_xp_formula_id ); + json.member( "failure_chance_formula_id", failure_chance_formula_id ); json.member( "energy_source", energy_source ); json.member( "cannot_cast_flags", cannot_cast_flags, std::set {} ); json.member( "cannot_cast_message", cannot_cast_message ); @@ -106,6 +108,10 @@ void magic_type::check_consistency() if( m_t.casting_xp_formula_id.has_value() && m_t.casting_xp_formula_id.value()->num_params != 0 ) { debugmsg( "ERROR: %s casting_xp_formula_id has params that != 0!", m_t.id.c_str() ); } + if( m_t.failure_chance_formula_id.has_value() && + m_t.failure_chance_formula_id.value()->num_params != 0 ) { + debugmsg( "ERROR: %s failure_chance_formula_id has params that != 0!", m_t.id.c_str() ); + } } } diff --git a/src/magic_type.h b/src/magic_type.h index 02b7280b5880e..bff85b5caee00 100644 --- a/src/magic_type.h +++ b/src/magic_type.h @@ -45,6 +45,7 @@ class magic_type std::optional exp_for_level_formula_id; std::optional casting_xp_formula_id; + std::optional failure_chance_formula_id; std::optional energy_source; std::set cannot_cast_flags; // string flags std::optional cannot_cast_message; diff --git a/src/npc.cpp b/src/npc.cpp index e6c8ec8768a5c..ad5c32765a3ff 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -3976,3 +3976,5 @@ std::unique_ptr get_talker_for( npc *guy ) { return std::make_unique( guy ); } + +