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

Add new safemode rule category for ignoring sounds #36786

Merged
merged 10 commits into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
101 changes: 71 additions & 30 deletions src/safemode_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in )
COLUMN_ATTITUDE,
COLUMN_PROXIMITY,
COLUMN_WHITE_BLACKLIST,
COLUMN_CATEGORY
};

std::map<int, int> column_pos;
column_pos[COLUMN_RULE] = 4;
column_pos[COLUMN_ATTITUDE] = 48;
column_pos[COLUMN_PROXIMITY] = 59;
column_pos[COLUMN_WHITE_BLACKLIST] = 66;
column_pos[COLUMN_ATTITUDE] = column_pos[COLUMN_RULE] + 38;
column_pos[COLUMN_PROXIMITY] = column_pos[COLUMN_ATTITUDE] + 10;
column_pos[COLUMN_WHITE_BLACKLIST] = column_pos[COLUMN_PROXIMITY] + 6;
column_pos[COLUMN_CATEGORY] = column_pos[COLUMN_WHITE_BLACKLIST] + 11;

const int num_columns = column_pos.size();

Expand Down Expand Up @@ -128,6 +130,7 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in )
mvwprintz( w_header, point( column_pos[COLUMN_ATTITUDE] + 2, 3 ), c_white, _( "Attitude" ) );
mvwprintz( w_header, point( column_pos[COLUMN_PROXIMITY] + 2, 3 ), c_white, _( "Dist" ) );
mvwprintz( w_header, point( column_pos[COLUMN_WHITE_BLACKLIST] + 2, 3 ), c_white, _( "B/W" ) );
mvwprintz( w_header, point( column_pos[COLUMN_CATEGORY] + 2, 3 ), c_white, _( "Cat" ) );
Ramza13 marked this conversation as resolved.
Show resolved Hide resolved

wrefresh( w_header );

Expand Down Expand Up @@ -223,9 +226,15 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in )
};

draw_column( COLUMN_RULE, ( rule.rule.empty() ) ? _( "<empty rule>" ) : rule.rule );
draw_column( COLUMN_ATTITUDE, Creature::get_attitude_ui_data( rule.attitude ).first.translated() );
draw_column( COLUMN_PROXIMITY, ( !rule.whitelist ) ? to_string( rule.proximity ) : "---" );
draw_column( COLUMN_WHITE_BLACKLIST, ( rule.whitelist ) ? _( "Whitelist" ) : _( "Blacklist" ) );
draw_column( COLUMN_ATTITUDE, ( rule.category == Categories::HOSTILE ) ?
Creature::get_attitude_ui_data( rule.attitude ).first.translated() : "---" );
draw_column( COLUMN_PROXIMITY, ( ( rule.category == Categories::HOSTILE ) ||
!rule.whitelist ) ? to_string( rule.proximity ) : "---" );
draw_column( COLUMN_WHITE_BLACKLIST,
( rule.category == Categories::HOSTILE ) ? ( rule.whitelist ) ? _( "Whitelist" ) : _( "Blacklist" )
: "---" );
draw_column( COLUMN_CATEGORY, ( rule.category == Categories::SOUND ) ? _( "Sound" ) :
_( "Hostile" ) );
}
}

