From ac61da2e17b19a8f5011b78d7ca0eef7ac290646 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Fri, 22 May 2020 11:48:48 -0400 Subject: [PATCH] Fix issue with auto_aim (#40662) --- src/avatar_action.cpp | 2 +- src/character.cpp | 14 +++++++++----- src/character.h | 2 +- src/ranged.cpp | 4 +--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index c6509e4260656..86c0194023c4b 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -609,7 +609,7 @@ static float rate_critter( const Creature &c ) void avatar_action::autoattack( avatar &you, map &m ) { int reach = you.weapon.reach_range( you ); - std::vector critters = you.get_targetable_creatures( reach ); + std::vector critters = you.get_targetable_creatures( reach, true ); critters.erase( std::remove_if( critters.begin(), critters.end(), []( const Creature * c ) { if( !c->is_npc() ) { return false; diff --git a/src/character.cpp b/src/character.cpp index 782b442a77806..02ef0429bb365 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -10498,15 +10498,19 @@ std::vector Character::get_visible_creatures( const int range ) cons } ); } -std::vector Character::get_targetable_creatures( const int range ) const +std::vector Character::get_targetable_creatures( const int range, bool melee ) const { - return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool { - bool can_see = sees( critter ) || sees_with_infrared( critter ); - if( can_see ) //handles the case where we can see something with glass in the way or a mutation lets us see through walls + return g->get_creatures_if( [this, range, melee]( const Creature & critter ) -> bool { + //the call to map.sees is to make sure that even if we can see it through walls + //via a mutation or cbm we only attack targets with a line of sight + bool can_see = ( ( sees( critter ) || sees_with_infrared( critter ) ) && g->m.sees( pos(), critter.pos(), 100 ) ); + if( can_see && melee ) //handles the case where we can see something with glass in the way for melee attacks { std::vector path = g->m.find_clear_path( pos(), critter.pos() ); for( const tripoint &point : path ) { - if( g->m.impassable( point ) ) { + if( g->m.impassable( point ) && + !( weapon.has_flag( "SPEAR" ) && // Fences etc. Spears can stab through those + g->m.has_flag( "THIN_OBSTACLE", point ) ) ) { //this mirrors melee.cpp function reach_attack can_see = false; break; } diff --git a/src/character.h b/src/character.h index 876e3319cae69..82ede2309f612 100644 --- a/src/character.h +++ b/src/character.h @@ -1895,7 +1895,7 @@ class Character : public Creature, public visitable * As above, but includes all creatures the player can detect well enough to target * with ranged weapons, e.g. with infrared vision. */ - std::vector get_targetable_creatures( int range ) const; + std::vector get_targetable_creatures( int range, bool melee ) const; /** Returns an enumeration of visible mutations with colors */ std::string visible_mutations( int visibility_cap ) const; player_activity get_destination_activity() const; diff --git a/src/ranged.cpp b/src/ranged.cpp index f7d212e20714d..1105612368281 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -2332,9 +2332,7 @@ void target_ui::update_target_list( player &pc ) } // Get targets in range and sort them by distance (targets[0] is the closest) - // FIXME: get_targetable_creatures does not consider some of the visible creatures - // as targets (e.g. those behind fences), but you can still see and shoot them - targets = pc.get_targetable_creatures( range ); + targets = pc.get_targetable_creatures( range, mode == TargetMode::Reach ); std::sort( targets.begin(), targets.end(), [&]( const Creature * lhs, const Creature * rhs ) { return rl_dist_exact( lhs->pos(), pc.pos() ) < rl_dist_exact( rhs->pos(), pc.pos() ); } );