From 19c2c67c3ad5219369bb88a4844ff5df8134cbc1 Mon Sep 17 00:00:00 2001 From: Chaosvolt Date: Mon, 23 Sep 2024 02:49:48 -0500 Subject: [PATCH] fix: AoE ammo hits NPCs once instead of spreading damage across all bodyparts (#5387) --- src/creature.cpp | 47 ---------------------------------------------- src/ranged.h | 2 -- src/ranged_aoe.cpp | 8 +++++++- 3 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/creature.cpp b/src/creature.cpp index 0f9fb5198280..06f450491d8a 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -677,53 +677,6 @@ void print_dmg_msg( Creature &target, Creature *source, const dealt_damage_insta } } -dealt_damage_instance hit_with_aoe( Creature &target, Creature *source, const damage_instance &di ) -{ - auto &all_body_parts = target.get_body(); - float hit_size_sum = std::accumulate( all_body_parts.begin(), all_body_parts.end(), 0.0f, - []( float acc, const std::pair &pr ) { - return acc + pr.first->hit_size; - } ); - dealt_damage_instance dealt_damage; - // This should be set to only body part that was damaged, or null, if not exactly one was damaged - bodypart_str_id bp_hit = bodypart_str_id::NULL_ID(); - bool hit_multiple_bps = false; - for( std::pair &pr : all_body_parts ) { - bool hit_this_bp = false; - damage_instance impact = di; - impact.mult_damage( pr.first->hit_size / hit_size_sum ); - dealt_damage_instance bp_damage = target.deal_damage( source, pr.first.id(), impact ); - for( size_t i = 0; i < dealt_damage.dealt_dams.size(); i++ ) { - dealt_damage.dealt_dams[i] += bp_damage.dealt_dams[i]; - hit_this_bp |= bp_damage.dealt_dams[i] > 0; - } - - if( !hit_multiple_bps && hit_this_bp ) { - if( !bp_hit ) { - bp_hit = pr.first; - } else { - bp_hit = bodypart_str_id::NULL_ID(); - hit_multiple_bps = true; - } - } - } - - dealt_damage.bp_hit = bp_hit->token; - if( get_player_character().sees( target ) ) { - ranged::print_dmg_msg( target, source, dealt_damage ); - } - - if( target.has_effect( effect_ridden ) ) { - monster *mons = dynamic_cast( &target ); - if( mons && mons->mounted_player && !mons->has_flag( MF_MECH_DEFENSIVE ) ) { - // TODO: Return value - hit_with_aoe( *mons->mounted_player, source, di ); - } - } - - return dealt_damage; -} - } // namespace ranged namespace diff --git a/src/ranged.h b/src/ranged.h index 58ba1f17f529..017a2cf0cb60 100644 --- a/src/ranged.h +++ b/src/ranged.h @@ -111,8 +111,6 @@ void execute_shaped_attack( const shape &sh, const projectile &proj, Creature &a std::map expected_coverage( const shape &sh, const map &here, int bash_power ); -dealt_damage_instance hit_with_aoe( Creature &target, Creature *source, const damage_instance &di ); - void draw_cone_aoe( const tripoint &origin, const std::map &aoe ); enum class hit_tier : int { diff --git a/src/ranged_aoe.cpp b/src/ranged_aoe.cpp index 6c5560262221..d74f1ac30c9d 100644 --- a/src/ranged_aoe.cpp +++ b/src/ranged_aoe.cpp @@ -5,6 +5,7 @@ #include "map_iterator.h" #include "projectile.h" #include "ranged.h" +#include "rng.h" #include "shape.h" #include "vehicle.h" #include "vehicle_part.h" @@ -122,7 +123,12 @@ void execute_shaped_attack( const shape &sh, const projectile &proj, Creature &a for( const std::pair &pr : final_coverage ) { Creature *critter = g->critter_at( pr.first ); if( critter != nullptr ) { - ranged::hit_with_aoe( *critter, &attacker, proj.impact ); + dealt_projectile_attack atk; + atk.end_point = pr.first; + atk.hit_critter = critter; + atk.proj = proj; + atk.missed_by = rng_float( 0.15, 0.45 ); + critter->deal_projectile_attack( &attacker, atk ); } } }