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

feat: JSONize some trap features #3941

Merged
merged 6 commits into from
Dec 24, 2023
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
24 changes: 20 additions & 4 deletions data/json/items/tool/traps.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@
"id": "shotgun_trap",
"type": "GENERIC",
"category": "tools",
"name": { "str": "shotgun trap" },
"description": "This is a simple tripwire is attached to the trigger of a loaded double-barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; the first time the trigger is pulled, one or both shells may be discharged.",
"weight": "2922 g",
"volume": "1750 ml",
"name": { "str": "double-barreled shotgun trap" },
"description": "This is a simple tripwire is attached to the trigger of a loaded double-barreled shotgun. When pulled, the shotgun fires, discharging both barrels into the target.",
"weight": "3500 g",
"volume": "3 L",
"price": "250 USD",
"price_postapoc": "10 USD",
"to_hit": -2,
Expand All @@ -238,6 +238,22 @@
"done_message": "You set the shotgun trap."
}
},
{
"id": "shotgun_trap_single",
"copy-from": "shotgun_trap",
"type": "GENERIC",
"name": { "str": "shotgun trap" },
"description": "This is a simple tripwire is attached to the trigger of a loaded single-barreled shotgun. When pulled, the shotgun fires.",
"weight": "2600 g",
"volume": "2500 ml",
"use_action": {
"type": "place_trap",
"trap": "tr_shotgun_1",
"moves": 225,
"practice": 5,
"done_message": "You set the shotgun trap."
}
},
{
"id": "tripwire",
"type": "GENERIC",
Expand Down
25 changes: 25 additions & 0 deletions data/json/obsoletion/uncategorized.json
Original file line number Diff line number Diff line change
Expand Up @@ -437,5 +437,30 @@
]
},
"examine_action": "clean_water_source"
},
{
"type": "trap",
"id": "tr_shotgun_2_1",
"trigger_weight": "200 g",
"name": "half-empty shotgun trap",
"color": "red",
"symbol": "^",
"visibility": 4,
"avoidance": 5,
"difficulty": 6,
"action": "shotgun",
"remove_on_trigger": true,
"trigger_items": [ "tripwire", "shotgun_d", { "item": "shot_hull", "quantity": 2, "charges": 1 } ],
"drops": [ "tripwire", "shotgun_d", { "item": "shot_00", "quantity": 1, "charges": 1 } ],
"vehicle_data": {
"chance": 70,
"damage": 300,
scarf005 marked this conversation as resolved.
Show resolved Hide resolved
"sound_volume": 60,
"sound": "Bang!",
"sound_type": "fire_gun",
"sound_variant": "shotgun_d",
"remove_trap": true,
"spawn_items": [ "shotgun_d", "string_6" ]
}
}
]
18 changes: 16 additions & 2 deletions data/json/recipes/other/traps.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@
"reversible": true,
"decomp_learn": 2,
"autolearn": true,
"components": [ [ [ "tripwire", 1 ] ], [ [ "crossbow", 1 ] ], [ [ "bolt_steel", 1 ], [ "bolt_wood", 4 ] ] ]
"components": [ [ [ "tripwire", 1 ] ], [ [ "crossbow", 1 ] ], [ [ "bolt_steel", 1 ], [ "bolt_wood", 1 ] ] ]
},
{
"type": "recipe",
"result": "shotgun_trap",
"result": "shotgun_trap_single",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_TRAPS",
"skill_used": "traps",
Expand All @@ -151,6 +151,20 @@
"reversible": true,
"decomp_learn": 2,
"autolearn": true,
"components": [ [ [ "tripwire", 1 ] ], [ [ "shotgun_s", 1 ] ], [ [ "shot_00", 1 ], [ "shot_slug", 1 ], [ "shot_flechette", 1 ] ] ]
},
{
"type": "recipe",
"result": "shotgun_trap",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_TRAPS",
"skill_used": "traps",
"skills_required": [ "mechanics", 1 ],
"difficulty": 4,
"time": "5 m",
"reversible": true,
"decomp_learn": 3,
"autolearn": true,
"components": [ [ [ "tripwire", 1 ] ], [ [ "shotgun_d", 1 ] ], [ [ "shot_00", 2 ], [ "shot_slug", 2 ], [ "shot_flechette", 2 ] ] ]
},
{
Expand Down
51 changes: 26 additions & 25 deletions data/json/traps.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"avoidance": 8,
"difficulty": 0,
"action": "bubble",
"remove_on_trigger": true,
"drops": [ "bubblewrap" ],
"vehicle_data": { "sound_volume": 18, "sound": "Pop!" }
},
Expand All @@ -34,6 +35,7 @@
"avoidance": 8,
"difficulty": 0,
"action": "glass",
"remove_on_trigger": true,
"drops": [ "glass_shard" ],
"vehicle_data": { "sound_volume": 10, "sound": "Crunch!" }
},
Expand Down Expand Up @@ -147,6 +149,8 @@
"avoidance": 7,
"difficulty": 3,
"action": "beartrap",
"//": "trigger_items isn't needed for this action, since trap behavior is tied to the target freeing themselves.",
"remove_on_trigger": true,
"drops": [ "beartrap" ],
"vehicle_data": {
"damage": 300,
Expand All @@ -169,6 +173,8 @@
"avoidance": 8,
"difficulty": 4,
"action": "beartrap",
"//": "trigger_items isn't needed for this action, since trap behavior is tied to the target freeing themselves.",
"remove_on_trigger": true,
"drops": [ "beartrap" ],
"vehicle_data": {
"damage": 300,
Expand Down Expand Up @@ -216,6 +222,8 @@
"avoidance": 6,
"difficulty": 0,
"action": "caltrops_glass",
"remove_on_trigger": true,
"trigger_items": [ { "item": "glass_shard", "quantity": 3 } ],
"drops": [ "caltrops_glass" ],
"vehicle_data": { "damage": 300 }
},
Expand Down Expand Up @@ -244,6 +252,8 @@
"difficulty": 5,
"action": "spell",
"spell_data": { "id": "spell_trap_can_alarm_trigger" },
"remove_on_trigger": true,
"trigger_items": [ "can_alarm_trap" ],
"drops": [ "can_alarm_trap" ],
"vehicle_data": { "sound_volume": 25, "sound": "empty cans clattering!" }
},
Expand All @@ -258,6 +268,9 @@
"avoidance": 4,
"difficulty": 5,
"action": "crossbow",
"remove_on_trigger": true,
"//": "Ammo spawn on activation is still hardcoded, as it has a randomized chance to drop intact.",
"trigger_items": [ "tripwire", "crossbow" ],
"drops": [ "tripwire", "crossbow", "bolt_steel" ],
"vehicle_data": {
"chance": 30,
Expand All @@ -274,13 +287,15 @@
"type": "trap",
"id": "tr_shotgun_2",
"trigger_weight": "200 g",
"name": "shotgun trap",
"name": "double-barrel shotgun trap",
"color": "red",
"symbol": "^",
"visibility": 4,
"avoidance": 5,
"difficulty": 6,
"action": "shotgun",
"remove_on_trigger": true,
"trigger_items": [ "tripwire", "shotgun_d", { "item": "shot_hull", "quantity": 2, "charges": 1 } ],
"drops": [ "tripwire", "shotgun_d", { "item": "shot_00", "quantity": 2, "charges": 1 } ],
"vehicle_data": {
"chance": 70,
Expand All @@ -292,29 +307,6 @@
"set_trap": "tr_shotgun_2_1"
}
},
{
"type": "trap",
"id": "tr_shotgun_2_1",
"trigger_weight": "200 g",
"name": "shotgun trap",
"color": "red",
"symbol": "^",
"visibility": 4,
"avoidance": 5,
"difficulty": 6,
"action": "shotgun",
"drops": [ "tripwire", "shotgun_d", { "item": "shot_00", "quantity": 1, "charges": 1 } ],
"vehicle_data": {
"chance": 70,
"damage": 300,
"sound_volume": 60,
"sound": "Bang!",
"sound_type": "fire_gun",
"sound_variant": "shotgun_d",
"remove_trap": true,
"spawn_items": [ "shotgun_d", "string_6" ]
}
},
{
"type": "trap",
"id": "tr_shotgun_1",
Expand All @@ -326,6 +318,8 @@
"avoidance": 5,
"difficulty": 6,
"action": "shotgun",
"remove_on_trigger": true,
"trigger_items": [ "tripwire", "shotgun_s", { "item": "shot_hull", "quantity": 1, "charges": 1 } ],
"drops": [ "tripwire", "shotgun_s", { "item": "shot_00", "quantity": 1, "charges": 1 } ],
"vehicle_data": {
"chance": 70,
Expand Down Expand Up @@ -375,6 +369,7 @@
"avoidance": 14,
"difficulty": 10,
"action": "landmine",
"remove_on_trigger": true,
"drops": [ "landmine" ],
"vehicle_data": {
"do_explosion": true,
Expand All @@ -397,6 +392,7 @@
"avoidance": 14,
"difficulty": 10,
"action": "landmine",
"remove_on_trigger": true,
"drops": [ "landmine" ],
"vehicle_data": {
"do_explosion": true,
Expand Down Expand Up @@ -430,7 +426,8 @@
"visibility": 0,
"avoidance": 15,
"difficulty": 15,
"action": "goo"
"action": "goo",
"remove_on_trigger": true
},
{
"type": "trap",
Expand All @@ -454,6 +451,7 @@
"avoidance": 14,
"difficulty": 99,
"action": "sinkhole",
"remove_on_trigger": true,
"vehicle_data": { "damage": 500 }
},
{
Expand All @@ -477,6 +475,7 @@
"visibility": 0,
"avoidance": 8,
"difficulty": 99,
"//": "trigger_items isn't used here since the spikes breaking occurs at random, and comes with converting the terrain type when triggered.",
"action": "pit_spikes",
"vehicle_data": { "damage": 500 }
},
Expand Down Expand Up @@ -527,6 +526,7 @@
"avoidance": 4,
"difficulty": 7,
"action": "boobytrap",
"remove_on_trigger": true,
"drops": [ "boobytrap" ],
"vehicle_data": {
"do_explosion": true,
Expand Down Expand Up @@ -630,6 +630,7 @@
"visibility": 0,
"avoidance": 8,
"difficulty": 99,
"//": "trigger_items isn't used here since the spikes breaking occurs at random, and comes with converting the terrain type when triggered.",
"action": "pit_glass",
"vehicle_data": { "damage": 500 }
},
Expand Down
33 changes: 33 additions & 0 deletions src/trap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ void trap::load( const JsonObject &jo, const std::string & )

optional( jo, was_loaded, "map_regen", map_regen, "none" );
optional( jo, was_loaded, "benign", benign, false );
optional( jo, was_loaded, "remove_on_trigger", remove_on_trigger, false );
optional( jo, was_loaded, "always_invisible", always_invisible, false );
optional( jo, was_loaded, "funnel_radius", funnel_radius_mm, 0 );
optional( jo, was_loaded, "comfort", comfort, 0 );
Expand All @@ -129,6 +130,24 @@ void trap::load( const JsonObject &jo, const std::string & )
looks_like = jo.get_string( "copy-from" );
}
jo.read( "looks_like", looks_like );
for( const JsonValue entry : jo.get_array( "trigger_items" ) ) {
itype_id item_type;
int quantity = 0;
int charges = 0;
if( entry.test_object() ) {
JsonObject jc = entry.get_object();
jc.read( "item", item_type, true );
quantity = jc.get_int( "quantity", 1 );
charges = jc.get_int( "charges", 1 );
} else {
entry.read( item_type, true );
quantity = 1;
charges = 1;
}
if( !item_type.is_empty() && quantity > 0 && charges > 0 ) {
trigger_components.emplace_back( item_type, quantity, charges );
}
}
for( const JsonValue entry : jo.get_array( "drops" ) ) {
itype_id item_type;
int quantity = 0;
Expand Down Expand Up @@ -261,6 +280,20 @@ bool trap::is_funnel() const
return !is_null() && funnel_radius_mm > 0;
}


void trap::trigger_aftermath( map &m, const tripoint &p ) const
{
for( auto &i : m.tr_at( p ).trigger_components ) {
const itype_id &item_type = std::get<0>( i );
const int quantity = std::get<1>( i );
const int charges = std::get<2>( i );
m.spawn_item( p.xy(), item_type, quantity, charges );
}
if( m.tr_at( p ).remove_trap_when_triggered() ) {
m.remove_trap( p );
}
}

void trap::on_disarmed( map &m, const tripoint &p ) const
{
for( auto &i : components ) {
Expand Down
18 changes: 17 additions & 1 deletion src/trap.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct trap {
// 0 to ??, trap radius
int trap_radius = 0;
bool benign = false;
bool remove_on_trigger = false;
bool always_invisible = false;
// a valid overmap id, for map_regen action traps
std::string map_regen;
Expand All @@ -111,7 +112,9 @@ struct trap {
*/
units::mass trigger_weight = units::mass( -1, units::mass::unit_type{} );
int funnel_radius_mm = 0;
// For disassembly?
// Items optionally yielded after the trap goes off
std::vector<std::tuple<itype_id, int, int>> trigger_components;
// Items optionally yielded after the trap is disarmed
std::vector<std::tuple<itype_id, int, int>> components;
public:
// data required for trapfunc::spell()
Expand Down Expand Up @@ -160,6 +163,13 @@ struct trap {
bool is_benign() const {
return benign;
}
/**
* If true, remove this trap during trap::trigger_aftermath when the trap is set off.
* Warning: won't affect underlying terrain, so not worth using for things like t_pit.
*/
bool remove_trap_when_triggered() const {
return remove_on_trigger;
}
/** Player has not yet seen the trap and returns the variable chance, at this moment,
of whether the trap is seen or not. */
bool detect_trap( const tripoint &pos, const Character &p ) const;
Expand All @@ -182,6 +192,12 @@ struct trap {
* If the given item is throw onto the trap, does it trigger the trap?
*/
bool triggered_by_item( const item &itm ) const;
/**
* Cleanup after a trap has been triggered, spawns items (if any) and.
* if remove_on_trigger is set to true removes the trap via
* @ref map::remove_trap.
*/
void trigger_aftermath( map &m, const tripoint &p ) const;
/**
* Called when a trap at the given point in the map has been disarmed.
* It should spawn trap items (if any) and remove the trap from the map via
Expand Down
Loading
Loading