From ab5a6dfd6eb3cba3e9457cfe80ece03b8342514a Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:28:55 +0200 Subject: [PATCH 1/4] add enchantment for range dodges --- doc/MAGIC.md | 1 + src/creature.cpp | 6 ++++++ src/magic_enchantment.cpp | 1 + src/magic_enchantment.h | 1 + 4 files changed, 9 insertions(+) diff --git a/doc/MAGIC.md b/doc/MAGIC.md index e7486a851b94c..06ca89ec98476 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -878,6 +878,7 @@ Character status value | Description `POWER_TRICKLE` | Generates this amount of millijoules each second. Default value is zero, so better to use `add` `RANGE` | Modifies your characters range with firearms `RANGED_DAMAGE` | Adds damage to ranged attacks. +`RANGE_DODGE` | Chance to dodge projectile attack, no matter of it's speed; Consumes dodges similarly to melee dodges, and fails, if character has no dodges left. `add` and `multiply` behave equally. `add: 0.5` would result in 50% chance to avoid projectile `READING_EXP` | Changes the minimum you learn from each reading increment. `READING_SPEED_MULTIPLIER` | Changes how fast you can read books; Lesser value means faster book reading, with cap of 1 second. `RECOIL_MODIFIER` | Affects recoil when shooting a gun. Positive value increase the dispersion, negative decrease one. diff --git a/src/creature.cpp b/src/creature.cpp index 440b023756b80..b00c36879488a 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1243,6 +1243,12 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack on_try_dodge(); // There's a dodge roll in accuracy_projectile_attack() } + // Supernatural dodges + double range_dodge_chance = enchantment_cache->modify_value( enchant_vals::mod::RANGE_DODGE, 1 ) - 1.0f; + if ( x_in_y( range_dodge_chance, 1.0f ) ) { + on_try_dodge(); + } + if( goodhit >= 1.0 && !magic ) { attack.missed_by = 1.0; // Arbitrary value if( !print_messages ) { diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index 5baf8e186c28f..0b13714a8279a 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -76,6 +76,7 @@ namespace io case enchant_vals::mod::REGEN_HP: return "REGEN_HP"; case enchant_vals::mod::REGEN_HP_AWAKE: return "REGEN_HP_AWAKE"; case enchant_vals::mod::MUT_INSTABILITY_MOD: return "MUT_INSTABILITY_MOD"; + case enchant_vals::mod::RANGE_DODGE: return "RANGE_DODGE"; case enchant_vals::mod::HUNGER: return "HUNGER"; case enchant_vals::mod::THIRST: return "THIRST"; case enchant_vals::mod::SLEEPINESS: return "SLEEPINESS"; diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index bf6bd747e3dda..a9cb95f5d88af 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -49,6 +49,7 @@ enum class mod : int { FAT_TO_MAX_HP, CARDIO_MULTIPLIER, MUT_INSTABILITY_MOD, + RANGE_DODGE, MAX_HP, // for all limbs! use with caution REGEN_HP, REGEN_HP_AWAKE, From fef783fced32a081f188ba0fa599c24d4e96f266 Mon Sep 17 00:00:00 2001 From: GuardianDll Date: Mon, 26 Aug 2024 19:39:12 +0200 Subject: [PATCH 2/4] move message about avoiding into it's own function, make the code use character to apply enchantment properly --- src/creature.cpp | 48 +++++++++++++++++++++++++++++------------------- src/creature.h | 1 + 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/creature.cpp b/src/creature.cpp index b00c36879488a..7368538f114ed 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1203,6 +1203,25 @@ void Creature::messaging_projectile_attack( const Creature *source, } } +void Creature::print_proj_avoid_msg( Creature *source, viewer &player_view ) +{ + // "Avoid" rather than "dodge", because it includes removing self from the line of fire + // rather than just Matrix-style bullet dodging + if( source != nullptr && player_view.sees( *source ) ) { + add_msg_player_or_npc( + m_warning, + _( "You avoid %s projectile!" ), + get_option( "LOG_MONSTER_ATTACK_MONSTER" ) ? _( " avoids %s projectile." ) : "", + source->disp_name( true ) ); + } else { + add_msg_player_or_npc( + m_warning, + _( "You avoid an incoming projectile!" ), + get_option( "LOG_MONSTER_ATTACK_MONSTER" ) ? _( " avoids an incoming projectile." ) : + "" ); + } +} + /** * Attempts to harm a creature with a projectile. * @@ -1243,10 +1262,15 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack on_try_dodge(); // There's a dodge roll in accuracy_projectile_attack() } - // Supernatural dodges - double range_dodge_chance = enchantment_cache->modify_value( enchant_vals::mod::RANGE_DODGE, 1 ) - 1.0f; - if ( x_in_y( range_dodge_chance, 1.0f ) ) { - on_try_dodge(); + Character *guy = as_character(); + if( guy ) { + double range_dodge_chance = guy->enchantment_cache->modify_value( enchant_vals::mod::RANGE_DODGE, + 1.0f ) - 1.0f; + if( x_in_y( range_dodge_chance, 1.0f ) ) { + on_try_dodge(); + print_proj_avoid_msg( source, player_view ); + return; + } } if( goodhit >= 1.0 && !magic ) { @@ -1254,21 +1278,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack if( !print_messages ) { return; } - // "Avoid" rather than "dodge", because it includes removing self from the line of fire - // rather than just Matrix-style bullet dodging - if( source != nullptr && player_view.sees( *source ) ) { - add_msg_player_or_npc( - m_warning, - _( "You avoid %s projectile!" ), - get_option( "LOG_MONSTER_ATTACK_MONSTER" ) ? _( " avoids %s projectile." ) : "", - source->disp_name( true ) ); - } else { - add_msg_player_or_npc( - m_warning, - _( "You avoid an incoming projectile!" ), - get_option( "LOG_MONSTER_ATTACK_MONSTER" ) ? _( " avoids an incoming projectile." ) : - "" ); - } + print_proj_avoid_msg( source, player_view ); return; } diff --git a/src/creature.h b/src/creature.h index de1f3678db319..e898df989b282 100644 --- a/src/creature.h +++ b/src/creature.h @@ -1343,6 +1343,7 @@ class Creature : public viewer // do messaging and SCT for projectile hit void messaging_projectile_attack( const Creature *source, const projectile_attack_results &hit_selection, int total_damage ) const; + void print_proj_avoid_msg( Creature *source, viewer &player_view ); }; std::unique_ptr get_talker_for( Creature &me ); std::unique_ptr get_talker_for( const Creature &me ); From 1805b37df92e791cdda57cc800815818f6966c81 Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Thu, 29 Aug 2024 08:38:28 +0200 Subject: [PATCH 3/4] make print_proj_avoid_msg const, as clang-tidy suggests --- src/creature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/creature.h b/src/creature.h index e898df989b282..13d89c261cb95 100644 --- a/src/creature.h +++ b/src/creature.h @@ -1343,7 +1343,7 @@ class Creature : public viewer // do messaging and SCT for projectile hit void messaging_projectile_attack( const Creature *source, const projectile_attack_results &hit_selection, int total_damage ) const; - void print_proj_avoid_msg( Creature *source, viewer &player_view ); + void print_proj_avoid_msg( Creature *source, viewer &player_view ) const; }; std::unique_ptr get_talker_for( Creature &me ); std::unique_ptr get_talker_for( const Creature &me ); From 7076ef523af0204672335e1bda8244e9e2457705 Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:37:51 +0200 Subject: [PATCH 4/4] make print_proj_avoid_msg const again --- src/creature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/creature.cpp b/src/creature.cpp index 7368538f114ed..cfdcc1770c099 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1203,7 +1203,7 @@ void Creature::messaging_projectile_attack( const Creature *source, } } -void Creature::print_proj_avoid_msg( Creature *source, viewer &player_view ) +void Creature::print_proj_avoid_msg( Creature *source, viewer &player_view ) const { // "Avoid" rather than "dodge", because it includes removing self from the line of fire // rather than just Matrix-style bullet dodging