void sounds::process_sounds() { std::vector<centroid> sound_clusters = cluster_sounds( recent_sounds ); const int weather_vol = weather_data( g->weather ).sound_attn; for( const auto &this_centroid : sound_clusters ) { // Since monsters don't go deaf ATM we can just use the weather modified volume // If they later get physical effects from loud noises we'll have to change this // to use the unmodified volume for those effects. const int vol = this_centroid.volume - weather_vol; const tripoint source = tripoint( this_centroid.x, this_centroid.y, this_centroid.z ); // --- Monster sound handling here --- // Alert all hordes if( vol > 20 && g->get_levz() == 0 ) { int sig_power = ( ( vol > 140 ) ? 140 : vol ); // With this, volume 100 reaches 20 overmap tiles away. sig_power /= 5; const point abs_ms = g->m.getabs( source.x, source.y ); const point abs_sm = ms_to_sm_copy( abs_ms ); const tripoint target( abs_sm.x, abs_sm.y, source.z ); overmap_buffer.signal_hordes( target, sig_power ); } // Alert all monsters (that can hear) to the sound. for (int i = 0, numz = g->num_zombies(); i < numz; i++) { monster &critter = g->zombie(i); const int dist = rl_dist( source, critter.pos() ); if( vol * 2 > dist ) { // Exclude monsters that certainly won't hear the sound critter.hear_sound( source, vol, dist ); } } } recent_sounds.clear(); }
void sounds::process_sounds() { std::vector<centroid> sound_clusters = cluster_sounds( recent_sounds ); const int weather_vol = weather_data(g->weather).sound_attn; for( const auto &this_centroid : sound_clusters ) { // Since monsters don't go deaf ATM we can just use the weather modified volume // If they later get physical effects from loud noises we'll have to change this // to use the unmodified volume for those effects. const int vol = this_centroid.volume - weather_vol; const tripoint source = tripoint( this_centroid.x, this_centroid.y, this_centroid.z ); // --- Monster sound handling here --- // Alert all hordes if( vol > 20 && g->get_levz() == 0 ) { int sig_power = ((vol > 140) ? 140 : vol) - 20; const point abs_ms = g->m.getabs( source.x, source.y ); const point abs_sm = overmapbuffer::ms_to_sm_copy( abs_ms ); const tripoint target( abs_sm.x, abs_sm.y, source.z ); overmap_buffer.signal_hordes( target, sig_power ); } // Alert all monsters (that can hear) to the sound. for (int i = 0, numz = g->num_zombies(); i < numz; i++) { monster &critter = g->zombie(i); // rl_dist() is faster than critter.has_flag() or critter.can_hear(), so we'll check it first. int dist = rl_dist( source, critter.pos3() ); int vol_goodhearing = vol * 2 - dist; if (vol_goodhearing > 0 && critter.can_hear()) { const bool goodhearing = critter.has_flag(MF_GOODHEARING); int volume = goodhearing ? vol_goodhearing : (vol - dist); // Error is based on volume, louder sound = less error if (volume > 0) { int max_error = 0; if (volume < 2) { max_error = 10; } else if (volume < 5) { max_error = 5; } else if (volume < 10) { max_error = 3; } else if (volume < 20) { max_error = 1; } int target_x = source.x + rng(-max_error, max_error); int target_y = source.y + rng(-max_error, max_error); // target_z will require some special check due to soil muffling sounds int wander_turns = volume * (goodhearing ? 6 : 1); critter.wander_to( tripoint( target_x, target_y, source.z ), wander_turns); critter.process_trigger(MTRIG_SOUND, volume); } } } } recent_sounds.clear(); }
void sounds::draw_monster_sounds( const tripoint &offset, WINDOW *window ) { auto sound_clusters = cluster_sounds( recent_sounds ); // TODO: Signal sounds on different Z-levels differently (with '^' and 'v'?) for( const auto &sound : recent_sounds ) { mvwputch( window, offset.y + sound.first.y, offset.x + sound.first.x, c_yellow, '?' ); } for( const auto &sound : sound_clusters ) { mvwputch( window, offset.y + sound.y, offset.x + sound.x, c_red, '?' ); } }
std::pair<std::vector<tripoint>, std::vector<tripoint>> sounds::get_monster_sounds() { auto sound_clusters = cluster_sounds( recent_sounds ); std::vector<tripoint> sound_locations; sound_locations.reserve( recent_sounds.size() ); for( const auto &sound : recent_sounds ) { sound_locations.push_back( sound.first ); } std::vector<tripoint> cluster_centroids; cluster_centroids.reserve( sound_clusters.size() ); for( const auto &sound : sound_clusters ) { cluster_centroids.emplace_back( sound.x, sound.y, sound.z ); } return { sound_locations, cluster_centroids }; }