Expand Down Expand Up @@ -261,12 +270,12 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in )
}
} else if( action == "ADD_DEFAULT_RULESET" ) {
changes_made = true;
current_tab.push_back( rules_class( "*", true, false, Creature::A_HOSTILE, 0 ) );
current_tab.push_back( rules_class( "*", true, false, Creature::A_HOSTILE, 0, HOSTILE ) );
line = current_tab.size() - 1;
} else if( action == "ADD_RULE" ) {
changes_made = true;
current_tab.push_back( rules_class( "", true, false, Creature::A_HOSTILE,
get_option<int>( "SAFEMODEPROXIMITY" ) ) );
get_option<int>( "SAFEMODEPROXIMITY" ), HOSTILE ) );
line = current_tab.size() - 1;
} else if( action == "REMOVE_RULE" && !current_tab.empty() ) {
changes_made = true;
Expand Down Expand Up @@ -320,6 +329,12 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in )
.query_string() );
} else if( column == COLUMN_WHITE_BLACKLIST ) {
current_tab[line].whitelist = !current_tab[line].whitelist;
} else if( column == COLUMN_CATEGORY ) {
if( current_tab[line].category == HOSTILE ) {
current_tab[line].category = SOUND;
} else if( current_tab[line].category == SOUND ) {
current_tab[line].category = HOSTILE;
}
} else if( column == COLUMN_ATTITUDE ) {
auto &attitude = current_tab[line].attitude;
switch( attitude ) {
Expand Down Expand Up @@ -514,7 +529,7 @@ void safemode::add_rule( const std::string &rule_in, const Creature::Attitude at
const rule_state state_in )
{
character_rules.push_back( rules_class( rule_in, true, ( state_in == RULE_WHITELISTED ),
attitude_in, proximity_in ) );
attitude_in, proximity_in, HOSTILE ) );
create_rules();

if( !get_option<bool>( "SAFEMODE" ) &&
Expand Down Expand Up @@ -557,8 +572,8 @@ bool safemode::empty() const

void safemode::create_rules()
{
safemode_rules.clear();

safemode_rules_hostile.clear();
safemode_rules_sound.clear();
//process include/exclude in order of rules, global first, then character specific
add_rules( global_rules );
add_rules( character_rules );
Expand All @@ -569,41 +584,51 @@ void safemode::add_rules( const std::vector<rules_class> &rules_in )
//if a specific monster is being added, all the rules need to be checked now
//may have some performance issues since exclusion needs to check all monsters also
for( auto &rule : rules_in ) {
if( !rule.whitelist ) {
//Check include patterns against all monster mtypes
for( const auto &mtype : MonsterGenerator::generator().get_all_mtypes() ) {
set_rule( rule, mtype.nname(), RULE_BLACKLISTED );
}
} else {
//exclude monsters from the existing mapping
for( const auto &safemode_rule : safemode_rules ) {
set_rule( rule, safemode_rule.first, RULE_WHITELISTED );
if( rule.category == SOUND ) {
set_rule( rule, rule.rule, RULE_WHITELISTED );
} else if( rule.category == HOSTILE ) {
if( !rule.whitelist ) {
//Check include patterns against all monster mtypes
for( const auto &mtype : MonsterGenerator::generator().get_all_mtypes() ) {
set_rule( rule, mtype.nname(), RULE_BLACKLISTED );
}
} else {
//exclude monsters from the existing mapping
for( const auto &safemode_rule : safemode_rules_hostile ) {
set_rule( rule, safemode_rule.first, RULE_WHITELISTED );
}
}
}
}
}

void safemode::set_rule( const rules_class &rule_in, const std::string &name_in, rule_state rs_in )
{
static std::vector<Creature::Attitude> attitude_any = {{Creature::A_HOSTILE, Creature::A_NEUTRAL, Creature::A_FRIENDLY}};
if( rule_in.category == HOSTILE ) {
static std::vector<Creature::Attitude> attitude_any = { {Creature::A_HOSTILE, Creature::A_NEUTRAL, Creature::A_FRIENDLY} };

if( !rule_in.rule.empty() && rule_in.active && wildcard_match( name_in, rule_in.rule ) ) {
if( rule_in.attitude == Creature::A_ANY ) {
for( auto &att : attitude_any ) {
safemode_rules[ name_in ][ att ] = rule_state_class( rs_in, rule_in.proximity );
if( !rule_in.rule.empty() && rule_in.active && wildcard_match( name_in, rule_in.rule ) ) {
if( rule_in.attitude == Creature::A_ANY ) {
for( auto &att : attitude_any ) {
safemode_rules_hostile[name_in][att] = rule_state_class( rs_in, rule_in.proximity, HOSTILE );
}
} else {
safemode_rules_hostile[name_in][rule_in.attitude] = rule_state_class( rs_in, rule_in.proximity,
HOSTILE );
}
} else {
safemode_rules[ name_in ][ rule_in.attitude ] = rule_state_class( rs_in, rule_in.proximity );
}
} else if( rule_in.category == SOUND ) {
safemode_rules_sound[name_in] = rule_state_class( rs_in, rule_in.proximity, SOUND );
}

}

rule_state safemode::check_monster( const std::string &creature_name_in,
const Creature::Attitude attitude_in,
const int proximity_in ) const
{
const auto iter = safemode_rules.find( creature_name_in );
if( iter != safemode_rules.end() ) {
const auto iter = safemode_rules_hostile.find( creature_name_in );
if( iter != safemode_rules_hostile.end() ) {
const auto &tmp = ( iter->second )[static_cast<int>( attitude_in )];
if( tmp.state == RULE_BLACKLISTED ) {
if( tmp.proximity == 0 || proximity_in <= tmp.proximity ) {
Expand All @@ -618,6 +643,19 @@ rule_state safemode::check_monster( const std::string &creature_name_in,
return RULE_NONE;
}

bool safemode::check_sound( const std::string &sound_name_in,
const int proximity_in ) const
{
for( auto &rule : safemode_rules_sound ) {
if( wildcard_match( sound_name_in, rule.first ) ) {
if( proximity_in >= rule.second.proximity ) {
return true;
}
}
};
return false;
}

void safemode::clear_character_rules()
{
character_rules.clear();
Expand Down Expand Up @@ -703,6 +741,7 @@ void safemode::serialize( JsonOut &json ) const
json.member( "whitelist", elem.whitelist );
json.member( "attitude", elem.attitude );
json.member( "proximity", elem.proximity );
json.member( "category", elem.category );

json.end_object();
}
Expand All @@ -724,9 +763,11 @@ void safemode::deserialize( JsonIn &jsin )
const bool whitelist = jo.get_bool( "whitelist" );
const Creature::Attitude attitude = static_cast<Creature::Attitude>( jo.get_int( "attitude" ) );
const int proximity = jo.get_int( "proximity" );
const Categories cat = jo.has_member( "category" ) ? static_cast<Categories>
( jo.get_int( "category" ) ) : HOSTILE;

temp_rules.push_back(
rules_class( rule, active, whitelist, attitude, proximity )
rules_class( rule, active, whitelist, attitude, proximity, cat )
);
}
}
19 changes: 14 additions & 5 deletions src/safemode_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class safemode
MAX_TAB
};

enum Categories : int {
HOSTILE,
SOUND
};

class rules_class
{
public:
Expand All @@ -30,13 +35,14 @@ class safemode
bool whitelist;
Creature::Attitude attitude;
int proximity;
Categories category;

rules_class() : active( false ), whitelist( false ), attitude( Creature::A_HOSTILE ),
proximity( 0 ) {}
proximity( 0 ), category( Categories::HOSTILE ) {}
rules_class( const std::string &rule_in, bool active_in, bool whitelist_in,
Creature::Attitude attitude_in, int proximity_in ) : rule( rule_in ),
Creature::Attitude attitude_in, int proximity_in, Categories cat ) : rule( rule_in ),
active( active_in ), whitelist( whitelist_in ),
attitude( attitude_in ), proximity( proximity_in ) {}
attitude( attitude_in ), proximity( proximity_in ), category( cat ) {}
};

class rule_state_class
Expand All @@ -46,7 +52,7 @@ class safemode
int proximity;

rule_state_class() : state( RULE_NONE ), proximity( 0 ) {}
rule_state_class( rule_state state_in, int proximity_in ) : state( state_in ),
rule_state_class( rule_state state_in, int proximity_in, Categories ) : state( state_in ),
proximity( proximity_in ) {}
};

Expand All @@ -57,7 +63,8 @@ class safemode
* is added as the key, with RULE_WHITELISTED or RULE_BLACKLISTED as the values.
* safemode_rules[ 'creature name' ][ 'attitude' ].rule_state_class('rule_state', 'proximity')
*/
std::unordered_map < std::string, std::array < rule_state_class, 3 > > safemode_rules;
std::unordered_map < std::string, std::array < rule_state_class, 3 > > safemode_rules_hostile;
std::unordered_map < std::string, rule_state_class > safemode_rules_sound;

/**
* current rules for global and character tab
Expand Down Expand Up @@ -87,6 +94,8 @@ class safemode
rule_state check_monster( const std::string &creature_name_in, Creature::Attitude attitude_in,
int proximity_in ) const;

bool check_sound( const std::string &sound_name_in, const int proximity_in ) const;

std::string npc_type_name();

void show();
Expand Down
4 changes: 3 additions & 1 deletion src/sounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "type_id.h"
#include "point.h"
#include "string_id.h"
#include "safemode_ui.h"

#if defined(SDL_SOUND)
# if defined(_MSC_VER) && defined(USE_VCPKG)
Expand Down Expand Up @@ -431,7 +432,8 @@ void sounds::process_sound_markers( player *p )

// don't print our own noise or things without descriptions
if( !sound.ambient && ( pos != p->pos() ) && !g->m.pl_sees( pos, distance_to_sound ) ) {
if( !p->activity.is_distraction_ignored( distraction_type::noise ) ) {
if( !p->activity.is_distraction_ignored( distraction_type::noise ) &&
!get_safemode().check_sound( sound.description, distance_to_sound ) ) {
const std::string query = string_format( _( "Heard %s!" ), description );
g->cancel_activity_or_ignore_query( distraction_type::noise, query );
}
Expand Down