sfx::sound_thread::sound_thread( const tripoint &source, const tripoint &target, const bool hit, const bool targ_mon, const std::string &material ) : hit( hit ) , targ_mon( targ_mon ) , material( material ) { // This is function is run in the main thread. const int heard_volume = get_heard_volume( source ); const player *p; int npc_index = g->npc_at( source ); if( npc_index == -1 ) { p = &g->u; // sound comes from the same place as the player is, calculation of angle wouldn't work ang_src = 0; vol_src = heard_volume; vol_targ = heard_volume; } else { p = g->active_npc[npc_index]; ang_src = get_heard_angle( source ); vol_src = std::max(heard_volume - 30, 0); vol_targ = std::max(heard_volume - 20, 0); } ang_targ = get_heard_angle( target ); weapon_skill = p->weapon.melee_skill(); weapon_volume = p->weapon.volume() / units::legacy_volume_factor; }
void sfx::do_projectile_hit( const Creature &target ) { const int heard_volume = sfx::get_heard_volume( target.pos() ); const int angle = get_heard_angle( target.pos() ); if( target.is_monster() ) { const monster &mon = dynamic_cast<const monster &>( target ); static std::set<material_id> const fleshy = { material_id( "flesh" ), material_id( "hflesh" ), material_id( "iflesh" ), material_id( "veggy" ), material_id( "bone" ), }; const bool is_fleshy = std::any_of( fleshy.begin(), fleshy.end(), [&mon]( const material_id &m ) { return mon.made_of( m ); } ); if( is_fleshy ) { play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); return; } else if( mon.made_of( material_id( "stone" ) ) ) { play_variant_sound( "bullet_hit", "hit_wall", heard_volume, angle, 0.8, 1.2 ); return; } else if( mon.made_of( material_id( "steel" ) ) ) { play_variant_sound( "bullet_hit", "hit_metal", heard_volume, angle, 0.8, 1.2 ); return; } else { play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); return; } } play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); }
void sfx::do_projectile_hit( const Creature &target ) { const int heard_volume = sfx::get_heard_volume( target.pos() ); const int angle = get_heard_angle( target.pos() ); if( target.is_monster() ) { const monster &mon = dynamic_cast<const monster &>( target ); const auto material = mon.get_material(); static std::set<mat_type> const fleshy = { mat_type( "flesh" ), mat_type( "hflesh" ), mat_type( "iflesh" ), mat_type( "veggy" ), mat_type( "bone" ), mat_type( "protoplasmic" ), }; if( fleshy.count( material ) > 0 || mon.has_flag( MF_VERMIN ) ) { play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); return; } else if( material == "stone" ) { play_variant_sound( "bullet_hit", "hit_wall", heard_volume, angle, 0.8, 1.2 ); return; } else if( material == "steel" ) { play_variant_sound( "bullet_hit", "hit_metal", heard_volume, angle, 0.8, 1.2 ); return; } else { play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); return; } } play_variant_sound( "bullet_hit", "hit_flesh", heard_volume, angle, 0.8, 1.2 ); }
// firing is the item that is fired. It may be the wielded gun, but it can also be an attached // gunmod. p is the character that is firing, this may be a pseudo-character (used by monattack/ // vehicle turrets) or a NPC. void sfx::generate_gun_sound( const player &p, const item &firing ) { end_sfx_timestamp = std::chrono::high_resolution_clock::now(); sfx_time = end_sfx_timestamp - start_sfx_timestamp; if( std::chrono::duration_cast<std::chrono::milliseconds> ( sfx_time ).count() < 80 ) { return; } const tripoint source = p.pos(); int heard_volume = get_heard_volume( source ); if( heard_volume <= 30 ) { heard_volume = 30; } itype_id weapon_id = firing.typeId(); int angle; int distance; std::string selected_sound; // this does not mean p == g->u (it could be a vehicle turret) if( g->u.pos() == source ) { angle = 0; distance = 0; selected_sound = "fire_gun"; const auto mods = firing.gunmods(); if( std::any_of( mods.begin(), mods.end(), []( const item *e ) { return e->type->gunmod->loudness < 0; } ) ) { weapon_id = "weapon_fire_suppressed"; } } else { angle = get_heard_angle( source ); distance = rl_dist( g->u.pos(), source ); if( distance <= 17 ) { selected_sound = "fire_gun"; } else { selected_sound = "fire_gun_distant"; } } play_variant_sound( selected_sound, weapon_id, heard_volume, angle, 0.8, 1.2 ); start_sfx_timestamp = std::chrono::high_resolution_clock::now(); }