Skip to content

Commit

Permalink
Sound-triggered traps (#68047)
Browse files Browse the repository at this point in the history
* Sound-triggered traps. Add traps to sound processing, add sound_threshold json key for traps, and add a test noise-triggered trap.

* Lint data/json/traps.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update src/sounds.cpp

Co-authored-by: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com>

* Update src/trap.h

Co-authored-by: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com>

* Add doc for new json key

* Match func def to updated func dec

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 9, 2023
1 parent 18cceb6 commit a1c4973
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 2 deletions.
12 changes: 12 additions & 0 deletions data/json/traps.json
Original file line number Diff line number Diff line change
Expand Up @@ -1155,5 +1155,17 @@
"name": "portal dungeon next level",
"copy-from": "trap_base",
"effect_str": "EOC_PORTAL_STORM_DUNGEON_NEXT_LEVEL"
},
{
"type": "trap",
"id": "tr_noisetest",
"name": "noise test trap",
"color": "light_cyan",
"symbol": "_",
"visibility": 0,
"avoidance": 8,
"difficulty": 0,
"action": "sound_detect",
"sound_threshold": 5
}
]
3 changes: 2 additions & 1 deletion doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2773,7 +2773,8 @@ See [MUTATIONS.md](MUTATIONS.md)
"spawn_items": [ "beartrap" ]
},
"trigger_message_u": "A bear trap closes on your foot!", // This message will be printed when player steps on a trap
"trigger_message_npc": "A bear trap closes on <npcname>'s foot!" // This message will be printed when NPC or monster steps on a trap
"trigger_message_npc": "A bear trap closes on <npcname>'s foot!", // This message will be printed when NPC or monster steps on a trap
"sound_threshold": 5 // Optional. Minimum volume of sound that will trigger this trap. Defaults to 0 (Will not trigger from sound).
```
### Vehicle Groups
Expand Down
11 changes: 11 additions & 0 deletions src/sounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "safemode_ui.h"
#include "string_formatter.h"
#include "translations.h"
#include "trap.h"
#include "type_id.h"
#include "uistate.h"
#include "units.h"
Expand Down Expand Up @@ -481,6 +482,16 @@ void sounds::process_sounds()
critter.hear_sound( source, vol, dist, this_centroid.provocative );
}
}
// Trigger sound-triggered traps
for( const trap *trapType : trap::get_sound_triggered_traps() ) {
for( const tripoint &tp : get_map().trap_locations( trapType->id ) ) {
const int dist = sound_distance( source, tp );
const trap &tr = get_map().tr_at( tp );
if( tr.triggered_by_sound( vol, dist ) ) {
tr.trigger( tp );
}
}
}
}
recent_sounds.clear();
}
Expand Down
31 changes: 31 additions & 0 deletions src/trap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ const std::vector<const trap *> &trap::get_funnels()
return funnel_traps;
}

static std::vector<const trap *> sound_triggered_traps;

const std::vector<const trap *> &trap::get_sound_triggered_traps()
{
return sound_triggered_traps;
}

size_t trap::count()
{
return trap_factory.size();
Expand Down Expand Up @@ -164,6 +171,7 @@ void trap::load( const JsonObject &jo, const std::string_view )
optional( jo, was_loaded, "floor_bedding_warmth", floor_bedding_warmth, 0 );
optional( jo, was_loaded, "spell_data", spell_data );
assign( jo, "trigger_weight", trigger_weight );
optional( jo, was_loaded, "sound_threshold", sound_threshold );
for( const JsonValue entry : jo.get_array( "drops" ) ) {
itype_id item_type;
int quantity = 0;
Expand Down Expand Up @@ -226,6 +234,7 @@ update_mapgen_id trap::map_regen_target() const
void trap::reset()
{
funnel_traps.clear();
sound_triggered_traps.clear();
trap_factory.reset();
}

Expand Down Expand Up @@ -307,6 +316,14 @@ bool trap::can_see( const tripoint &pos, const Character &p ) const
return visibility < 0 || p.knows_trap( pos );
}

void trap::trigger( const tripoint &pos ) const
{
if( is_null() ) {
return;
}
act( pos, nullptr, nullptr );
}

void trap::trigger( const tripoint &pos, Creature &creature ) const
{
return trigger( pos, &creature, nullptr );
Expand Down Expand Up @@ -348,6 +365,17 @@ bool trap::is_funnel() const
return !is_null() && funnel_radius_mm > 0;
}

bool trap::has_sound_trigger() const
{
return !is_null() && sound_threshold > 0;
}

bool trap::triggered_by_sound( int vol, int dist ) const
{
const int volume = vol - dist;
return !is_null() && volume >= sound_threshold;
}

void trap::on_disarmed( map &m, const tripoint &p ) const
{
for( const auto &i : components ) {
Expand Down Expand Up @@ -396,6 +424,9 @@ void trap::finalize()
if( t.is_funnel() ) {
funnel_traps.push_back( &t );
}
if( t.has_sound_trigger() ) {
sound_triggered_traps.push_back( &t );
}
}

tr_null = trap_str_id::NULL_ID().id();
Expand Down
14 changes: 14 additions & 0 deletions src/trap.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ bool map_regen( const tripoint &p, Creature *c, item *i );
bool drain( const tripoint &p, Creature *c, item *i );
bool snake( const tripoint &p, Creature *c, item *i );
bool cast_spell( const tripoint &p, Creature *critter, item * );
bool sound_detect( const tripoint &p, Creature *, item * );
} // namespace trapfunc

struct vehicle_handle_trap_data {
Expand Down Expand Up @@ -151,6 +152,10 @@ struct trap {
* If an item with this weight or more is thrown onto the trap, it triggers.
*/
units::mass trigger_weight = 500_gram;
/**
* If a sound of at least this volume reaches the trap, it triggers.
*/
int sound_threshold = 0;
int funnel_radius_mm = 0;
// For disassembly?
std::vector<std::tuple<itype_id, int, int>> components;
Expand Down Expand Up @@ -284,6 +289,8 @@ struct trap {
void trigger( const tripoint &pos, item &item ) const;
/*@}*/

void trigger( const tripoint &pos ) const;

/**
* If the given item is throw onto the trap, does it trigger the trap?
*/
Expand Down Expand Up @@ -331,6 +338,13 @@ struct trap {
static const std::vector<const trap *> &get_funnels();
/*@}*/

/*
* Can the trap be triggered by sounds?
*/
bool has_sound_trigger() const;
static const std::vector<const trap *> &get_sound_triggered_traps();
bool triggered_by_sound( int vol, int dist ) const;

/*@{*/
/**
* @name Initialization
Expand Down
13 changes: 12 additions & 1 deletion src/trapfunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,16 @@ bool trapfunc::snake( const tripoint &p, Creature *, item * )
return true;
}

/**
* Made to test sound-triggered traps.
* Warning: generating a sound can trigger sound-triggered traps.
*/
bool trapfunc::sound_detect( const tripoint &p, Creature *, item * )
{
sounds::sound( p, 10, sounds::sound_t::alert, _( "Sound Detected!" ), false, "misc" );
return true;
}

/**
* Takes the name of a trap function and returns a function pointer to it.
* @param function_name The name of the trapfunc function to find.
Expand Down Expand Up @@ -1618,7 +1628,8 @@ const trap_function &trap_function_from_string( const std::string &function_name
{ "map_regen", trapfunc::map_regen },
{ "drain", trapfunc::drain },
{ "spell", trapfunc::cast_spell },
{ "snake", trapfunc::snake }
{ "snake", trapfunc::snake },
{ "sound_detect", trapfunc::sound_detect }
}
};

Expand Down

0 comments on commit a1c4973

Please sign in to comment.