Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start zombie bash gaieties #44751

Merged
merged 4 commits into from
Jul 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/monmove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ void monster::move()
continue;
}
// Don't bash if we're just tracking a noise.
if( wander() && destination == wander_pos ) {
if( !provocative_sound && wander() && destination == wander_pos ) {
continue;
}
const int estimate = here.bash_rating( bash_estimate(), candidate );
Expand Down
13 changes: 12 additions & 1 deletion src/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2863,7 +2863,7 @@ float monster::get_mountable_weight_ratio() const
return type->mountable_weight_ratio;
}

void monster::hear_sound( const tripoint &source, const int vol, const int dist )
void monster::hear_sound( const tripoint &source, const int vol, const int dist, bool provocative )
{
if( !can_hear() ) {
return;
Expand All @@ -2876,6 +2876,12 @@ void monster::hear_sound( const tripoint &source, const int vol, const int dist
return;
}

int tmp_provocative = provocative || volume >= normal_roll( 30, 5 );
// already following a more interesting sound
if( provocative_sound && !tmp_provocative && wandf > 0 ) {
return;
}

int max_error = 0;
if( volume < 2 ) {
max_error = 10;
Expand All @@ -2892,7 +2898,12 @@ void monster::hear_sound( const tripoint &source, const int vol, const int dist
// target_z will require some special check due to soil muffling sounds

int wander_turns = volume * ( goodhearing ? 6 : 1 );
// again, already following a more interesting sound
if( wander_turns < wandf ) {
return;
}
process_trigger( mon_trigger::SOUND, volume );
provocative_sound = tmp_provocative;
if( morale >= 0 && anger >= 10 ) {
// TODO: Add a proper check for fleeing attitude
// but cache it nicely, because this part is called a lot
Expand Down
3 changes: 2 additions & 1 deletion src/monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ class monster : public Creature
* @param vol Volume at the center of the sound source
* @param distance Distance to sound source (currently just rl_dist)
*/
void hear_sound( const tripoint &source, int vol, int distance );
void hear_sound( const tripoint &source, int vol, int distance, bool provocative );

bool is_hallucination() const override; // true if the monster isn't actually real

Expand All @@ -447,6 +447,7 @@ class monster : public Creature
const std::string &npc_msg ) const override;
// TEMP VALUES
tripoint wander_pos; // Wander destination - Just try to move in that direction
bool provocative_sound = false; // Are we wandering toward something we think is alive?
int wandf = 0; // Urge to wander - Increased by sound, decrements each move
std::vector<item> inv; // Inventory
Character *mounted_player = nullptr; // player that is mounting this creature
Expand Down
2 changes: 2 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,7 @@ void monster::load( const JsonObject &data )
position.z = get_map().get_abs_sub().z;
}

data.read( "provocative_sound", provocative_sound );
data.read( "wandf", wandf );
data.read( "wandx", wander_pos.x );
data.read( "wandy", wander_pos.y );
Expand Down Expand Up @@ -2110,6 +2111,7 @@ void monster::store( JsonOut &json ) const
json.member( "wandx", wander_pos.x );
json.member( "wandy", wander_pos.y );
json.member( "wandz", wander_pos.z );
json.member( "provocative_sound", provocative_sound );
json.member( "wandf", wandf );
json.member( "hp", hp );
json.member( "special_attacks", special_attacks );
Expand Down
58 changes: 48 additions & 10 deletions src/sounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ static const itype_id fuel_type_battery( "battery" );

static const itype_id itype_weapon_fire_suppressed( "weapon_fire_suppressed" );

struct monster_sound_event {
int volume;
bool provocative;
};

struct sound_event {
int volume;
sounds::sound_t category;
Expand All @@ -99,6 +104,7 @@ struct centroid {
float z;
float volume;
float weight;
bool provocative;
};

namespace io
Expand Down Expand Up @@ -130,7 +136,7 @@ std::string enum_to_string<sounds::sound_t>( sounds::sound_t data )

// Static globals tracking sounds events of various kinds.
// The sound events since the last monster turn.
static std::vector<std::pair<tripoint, int>> recent_sounds;
static std::vector<std::pair<tripoint, monster_sound_event>> recent_sounds;
// The sound events since the last interactive player turn. (doesn't count sleep etc)
static std::vector<std::pair<tripoint, sound_event>> sounds_since_last_turn;
// The sound events currently displayed to the player.
Expand Down Expand Up @@ -160,6 +166,30 @@ static int sound_distance( const tripoint &source, const tripoint &sink )
return rl_dist( source.xy(), sink.xy() ) + vertical_attenuation;
}

static bool is_provocative( sounds::sound_t category )
{
switch( category ) {
case sounds::sound_t::background:
case sounds::sound_t::weather:
case sounds::sound_t::music:
case sounds::sound_t::activity:
case sounds::sound_t::destructive_activity:
case sounds::sound_t::alarm:
case sounds::sound_t::combat:
return false;
case sounds::sound_t::movement:
case sounds::sound_t::speech:
case sounds::sound_t::electronic_speech:
case sounds::sound_t::alert:
case sounds::sound_t::order:
return true;
case sounds::sound_t::_LAST:
break;
}
debugmsg( "Invalid sound_t category" );
abort();
}

void sounds::ambient_sound( const tripoint &p, int vol, sound_t category,
const std::string &description )
{
Expand All @@ -178,7 +208,7 @@ void sounds::sound( const tripoint &p, int vol, sound_t category, const std::str
if( description.empty() ) {
debugmsg( "Sound at %d:%d has no description!", p.x, p.y );
}
recent_sounds.emplace_back( std::make_pair( p, vol ) );
recent_sounds.emplace_back( std::make_pair( p, monster_sound_event{ vol, is_provocative( category ) } ) );
sounds_since_last_turn.emplace_back( std::make_pair( p,
sound_event {vol, category, description, ambient,
false, id, variant} ) );
Expand Down Expand Up @@ -208,7 +238,8 @@ static void vector_quick_remove( std::vector<C> &source, int index )
source.pop_back();
}

static std::vector<centroid> cluster_sounds( std::vector<std::pair<tripoint, int>> input_sounds )
static std::vector<centroid> cluster_sounds( std::vector<std::pair<tripoint, monster_sound_event>>
input_sounds )
{
// If there are too many monsters and too many noise sources (which can be monsters, go figure),
// applying sound events to monsters can dominate processing time for the whole game,
Expand All @@ -233,7 +264,8 @@ static std::vector<centroid> cluster_sounds( std::vector<std::pair<tripoint, int
{
static_cast<float>( input_sounds[index].first.x ), static_cast<float>( input_sounds[index].first.y ),
static_cast<float>( input_sounds[index].first.z ),
static_cast<float>( input_sounds[index].second ), static_cast<float>( input_sounds[index].second )
static_cast<float>( input_sounds[index].second.volume ), static_cast<float>( input_sounds[index].second.volume ),
input_sounds[index].second.provocative
} );
vector_quick_remove( input_sounds, index );
}
Expand All @@ -251,19 +283,25 @@ static std::vector<centroid> cluster_sounds( std::vector<std::pair<tripoint, int
dist_factor = dist * dist;
}
}
const float volume_sum = static_cast<float>( sound_event_pair.second ) + found_centroid->weight;
const float volume_sum = static_cast<float>( sound_event_pair.second.volume ) +
found_centroid->weight;
// Set the centroid location to the average of the two locations, weighted by volume.
found_centroid->x = static_cast<float>( ( sound_event_pair.first.x * sound_event_pair.second ) +
found_centroid->x = static_cast<float>( ( sound_event_pair.first.x *
sound_event_pair.second.volume ) +
( found_centroid->x * found_centroid->weight ) ) / volume_sum;
found_centroid->y = static_cast<float>( ( sound_event_pair.first.y * sound_event_pair.second ) +
found_centroid->y = static_cast<float>( ( sound_event_pair.first.y *
sound_event_pair.second.volume ) +
( found_centroid->y * found_centroid->weight ) ) / volume_sum;
found_centroid->z = static_cast<float>( ( sound_event_pair.first.z * sound_event_pair.second ) +
found_centroid->z = static_cast<float>( ( sound_event_pair.first.z *
sound_event_pair.second.volume ) +
( found_centroid->z * found_centroid->weight ) ) / volume_sum;
// Set the centroid volume to the larger of the volumes.
found_centroid->volume = std::max( found_centroid->volume,
static_cast<float>( sound_event_pair.second ) );
static_cast<float>( sound_event_pair.second.volume ) );
// Set the centroid weight to the sum of the weights.
found_centroid->weight = volume_sum;
// Set and keep provocative if any sound in the centroid is provocative
found_centroid->provocative |= sound_event_pair.second.provocative;
}
return sound_clusters;
}
Expand Down Expand Up @@ -320,7 +358,7 @@ void sounds::process_sounds()
const int dist = sound_distance( source, critter.pos() );
if( vol * 2 > dist ) {
// Exclude monsters that certainly won't hear the sound
critter.hear_sound( source, vol, dist );
critter.hear_sound( source, vol, dist, this_centroid.provocative );
}
}
}
Expand Down