From d000196f151985d5b2f38a48d16159dcd0973d9a Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Tue, 10 Mar 2020 21:59:22 +0100 Subject: [PATCH] Add map_bash_info to fields (#37865) --- data/json/field_type.json | 8 ++++++ .../My_Sweet_Cataclysm/sweet_field_type.json | 9 ++++++ doc/JSON_INFO.md | 17 +++++++++++ src/field_type.cpp | 1 + src/field_type.h | 2 ++ src/handle_action.cpp | 28 +++++++++++++++---- src/mapdata.cpp | 27 +++++++++++------- src/mapdata.h | 9 +++++- 8 files changed, 84 insertions(+), 17 deletions(-) diff --git a/data/json/field_type.json b/data/json/field_type.json index 62edc326ade03..a9c4e1daf7618 100644 --- a/data/json/field_type.json +++ b/data/json/field_type.json @@ -82,6 +82,14 @@ "priority": 2, "phase": "solid", "display_items": false, + "bash": { + "str_min": 1, + "str_max": 3, + "sound_vol": 2, + "sound_fail_vol": 2, + "sound": "hsh!", + "msg_success": "You brush aside some webs." + }, "display_field": true }, { diff --git a/data/mods/My_Sweet_Cataclysm/sweet_field_type.json b/data/mods/My_Sweet_Cataclysm/sweet_field_type.json index 6c3cd61622f07..77c43ffcd5850 100644 --- a/data/mods/My_Sweet_Cataclysm/sweet_field_type.json +++ b/data/mods/My_Sweet_Cataclysm/sweet_field_type.json @@ -58,6 +58,15 @@ "priority": 2, "phase": "solid", "half_life": "2 h", + "bash": { + "str_min": 1, + "str_max": 3, + "sound_vol": 2, + "sound_fail_vol": 2, + "sound": "shwip", + "sound_fail": "shwomp", + "msg_success": "You brush the gum web aside." + }, "display_items": false, "display_field": true }, diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index ec3a135c20cbe..3b19c0dc23de5 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3019,4 +3019,21 @@ Setting of sprite sheets. Same as `tiles-new` field in `tile_config`. Sprite fil "type": "field_type", // this is a field type "id": "fd_gum_web", // id of the field "immune_mtypes": [ "mon_spider_gum" ], // list of monster immune to this field + "bash": { + "str_min": 1, // lower bracket of bashing damage required to bash + "str_max": 3, // higher bracket + "sound_vol": 2, // noise made when succesfully bashing the field + "sound_fail_vol": 2, // noise made when failing to bash the field + "sound": "shwip", // sound on success + "sound_fail": "shwomp", // sound on failure + "msg_success": "You brush the gum web aside.", // message on success + "move_cost": 120, // how many moves it costs to succesfully bash that field (default: 100) + "items": [ // item dropped upon succesful bashing + { "item": "2x4", "count": [ 5, 8 ] }, + { "item": "nail", "charges": [ 6, 8 ] }, + { "item": "splinter", "count": [ 3, 6 ] }, + { "item": "rag", "count": [ 40, 55 ] }, + { "item": "scrap", "count": [ 10, 20 ] } + ] + } } diff --git a/src/field_type.cpp b/src/field_type.cpp index f35fdc83a6512..891f435c113c0 100644 --- a/src/field_type.cpp +++ b/src/field_type.cpp @@ -244,6 +244,7 @@ void field_type::load( const JsonObject &jo, const std::string & ) optional( jo, was_loaded, "display_field", display_field, false ); optional( jo, was_loaded, "wandering_field", wandering_field_id, "fd_null" ); + bash_info.load( jo, "bash", map_bash_info::field ); if( was_loaded && jo.has_member( "copy-from" ) && looks_like.empty() ) { looks_like = jo.get_string( "copy-from" ); } diff --git a/src/field_type.h b/src/field_type.h index 7302b51f09b8b..d2af7b846ea48 100644 --- a/src/field_type.h +++ b/src/field_type.h @@ -15,6 +15,7 @@ #include "color.h" #include "effect.h" #include "enums.h" +#include "mapdata.h" #include "type_id.h" #include "string_id.h" #include "translations.h" @@ -143,6 +144,7 @@ struct field_type { bool has_elec = false; bool has_fume = false; description_affix desc_affix = description_affix::DESCRIPTION_AFFIX_NUM; + map_bash_info bash_info; // chance, issue, duration, speech std::tuple npc_complain_data; diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 71eb8af87dc6a..88b018705571b 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -674,12 +674,28 @@ static void smash() crit->use_mech_power( -3 ); } } - if( m.get_field( smashp, fd_web ) != nullptr ) { - m.remove_field( smashp, fd_web ); - sounds::sound( smashp, 2, sounds::sound_t::combat, _( "hsh!" ), true, "smash", "web" ); - add_msg( m_info, _( "You brush aside some webs." ) ); - u.moves -= 100; - return; + for( std::pair &fd_to_smsh : m.field_at( smashp ) ) { + const map_bash_info &bash_info = fd_to_smsh.first->bash_info; + if( bash_info.str_min == -1 ) { + continue; + } + if( smashskill < bash_info.str_min && one_in( 10 ) ) { + add_msg( m_neutral, _( "You don't seem to be damaging the %s." ), fd_to_smsh.first->get_name() ); + return; + } else if( smashskill >= rng( bash_info.str_min, bash_info.str_max ) ) { + sounds::sound( smashp, bash_info.sound_vol, sounds::sound_t::combat, bash_info.sound, true, "smash", + "field" ); + m.remove_field( smashp, fd_to_smsh.first ); + m.spawn_items( smashp, item_group::items_from( bash_info.drop_group, calendar::turn ) ); + u.mod_moves( - bash_info.fd_bash_move_cost ); + add_msg( m_info, bash_info.field_bash_msg_success.translated() ); + return; + } else { + sounds::sound( smashp, bash_info.sound_fail_vol, sounds::sound_t::combat, bash_info.sound_fail, + true, "smash", + "field" ); + return; + } } for( const auto &maybe_corpse : m.i_at( smashp ) ) { diff --git a/src/mapdata.cpp b/src/mapdata.cpp index f0f0101330290..aa3c1c94eda28 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -198,7 +198,8 @@ map_bash_info::map_bash_info() : str_min( -1 ), str_max( -1 ), drop_group( "EMPTY_GROUP" ), ter_set( ter_str_id::NULL_ID() ), furn_set( furn_str_id::NULL_ID() ) {} -bool map_bash_info::load( const JsonObject &jsobj, const std::string &member, bool is_furniture ) +bool map_bash_info::load( const JsonObject &jsobj, const std::string &member, + map_object_type obj_type ) { if( !jsobj.has_object( member ) ) { return false; @@ -230,13 +231,19 @@ bool map_bash_info::load( const JsonObject &jsobj, const std::string &member, bo j.read( "sound", sound ); j.read( "sound_fail", sound_fail ); - if( is_furniture ) { - furn_set = furn_str_id( j.get_string( "furn_set", "f_null" ) ); - } else { - const std::string ter_set_string = j.get_string( "ter_set" ); - ter_set = ter_str_id( ter_set_string ); - ter_set_bashed_from_above = ter_str_id( j.get_string( "ter_set_bashed_from_above", - ter_set_string ) ); + switch( obj_type ) { + case map_bash_info::furniture: + furn_set = furn_str_id( j.get_string( "furn_set", "f_null" ) ); + break; + case map_bash_info::terrain: + ter_set = ter_str_id( j.get_string( "ter_set" ) ); + ter_set_bashed_from_above = ter_str_id( j.get_string( "ter_set_bashed_from_above", + ter_set.c_str() ) ); + break; + case map_bash_info::field: + assign( j, "move_cost", fd_bash_move_cost, 100 ); + j.read( "msg_success", field_bash_msg_success ); + break; } if( j.has_member( "items" ) ) { @@ -1166,7 +1173,7 @@ void ter_t::load( const JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "transforms_into", transforms_into, ter_str_id::NULL_ID() ); optional( jo, was_loaded, "roof", roof, ter_str_id::NULL_ID() ); - bash.load( jo, "bash", false ); + bash.load( jo, "bash", map_bash_info::terrain ); deconstruct.load( jo, "deconstruct", false ); } @@ -1269,7 +1276,7 @@ void furn_t::load( const JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "open", open, string_id_reader {}, furn_str_id::NULL_ID() ); optional( jo, was_loaded, "close", close, string_id_reader {}, furn_str_id::NULL_ID() ); - bash.load( jo, "bash", true ); + bash.load( jo, "bash", map_bash_info::furniture ); deconstruct.load( jo, "deconstruct", true ); if( jo.has_object( "workbench" ) ) { diff --git a/src/mapdata.h b/src/mapdata.h index 184d8abc270bf..b709dbe7bac64 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -39,18 +39,25 @@ struct map_bash_info { int sound_vol; // sound volume of breaking terrain/furniture int sound_fail_vol; // sound volume on fail int collapse_radius; // Radius of the tent supported by this tile + int fd_bash_move_cost = 100; // cost to bash a field bool destroy_only; // Only used for destroying, not normally bashable bool bash_below; // This terrain is the roof of the tile below it, try to destroy that too std::string drop_group; // item group of items that are dropped when the object is bashed translation sound; // sound made on success ('You hear a "smash!"') translation sound_fail; // sound made on fail + translation field_bash_msg_success; // message upon successfully bashing a field ter_str_id ter_set; // terrain to set (REQUIRED for terrain)) ter_str_id ter_set_bashed_from_above; // terrain to set if bashed from above (defaults to ter_set) furn_str_id furn_set; // furniture to set (only used by furniture, not terrain) // ids used for the special handling of tents std::vector tent_centers; map_bash_info(); - bool load( const JsonObject &jsobj, const std::string &member, bool is_furniture ); + enum map_object_type { + furniture = 0, + terrain, + field + }; + bool load( const JsonObject &jsobj, const std::string &member, map_object_type obj_type ); }; struct map_deconstruct_info { // Only if true, the terrain/furniture can be deconstructed