@@ -2723,6 +2723,46 @@ int Character::attack_speed( const item &weap ) const
2723
2723
return std::round ( move_cost );
2724
2724
}
2725
2725
2726
+ double Character::evaluate_weapon ( const item &maybe_weapon ) const
2727
+ {
2728
+ bool can_use_gun = true ;
2729
+ bool use_silent = false ;
2730
+ const npc *me_as_npc = dynamic_cast <const npc *>( this );
2731
+ if ( me_as_npc ) {
2732
+ if ( me_as_npc->is_player_ally () && !me_as_npc->rules .has_flag ( ally_rule::use_guns ) ) {
2733
+ can_use_gun = false ;
2734
+ }
2735
+ if ( me_as_npc->is_player_ally () && me_as_npc->rules .has_flag ( ally_rule::use_silent ) ) {
2736
+ use_silent = true ;
2737
+ }
2738
+ }
2739
+ return evaluate_weapon_internal ( maybe_weapon, can_use_gun, use_silent );
2740
+ }
2741
+
2742
+ double Character::evaluate_weapon_internal ( const item &maybe_weapon, bool can_use_gun,
2743
+ bool use_silent ) const
2744
+ {
2745
+ // Needed because evaluation includes electricity via linked cables.
2746
+ const map &here = get_map ();
2747
+
2748
+ bool allowed = can_use_gun && maybe_weapon.is_gun () && ( !use_silent || maybe_weapon.is_silent () );
2749
+ // According to unmodified evaluation score, NPCs almost always prioritize wielding guns if they have one.
2750
+ // This is relatively reasonable, as players can issue commands to NPCs when we do not want them to use ranged weapons.
2751
+ // Conversely, we cannot directly issue commands when we want NPCs to prioritize ranged weapons.
2752
+ // Note that the scoring method here is different from the 'weapon_value' used elsewhere.
2753
+ double val_gun = allowed ? gun_value ( maybe_weapon, maybe_weapon.shots_remaining ( here,
2754
+ this ) ) : 0 ;
2755
+ add_msg_debug ( debugmode::DF_NPC_ITEMAI,
2756
+ " %s %s valued at <color_light_cyan>%1.2f as a ranged weapon to wield</color>." ,
2757
+ disp_name ( true ), maybe_weapon.type ->get_id ().str (), val_gun );
2758
+ double val_melee = melee_value ( maybe_weapon );
2759
+ add_msg_debug ( debugmode::DF_NPC_ITEMAI,
2760
+ " %s %s valued at <color_light_cyan>%1.2f as a melee weapon to wield</color>." , disp_name ( true ),
2761
+ maybe_weapon.type ->get_id ().str (), val_melee );
2762
+ double val = std::max ( val_gun, val_melee );
2763
+ return val;
2764
+ }
2765
+
2726
2766
double Character::weapon_value ( const item &weap, int ammo ) const
2727
2767
{
2728
2768
if ( is_wielding ( weap ) || ( !get_wielded_item () && weap.is_null () ) ) {
0 commit comments